什麼?這不是只是使用 Laravel 的教學嗎?為什麼突然就講起了自動測試?
沒有問題,讓自動測試變得簡單也是 Laravel 這個框架的一個重要特性。
實際上,Laravel 在這件事情上,也確實做得很不錯。撰寫自動測試在 Laravel 的支援下非常直觀而且簡單。
所以,就趁機一起把自動測試學好吧!
一般來說,我們常見的測試,就是像之前我們寫完功能後所做的這樣,實際點開寫好的網頁,看看我們撰寫的功能,有沒有照我們的預期運作。
這在網站還小,功能還不多時,是沒有問題的。每次新功能上線之後,我們只需要找一批人進到網站實際點看看各個功能,確定沒有問題就好。
但是!
當你的網站功能越來越多,每個功能又可能互相關聯時,每次增加一個功能都得點開所有網頁,甚至要開啟不同身份的帳號,來檢查所有功能的話,實際上是不可能的。
幸好,我們可以用程式來協助這件事情!
如果我們每次為每個功能撰寫程式時,都寫另一段小程式來測試這個功能。隨著時間過去,需求的改變,雖然功能越來越多,但是相對應的,測試這些功能的程式也會越來越多,並且不管這個功能是多久之前開發的,每個功能都有相對應的測試。
這樣,當我們想知道新加入的功能正不正確時,不就只要將所有的測試程式碼跑過一遍,確認所有的自動測試都正常,就可以知道了新加入的功能有沒有影響到舊功能了嗎?
這就是自動測試的威力!
我們只寫了一個 Hello World 而已,要測試些什麼呢?
稍微思考一下,我們可以預期這個程式,應該要有以下行為:
hello-world/
,HTTP Status 應該要顯示 200(成功連線)即便是這麼簡單的功能,我們仍舊整理出了兩項可供測試的需求。
再來,我們來看看 PHP 裡面怎麼執行自動測試。
在 PHP 的世界裡面,自動測試通常使用 PHPUnit 這個工具。
很幸運的是,Laravel 在安裝的同時,就自動也幫我們安裝了這個工具!所以不需要講安裝的流程了!
安裝的位置在 vendor/
裡面,我們立刻來試用看看
vendor/phpunit/phpunit/phpunit
PHPUnit 7.5.15 by Sebastian Bergmann and contributors.
.. 2 / 2 (100%)
Time: 351 ms, Memory: 18.00 MB
OK (2 tests, 2 assertions)
(p.s. 較新的 Laravel 支援 php artisan test
這個指令,各位可以嘗試看看自己的專案內是否有此指令,會以比較易讀的格式顯示測試結果)
咦?我們什麼都還沒做,為什麼已經有兩個測試案例通過了呢?
這是因為 Laravel 有事先提供兩個測試的案例,來看看這些案例長什麼樣子。
這兩個案例,分別位在下面兩個位置:
tests/Feature/ExampleTest.php
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
這個測試相當容易理解,我們可以看到,這測試應該是:
/
並取得回傳沒錯!這個測試就是檢查網頁的首頁是否存在!
另一個測試是單元測試的範例,位在tests/Unit/ExampleTest.php
:
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
}
這個呢⋯⋯測試了 true
是不是等於 true
(廢話
再次確認一下,我們的需求是
hello-world/
,HTTP Status 應該要顯示 200(成功連線)我們輸入指令
$ php artisan make:test HelloWorldTest
Test created successfully.
什麼?這樣就建立好了嗎?
我們打開測試資料夾,可以看到現在多了一個新的測試 tests/Feature/HelloWorldTest.php
內容為:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class HelloWorldTest extends TestCase
{
/**
* A basic feature test example.
*
* @return void
*/
public function testExample()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
範例已經做好了!而且 Laravel 還很貼心的幫我們寫了範例程式碼!
我們依照前面所說的需求,改寫這段範例:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class HelloWorldTest extends TestCase
{
/**
* A basic feature test example.
*
* @return void
*/
public function testExample()
{
$response = $this->get('/hello-world');
// 如果連線 `hello-world/`,HTTP Status 應該要顯示 200(成功連線)
$response->assertStatus(200);
//連線到網頁內,應該要可以看到「Hello world!」這些字
$response->assertSee('Hello World!');
}
}
然後,運作一下我們的測試:
$ vendor/phpunit/phpunit/phpunit
PHPUnit 7.5.15 by Sebastian Bergmann and contributors.
... 3 / 3 (100%)
Time: 399 ms, Memory: 18.00 MB
OK (3 tests, 4 assertions)
測試成功了!
今天,我們學到了 PHPUnit 這個工具,知道怎麼運作測試,還完成了幾個測試案例!
相信大家收穫都不少吧,明天見!
新版的已經預設是 PHPUnit 8了,指令的路徑改成在
vendor/bin/phpunit
https://phpunit.de/getting-started/phpunit-8.html
不好意思 vendor/phpunit/phpunit/phpunit 也可以 留完言才發現
我是運用laragon來裝laravel的
原本內建的laravel資料夾中就會產生vendor 裡面也會有PHPUnit
可是為何我每次下PHPUnit的指令
他都是引用
C:\Users\User\AppData\Roaming\Composer\vendor\bin 中的PHPUnit(5.4.x版)
因為他跟我laragon裝的版本不相符(8.2.x版)
由於我PHP用7.2.9所以這樣抓到的PHPUnit 並不能使用
請問有什麼方法可以改變cmd的指令去抓我laragon裡面的PHPUnit嗎
(我都已經修改過環境變數了QQ)
改用 vendor/phpunit/phpunit/phpunit
呢?
可以用 artisan 提供的方法來啟動測試,省去找路徑的問題
php artisan test
排版也更清楚哦,比較兩者差異
查看所有的 artisan 指令
php artisan list
感謝您的回應
用 php artisan test
確實是比較好的顯示方式
不過這個方式在 6 上面還不支援,我自己查看的結果應該是在 Laravel 7 上面才支援
我會將這段資訊補充在文章內,再次謝謝您!
WINDOWS這樣下達,會出錯
vendor/phpunit/phpunit/phpunit
指令找不到
laragon套件的環境,所以WINDOWS環境要這樣下達
要包含 路徑
D:\laragon\www\demo\vendor\bin\phpunit