php單元測試進階(2)-入門
本系列文章主要代碼與文字來源于《單元測試的藝術》,原作者:Roy Osherove。譯者:金迎。
本系列文章根據php的語法與使用習慣做了改編。所有代碼在本機測試通過。如轉載請注明出處。
首先清空tests目錄下所有文件,其實就2個。
假設有一個項目,用于分析日志文件,在其中搜索特定的情況和事件,找到后,自動通知相關的人員。
先做一個最簡單的類和方法,測試方法名是否有效。如下。
在t2\application\index\controller下建文件LogAnalyzer.php
<?php
namespace app\index\controller;
/**
* 日志分析器類,也是被測類
*
*/
class LogAnalyzer
{
/**
* 判斷文件名是否有效,.slf結尾的文件名就是有效的,返回真
* @param string $filename
*/
public function isValidLogFileName($filename)
{
if (preg_match('/\.SLF$/', $filename)){
return false;
}
return true;
}
}
請注意上面的代碼,故意寫錯了,在if后面漏了一個!運算符。
現在我們來做單元測試。
在t2\tests\index\controller\下建立LogAnalyzerTest.php,內容如下
<?php
namespace tests\index\controller;
class LogAnalyzerTest extends \think\testing\TestCase
{
/**
* @test
* 注意,盡量使得測試的方法名稱有意義,這非常重要,便于維護測試代碼。有規律
*/
public function isValidFileName_BadExtension_RetrunFalse()
{
$analyzer = new \app\index\controller\LogAnalyzer();
$result = $analyzer->isValidLogFileName("file_with_bad_extension.foo");
$this->assertFalse($result);
}
}
建議的測試方法名稱規范:
[UnitOfWorkName]_[ScenarioUnderTest]_[ExpectedBehavior]
UnitOfWorkName:工作單元名,既可以對應于被測類的一個方法,也可能對應于被測項目的多個類或方法。前者可以直接引用原方法名,后者可以象UserLogin,RemoveUser或Startup等。一個工作單元,至少應該有一個測試方法。
ScenarioUnderTest:發生什么狀況,當事情怎樣的時候,指定什么條件,例如“登入失敗”,“無效用戶”,“密碼正確”等
ExpectedBehavior:在測試場景指定條件下,你對被測方法行為的預期。
對于上面的被測類的測試文件名是否正確的那個方法,我們的測試方法可以命名為 isValidFileName_BadExtension_RetrunFalse。
一個單元測試通常包含3個步驟
(1)準備對象,創建對象,進行必要的設置,也包括建立初始數據。
(2)操作對象
(3)斷言某件事情符合預期
cmd窗口下,在t2目錄下,執行php think unit
看到測試未通過,因為我們的源代碼錯了,
修改后的代碼應該如下所示
if (!preg_match('/\.SLF$/', $filename)){
return false;
}
現在測試通過了,在我的電腦,顯示如下
D:\workspace\t2>php think unit
PHPUnit 4.8.35 by Sebastian Bergmann and contributors.
.
Time: 398 ms, Memory: 4.00MB
OK (1 test, 1 assertion)
D:\workspace\t2>