本筆記會以簡單的例子說明,如何在Laravel中進行unit test 與 feature test。
Laravel 內建tests資料夾下有分成Feature與Unit兩個目錄,Feature是用來做功能測試的,可能是幾個unit組成的一個完整功能,Unit是用來做單元測試的,比如說測試一個method執行結果是否正確。
phpunit.xml則是設定檔,可以設定哪些檔案要做測試,哪些要排除在外等等。
使用命令建立新的test case:
$ php artisan make:test UserTest
$ php artisan make:test UserTest --unit
接著就會看到目錄中新增了UserTest.php檔案
$ php artisan test
以下用簡單的例子來說明,假設有個可以by user id取得user name的API,想要進行單元測試與功能測試。
程式碼如下:
user table資料如下:
Unit Test
接著如上所述,想測試UserRepository這個getName method,建立一個unit test case:
<?php
namespace Tests\Unit;
use Tests\TestCase;
use App\Repositories\UserRepository;
class UserTest extends TestCase
{
/**
* @dataProvider getNameProvider
*/
public function testGetName($id, $name)
{
$userRepo = new UserRepository();
$this->assertEquals($name, $userRepo->getName($id));
}
public function getNameProvider() {
return [
[1, 'Vic'],
[2, 'Allen'],
];
}
}
- 執行$php artisan test後,會將所有test開頭的method都當作進入點做測試,也就是說method命名可以用testXXX 或 test_xxx等等。
- @dataProvider是用來定義method輸入參數用的。
意思其實等同於:
testGetName(1, 'Vic')
testGetName(2, 'Allen')
Feature Test
接著看看feature test case的部分,如同上述,功能測試是用來測試完整功能是否正常的,也就是可以測試某個api功能是否正常。
這邊以測試取得使用者名稱的api是否正常為例,由於route中定義的api/user/name的http method是get,所以這邊是用
$this->get(),等同於要測試這個get api response status code是否為200。
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class UserTest extends TestCase
{
public function testGetName()
{
$response = $this->get('api/user/name?id=1');
$response->assertStatus(200);
}
}
最後看看執行unit test的結果:
Note:
若執行測試發現這個error:
Call to a member function connection() on null
解決方法: 將 use PHPUnit\Framework\TestCase; 改成use Tests\TestCase;