[軟體概念入門系列] 自動化測試與持續整合

Brett Yu
Brett’s dev log
Published in
7 min readNov 4, 2023

本節介紹自動化測試相關概念及技術

功能性測試

下圖為測試金字塔, 主要將測試分為以下幾種

  • Manual Test 手動測試

以手動操作模擬終端使用者透過畫面操作的結果

  • End to end(GUI) Test 端點對端點測試

撰寫自動測試以模擬終端使用者透過畫面操作的結果

  • Integration Test 整合測試

自動化測試多個類別, 模組等組合運作的結果

  • Unit Test 單元測試

針對單一個程式method/function的邏輯進行自動化測試, 需要隔絕外部環境影響如資料庫, 外部Api等條件

金字塔越底層的測試一般來說越容易定位問題, 較不易受到改動影響, 維護成本較低, 執行速度較快, 應占整體測試中最高比例

而越上層的測試則較難定位問題, 較為脆弱, 維護成本較高, 執行速度較慢, 應占整體測試中最少比例, 但也由於最貼近使用者行為, 故對整體系統及商業價值來說較有效益

Smoke Test 冒煙測試

對新版本的程式做廣而不深入的快速測試, 以便判斷此版本是否要進行更進一步的測試或發佈

Regression Test 回歸測試

對新版本的程式異動的範圍做其他相關功能的測試, 以確保本次異動沒有影響到系統的其他部分

Sanity Test 可用性測試

對新版的程式異動的範圍內做測試, 以便判斷修正範圍是否有如預期運作, 相對於回歸測試範圍較窄但較節省測試時間

非功能性測試

Load Testing 負載測試

針對系統預期服務的數量, 如同時可上線人數1000人, 則以相同的數量進行正常的系統操作並觀察系統是否如預期般正常執行

Soak Testing 浸泡測試

在預期的最大系統負荷下進行長時間的測試, 確保系統能如預期般正常執行, 並監控是否會有資源未正確釋放造成Memory leak等問題

Stress Testing 壓力測試

在超過預期最大負荷的情況下進行測試, 以觀察系統瓶頸以及系統是否可正確執行, 若有發生錯誤是否可自行正常回復等

Penetration Testing 滲透測試

模擬惡意攻擊者用各種方式找到系統漏洞以竊取資料或攻擊系統, 以在系統遭受真正的惡意攻擊前可以預先修復相關漏洞

測試驅動開發

測試驅動開發是一種先撰寫自動化測試案例, 再開發實際應用程式的開發方式

一次只新增一個測試案例, 並撰寫「剛剛好」讓測試案例通過的應用程式程式碼, 接著在不弄壞任一測試案例的情況下進行重構, 以此方式反覆循環, 最終可以得到被測試案例保護及沒有冗餘設計邏輯的應用程式

Test-driven development​

一般而言提到TDD通常是指Unit Test為主的測試案例來作為開發的驅動, 但也可使用Integration Test

如以下是一個由C#實作的Unit Test及實際的應用程式Method

[TestMethod()]
public void Add_Input_First_1_Second_2_Return_3()
{
//arrange
Calculator target = new Calculator();
int firstNumber = 1;
int secondNumber = 2;
int expected = 3;

//act
int actual;
actual = target.Add(firstNumber, secondNumber);

//assert
Assert.AreEqual(expected, actual);
}

public class Calculator
{
public int Add(int firstNumber, int secondNumber)
{
return firstNumber + secondNumber;
}
}

Behavior-driven development​ 與 Acceptance Test-Driven development​

TDD在專案中遇到的問題是測試案例主要由開發人員自行撰寫, 未必符合使用者需求

BDD與ATDD較為相近, 都是用Given, When, Then (Gherkin語法)來表達系統行為, 並以此作為測試案例, 也稱作為實例化需求 (Specification by Example), 兩者差別在於ATDD較貼近User實際使用情境, 而BDD可以用來驗證非使用者可見的系統行為

有測試案例後, 便可使用 Cucumber 這類的Framework將測試案例轉為可執行的測試程式 (通常為Integration Test或End to end Test), 並以此作為測試驅動開發

User Story​
As an operator, I want to login to BO and view the function menu​
Given an existing operator go to BO login page​
When he/she login successfully​
Then he/she can view the function menu

Continuous Integration

自動化測試與CI持續整合有相當緊密的關係, 當Developer將程式碼合併至master或其他指定branch時, CI Server會偵測到這個新的commit, 並將此版本取出執行自動化測試以確保此版本沒有問題

也可將Smoke Test安排在CI Server的排程中, 以定期確認特定環境的健康度

視測試的種類而定, 有些Integration Test可能需要在每次測試前先建立相關資料庫或外部資源等, 故應依據自動化測試的種類及目的來規畫執行的頻率以及時機

Command-Line Interface 命令列介面與自動化

前述章節提到的Git版本控制, 執行自動化測試, 將程式碼建立成Docker Image, 以Docker Image建立Container等等動作, 都有對應的命令列介面讓使用者輸入指令就可以做到對應的動作

相對的這些命令也可以由程式在適當的時間點自動執行, 或由使用者手動觸發去執行後續一系列的步驟, 公司內常用的平台有Jenkins, Gitlab Runner以及Ansible Tower (AWX)

Jenkins

Jenkins是一個持續整合的工具平台, 可以在上面建立Job以執行自動化測試, 也可以用來執行自動化部屬或其他任何可以透過CLI指令執行的作業

Jenkins Job可以由手動觸發, 也提供Api Webhook由外部系統如Gitlab, 或甚至是Slack, Teams等通訊軟體來自動觸發

除了Jenkins, 其他也有Gitlab Runner, Teamcity, Maven等替代工具

--

--