iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 5
1
Modern Web

Laravel 6.0 初體驗!怎麼用最新的 laravel 架網站!系列 第 5

[Day 5] 猝不及防的自動測試教學!怎麼用 Laravel 撰寫自動測試

  • 分享至 

  • xImage
  •  

什麼?這不是只是使用 Laravel 的教學嗎?為什麼突然就講起了自動測試?

(驚恐)

沒有問題,讓自動測試變得簡單也是 Laravel 這個框架的一個重要特性。

實際上,Laravel 在這件事情上,也確實做得很不錯。撰寫自動測試在 Laravel 的支援下非常直觀而且簡單。

所以,就趁機一起把自動測試學好吧!

什麼是自動測試

一般來說,我們常見的測試,就是像之前我們寫完功能後所做的這樣,實際點開寫好的網頁,看看我們撰寫的功能,有沒有照我們的預期運作。

這在網站還小,功能還不多時,是沒有問題的。每次新功能上線之後,我們只需要找一批人進到網站實際點看看各個功能,確定沒有問題就好。

但是!

當你的網站功能越來越多,每個功能又可能互相關聯時,每次增加一個功能都得點開所有網頁,甚至要開啟不同身份的帳號,來檢查所有功能的話,實際上是不可能的。

幸好,我們可以用程式來協助這件事情!

如果我們每次為每個功能撰寫程式時,都寫另一段小程式來測試這個功能。隨著時間過去,需求的改變,雖然功能越來越多,但是相對應的,測試這些功能的程式也會越來越多,並且不管這個功能是多久之前開發的,每個功能都有相對應的測試。

這樣,當我們想知道新加入的功能正不正確時,不就只要將所有的測試程式碼跑過一遍,確認所有的自動測試都正常,就可以知道了新加入的功能有沒有影響到舊功能了嗎?

這就是自動測試的威力!

確認需求

我們只寫了一個 Hello World 而已,要測試些什麼呢?

稍微思考一下,我們可以預期這個程式,應該要有以下行為:

  • 如果連線 hello-world/,HTTP Status 應該要顯示 200(成功連線)
  • 連線到網頁內,應該要可以看到「Hello world!」這些字

即便是這麼簡單的功能,我們仍舊整理出了兩項可供測試的需求。

再來,我們來看看 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);
    }
}

這個測試相當容易理解,我們可以看到,這測試應該是:

  • 連線 / 並取得回傳
  • 檢查回傳的 HTTP Status 是不是 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(成功連線)
  • 連線到網頁內,應該要可以看到「Hello world!」這些字

我們輸入指令

$ 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 這個工具,知道怎麼運作測試,還完成了幾個測試案例!

相信大家收穫都不少吧,明天見!


上一篇
[Day 4] Hello World! 開啟我們自己的第一個網頁!
下一篇
[Day 6] 優化網頁外觀!淺聊 blade 樣板
系列文
Laravel 6.0 初體驗!怎麼用最新的 laravel 架網站!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
jkl99
iT邦新手 5 級 ‧ 2019-09-10 00:34:11

新版的已經預設是 PHPUnit 8了,指令的路徑改成在
vendor/bin/phpunit

https://phpunit.de/getting-started/phpunit-8.html

不好意思 vendor/phpunit/phpunit/phpunit 也可以 留完言才發現

0
ckp6250
iT邦好手 1 級 ‧ 2019-11-26 17:22:45

打卡上課。

0
st474ddr
iT邦新手 2 級 ‧ 2020-01-14 15:49:27

我是運用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)

ReccaChao iT邦新手 1 級 ‧ 2020-02-10 18:23:34 檢舉

改用 vendor/phpunit/phpunit/phpunit 呢?

0
a600masool
iT邦新手 5 級 ‧ 2020-05-13 10:25:29

可以用 artisan 提供的方法來啟動測試,省去找路徑的問題

php artisan test

排版也更清楚哦,比較兩者差異
https://i.imgur.com/dodtDdb.png

查看所有的 artisan 指令

php artisan list
ReccaChao iT邦新手 1 級 ‧ 2020-05-18 11:33:32 檢舉

感謝您的回應

php artisan test 確實是比較好的顯示方式
不過這個方式在 6 上面還不支援,我自己查看的結果應該是在 Laravel 7 上面才支援

我會將這段資訊補充在文章內,再次謝謝您!

1
eric19740521
iT邦新手 1 級 ‧ 2020-08-26 03:59:18

WINDOWS這樣下達,會出錯

vendor/phpunit/phpunit/phpunit
指令找不到

laragon套件的環境,所以WINDOWS環境要這樣下達
要包含 路徑


D:\laragon\www\demo\vendor\bin\phpunit

我要留言

立即登入留言