PHPUnit 自動化測試大作戰【CH25】

閱讀時間約 12 分鐘

今天就讓我們依照前一天的情境題,來撰寫測試案例函數吧!

先讓我們規畫擬訂測試案例:

測試案例

當使用者瀏覽文章清單頁時:

  1. 使用者可看到所有文章清單,也就是【文章清單API】要能確實將資料庫內的文章資料,筆數不多不少地回應出來。

當使用者瀏覽單一文章頁時:

  1. 使用者可看到該文章資料,也就是【單一文章API】要能確實將指定ID之文章在資料庫內的資料回應出來,並包含所有欄位。
  2. 使用者可取得單一文章評論清單資料,也就是【單一文章評論清單API】要能確實將指定ID之文章在資料庫內的評論資料回應出來,並包含所有欄位。

當使用者對單一文章新增評論時:

  1. 使用者可針對此單一文章新增評論資料,也就是【新增單一文章評論API】在接受請求後,需新增一筆資料到資料庫。
  2. 使用者新增評論後,再次呼叫該文章評論清單API時,其回應資料應有包含新增的評論資料。

話不多說,來寫 Code !

測試案例函數實作

  • tests/Feature/ArticleControllerTest.php
<?php

namespace Tests\Feature;

use App\Models\Article;

use App\Models\User;

use Database\Seeders\ArticleSeeder;

use Database\Seeders\UserSeeder;

use Illuminate\Foundation\Testing\RefreshDatabase;

use Illuminate\Foundation\Testing\WithFaker;

use Illuminate\Foundation\Testing\WithoutMiddleware;

use Tests\TestCase;

class ArticleControllerTest extends TestCase{

use WithoutMiddleware;

use WithFaker;

use RefreshDatabase;

public function setUp(): void {

parent::setUp();

// 建立通用測試資料

$this->seed([

UserSeeder::class,

ArticleSeeder::class,

]); } public function testUserBrowseArticleList() {

// 建立測試資料

$articles = Article::all();

// 執行測試行為:對【文章清單API】發出請求

$response = $this->get(route('article.list'));

$response->assertOk()

->assertJsonStructure([

'data' => [

'*' => [

'id',

'content',

], ], ]); $list = $response->json('data');

$listExpected = $articles->toArray();

// 驗證結果

$this->assertJsonStringEqualsJsonString(json_encode($listExpected), json_encode($list));

$this->assertCount($articles->count(), $list);

} public function testUserBrowseOneArticle() {

// 建立測試資料

$article = Article::find(1);

// 執行測試行為:對【單一文章API】發出請求

$response = $this->get(route('article.one', ['id' => $article->id]));

$response->assertOk()

->assertJson([

'data' => [

'id' => $article->id,

'content' => $article->content,

], ]); $comments = $article->comments;

$responseComments = $this->get(route('article.one.comments', ['id' => $article->id]));

$list = $responseComments->json('data');

$listExpected = $comments->toArray();

// 驗證結果

$this->assertJsonStringEqualsJsonString(json_encode($listExpected), json_encode($list));

$responseComments->assertOk()

->assertJsonStructure([

'data' => [

'*' => [

'id',

'article_id',

'user_id',

'content',

], ], ]); $this->assertCount($comments->count(), $list);

} public function testUserPostCommentOnOneArticle() {

// 建立測試資料

$user = User::first();

$article = Article::find(1);

$data = [

'comment' => $this->faker->text,

]; // 執行測試行為:對【新增單一文章評論API】發出請求

$response = $this->be($user)->post(route('article.one.comments.store', ['id' => $article->id]), $data);

$responseComments = $this->get(route('article.one.comments', ['id' => $article->id]));

$responseCommentsList = $responseComments->json('data');

$foundPostedComment = false;

foreach ($responseCommentsList as $comment) {

if ($comment['content'] === $data['comment']) {

$foundPostedComment = true;

break;

} } // 驗證結果

$response->assertOk();

$this->assertDatabaseHas('comments', [

'article_id' => $article->id,

'user_id' => $user->id,

'content' => $data['comment'],

]); $this->assertTrue($foundPostedComment);

}}

在以上程式碼中,我們實作了以下測試案例函數:

  • testUserBrowseArticleList()

在這個測試案例函數中,我們呼叫了【文章清單API】,並確認回應是否成功,資料結構是否符合預期,且是否就是資料庫中的所有資料。

  • testUserBrowseOneArticle()

在這個測試案例函數中,我們呼叫了【單一文章API】及【單一文章評論API】,並各自確認回應是否成功,資料結構是否符合預期,且是否就是資料庫中的所有資料。

  • testUserPostCommentOnOneArticle()

在這個測試案例函數中,我們呼叫了【新增單一文章評論API】,並確認回應是否成功,資料結構是否符合預期,且資料庫中是否有新增對應資料。接著,呼叫【單一文章評論API】,看其回應之是否包含剛新增的評論資料。

除此之外,我們在 setUp() 函數內呼叫了 2 個 Seeder,建立各測試案例函數都會用到的通用測試資料:

  • setUp()
public function setUp(): void{

parent::setUp();

// 建立通用測試資料

$this->seed([

UserSeeder::class,

ArticleSeeder::class,

]);}

此外,我們使用了幾個測試相關 Traits 來協助我們執行測試:

  • WithoutMiddleware:略過 Middleware 層之運行
  • WithFaker:方便建立假資料
  • RefreshDatabase:重建測試資料庫之用

以上就是今天的練習,希望對大家有所幫助。

下一篇讓我們再探討另一個情境題!

如果您喜歡這篇文章,歡迎加入追蹤以接收新文章通知 😄

本系列文章目錄

8會員
223內容數
歡迎來到 WilliamP 的沙龍天地,在這裡將與各位讀者探討各種主題,包刮高中數學題庫、PHP開發經驗、LINE聊天機器人開發經驗、書摘筆記等,歡迎交流!
留言0
查看全部
發表第一個留言支持創作者!
WilliamP的沙龍 的其他內容
在前面的篇幅中,與大家分享了許多撰寫 PHPUnit 測試程式碼所需的知識,之後的文章就讓我們來來模擬一些情境題,並在這些情境題底下,實際去設計測試案例函數吧! 作為第一個情境題,我們就選「網站文章」來當作第一個挑戰吧! 這邊我們假設網站是採前後端分離的設計,因此我們就專注在測試 API 的部分
今天我們來聊聊覆蓋率報告吧! 何為覆蓋率報告 & 為何需要覆蓋率報告 所謂的覆蓋率報告,指的是能指出我們的專案程式庫,有被測試程式碼實際測試到的部分的佔比有多少。當我們了解有多少程式碼有被覆蓋到,以及有多少程式碼沒被覆蓋到時,理論上我們可以對程式碼是否可正常運作更有信心! 事前準備 先將以
今天讓我們來看 phpunit.xml 吧! phpunit.xml 位在 Laravel 專案根目錄底下,顧名思義,它是一個設定 PHPUnit 執行方式的設定XML檔,PHPUnit 提供了不少設定值可供設定,這邊只提最重要的幾個: stopOnFailure 說明:當此欄位設定為 tru
今天要來為大家介紹 Storage Mocking 及 HTTP Mocking! Storage Mocking 函數 Storage::fake():當我們希望在執行測試目標行為時,想驗證 Storage 各類行為是否符合預期,但又不要真的增刪改檔案時,可在測試程式碼中呼叫此函數。 Upl
今天來看 Queue Mocking 吧! Queue Mocking 函數 Queue::fake():當我們希望在執行測試目標行為時,想驗證某個 Job 類別是否有被派送至佇列中,但又不要真的觸發 Job 入列時,可在測試程式碼中呼叫此函數。 Queue::assertPushed():可
今天來看 Mail Mocking 吧! Mail Mocking 函數 Mail::fake():當我們希望在執行測試目標行為時, 想驗證是否有觸發到發送 Email ,但又不要真的觸發 Email 的寄送時,可在測試程式碼中呼叫此函數。 Mail::assertSent():可驗證指定的
在前面的篇幅中,與大家分享了許多撰寫 PHPUnit 測試程式碼所需的知識,之後的文章就讓我們來來模擬一些情境題,並在這些情境題底下,實際去設計測試案例函數吧! 作為第一個情境題,我們就選「網站文章」來當作第一個挑戰吧! 這邊我們假設網站是採前後端分離的設計,因此我們就專注在測試 API 的部分
今天我們來聊聊覆蓋率報告吧! 何為覆蓋率報告 & 為何需要覆蓋率報告 所謂的覆蓋率報告,指的是能指出我們的專案程式庫,有被測試程式碼實際測試到的部分的佔比有多少。當我們了解有多少程式碼有被覆蓋到,以及有多少程式碼沒被覆蓋到時,理論上我們可以對程式碼是否可正常運作更有信心! 事前準備 先將以
今天讓我們來看 phpunit.xml 吧! phpunit.xml 位在 Laravel 專案根目錄底下,顧名思義,它是一個設定 PHPUnit 執行方式的設定XML檔,PHPUnit 提供了不少設定值可供設定,這邊只提最重要的幾個: stopOnFailure 說明:當此欄位設定為 tru
今天要來為大家介紹 Storage Mocking 及 HTTP Mocking! Storage Mocking 函數 Storage::fake():當我們希望在執行測試目標行為時,想驗證 Storage 各類行為是否符合預期,但又不要真的增刪改檔案時,可在測試程式碼中呼叫此函數。 Upl
今天來看 Queue Mocking 吧! Queue Mocking 函數 Queue::fake():當我們希望在執行測試目標行為時,想驗證某個 Job 類別是否有被派送至佇列中,但又不要真的觸發 Job 入列時,可在測試程式碼中呼叫此函數。 Queue::assertPushed():可
今天來看 Mail Mocking 吧! Mail Mocking 函數 Mail::fake():當我們希望在執行測試目標行為時, 想驗證是否有觸發到發送 Email ,但又不要真的觸發 Email 的寄送時,可在測試程式碼中呼叫此函數。 Mail::assertSent():可驗證指定的
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
練習 PHPUnit 測試的撰寫,依序創建Controller、Service,並針對計算邏輯進行單元測試的練習。
Thumbnail
在 Laravel 中的測試中,PHPUnit 和 Mockery 都可以用來創建測試替身(test double),但它們有不同的方式和功能,以下簡單介紹兩種寫法方式。
前言 基本準備差不多了,也能跑自己的測試,再來就是關於測試腳本的核心:元素定位跟動作,本篇會著重介紹 XPATH 定位的部分
Thumbnail
前言 上篇我們成功執行第一個測試案例,從 Python 腳本透過 Appium 控制模擬器點選設定中的電池,下個問題就是怎麼找元件,這時候就要請出 Appium Inspector 了
前言 經過五個小單元的準備,終於可以開始跑第一個測試了,Appium 本身是個工具,可以搭配各種語言,這邊選擇 Python 作為測試腳本語言,以便之後跟 Robot Framework 串接。
前言 前四篇,把主機作業系統跟待測物準備交代完畢,有需要請自行跳轉取用,接下來就是測試工具的部分,這次測試套件使用大名鼎鼎 Appium 2。 選擇 Appium 2 的理由 歷史悠久:Appium 2012 年公開之後,就廣受測試社群愛戴 站在巨人的肩榜上:架構類似 Selenium的主從式架構,
前言 前幾篇聊到作業系統、Docker 跟 Android 容器的準備,再來就是替 Android 容器開啟 Google Play 套件並安裝待測 App 供後續手動或者自動測試使用。
前言 前兩篇把作業系統跟 Docker 安裝講完了,接下來就是 Android 容器的安裝了,這裡選用 ReDroid ,因為它是開源、高效、又便於管理的方案。
Thumbnail
前言 前篇把 Ubuntu 作業系統的安裝跟準備談完了,有需要可以跳回去看。接下來聊容器服務 Docker 的安裝與使用。 Docker 可以應用的場合很多,這次是會用它來模擬 Android 受測裝置
前言 本 App 自動化測試專題,用來記錄自動化 App 測試的各環節,包含環境準備、套件安裝、腳本編寫、執行測試與整合。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
練習 PHPUnit 測試的撰寫,依序創建Controller、Service,並針對計算邏輯進行單元測試的練習。
Thumbnail
在 Laravel 中的測試中,PHPUnit 和 Mockery 都可以用來創建測試替身(test double),但它們有不同的方式和功能,以下簡單介紹兩種寫法方式。
前言 基本準備差不多了,也能跑自己的測試,再來就是關於測試腳本的核心:元素定位跟動作,本篇會著重介紹 XPATH 定位的部分
Thumbnail
前言 上篇我們成功執行第一個測試案例,從 Python 腳本透過 Appium 控制模擬器點選設定中的電池,下個問題就是怎麼找元件,這時候就要請出 Appium Inspector 了
前言 經過五個小單元的準備,終於可以開始跑第一個測試了,Appium 本身是個工具,可以搭配各種語言,這邊選擇 Python 作為測試腳本語言,以便之後跟 Robot Framework 串接。
前言 前四篇,把主機作業系統跟待測物準備交代完畢,有需要請自行跳轉取用,接下來就是測試工具的部分,這次測試套件使用大名鼎鼎 Appium 2。 選擇 Appium 2 的理由 歷史悠久:Appium 2012 年公開之後,就廣受測試社群愛戴 站在巨人的肩榜上:架構類似 Selenium的主從式架構,
前言 前幾篇聊到作業系統、Docker 跟 Android 容器的準備,再來就是替 Android 容器開啟 Google Play 套件並安裝待測 App 供後續手動或者自動測試使用。
前言 前兩篇把作業系統跟 Docker 安裝講完了,接下來就是 Android 容器的安裝了,這裡選用 ReDroid ,因為它是開源、高效、又便於管理的方案。
Thumbnail
前言 前篇把 Ubuntu 作業系統的安裝跟準備談完了,有需要可以跳回去看。接下來聊容器服務 Docker 的安裝與使用。 Docker 可以應用的場合很多,這次是會用它來模擬 Android 受測裝置
前言 本 App 自動化測試專題,用來記錄自動化 App 測試的各環節,包含環境準備、套件安裝、腳本編寫、執行測試與整合。