2013-12-10 36 views
2

在編寫PHPUnit測試一段時間後,我遇到了一個我希望找到一個優雅解決方案的模式。我的項目的單元測試使用了很多臨時文件。我將有一個輸出文件的函數,並且我需要在輸出(temp)文件上做出幾個斷言。之後,我想確保臨時文件得到清理,即使某些斷言失敗。PHPUnit臨時文件助手

下面是一些使用克魯夫特來處理臨時文件的示例測試文件:

class FooTest extends AhshayTestUnit 
{ 
    function setUp() 
    { 
     $this->tmps[] = array(); 
    } 

    function tearDown() 
    { 
     foreach ($this->tmps as $tmp) 
     { 
      @unlink($tmp); 
     } 
    } 

    function tmp() 
    { 
     $this->tmps[] = $tmp = tempnam('/tmp', 'test_foo'); 
     unlink($tmp); 
     return $tmp; 
    } 

    function testFoo() 
    { 
     $in = 'html2pdf.html'; 
     $out = $this->tmp(); 

     $success = html2Pdf($in, $out); 

     $this->assertFileExists($out, "should create PDF file"); 
     $this->assertGreaterThan(1024, filesize($out), "output file should be atleast 1k"); 

     # and so on 
    } 
} 

這樣,每個測試功能並不需要擔心刪除$out,即使第一個斷言失敗。

現在我已經說了所有這些,我想將這些幫助函數烘焙到我擁有的每個測試對象中。我已經有了自己的課程,可以延伸到PHPUnit_Framework_TestCase。我可以將我的自定義setUp()tearDown()放在我的子類中,但要求我所有的測試都有自己的設置/拆卸記住要撥打parent::__construct()似乎有點蹩腳。有沒有更優雅的方式來做到這一點?有沒有內置到PHPUnit中來處理這個問題?看起來最好的辦法是有一些方法讓PHPUnit鏈接setup/teardown回調。

回答

1

您可以使用vfsstream來模擬文件系統。這是一個很好的解決方案,可以避免任何設計垃圾。

定製的解決方案可能是寄存器被刪除臨時文件(多個)關閉功能,即使發生了致命錯誤,例如在該(簡單)例如:

class MyTest extends PHPUnit_Framework_TestCase 
{ 

    public function setUp() { 
     register_shutdown_function(function() { 
      if(file_exists('temp.file')) { 
       unlink('temp.file'); 
      } 
     }); 
    } 

    ... the tests 

} 
0

註冊爲關閉功能當你的測試不能自行清理時(因爲它們在集成測試期間可能不會),清理非常有用。如上所述,如果您確實發現多次重複相同的邏輯,則可以使用PHP traits來創建類似於TempTrait的東西,它們只需要在測試期間或每次測試期間運行所需的功能tearDown功能。