隨著我們的 C# 程式越寫越多,功能也越來越複雜,這時候就會出現一個問題:
「我改了某段程式碼,會不會不小心讓別的功能壞掉?」
這正是 單元測試(Unit Testing) 存在的理由。
透過單元測試,我們可以:
而今天要介紹的主角是 C# 最常用的測試框架之一—— xUnit.net。那什麼是 xUnit呢?xUnit 是一個開源、輕量、現代化的 .NET 測試框架,由原先開發 NUnit 的工程師所設計,它的設計理念是「簡單、可擴充、符合 .NET Core 精神」。xUnit的官方網站
首先,先建立一個範例專案:
# 建立主要程式
dotnet new console -n CalculatorApp
cd CalculatorApp
# 建立測試專案
dotnet new xunit -n CalculatorApp.Tests
# 將測試專案指向主專案
dotnet add CalculatorApp.Tests reference ../CalculatorApp
專案結構會長這樣:
📁 CalculatorApp/
│ ├── Program.cs
│ └── Calculator.cs
📁 CalculatorApp.Tests/
│ └── CalculatorTests.cs
首先在Calculator.cs內:
namespace CalculatorApp
{
public class Calculator
{
public int Add(int a, int b) => a + b;
public int Divide(int a, int b)
{
if (b == 0)
throw new DivideByZeroException("不能除以零");
return a / b;
}
}
}
接著在 CalculatorApp.Tests 裡建立 CalculatorTests.cs:
using Xunit;
using CalculatorApp;
namespace CalculatorApp.Tests
{
public class CalculatorTests
{
[Fact]
public void Add_ShouldReturnCorrectSum()
{
// Arrange
var calc = new Calculator();
// Act
var result = calc.Add(3, 5);
// Assert
Assert.Equal(8, result);
}
[Fact]
public void Divide_ByZero_ShouldThrowException()
{
var calc = new Calculator();
var ex = Assert.Throws<DivideByZeroException>(() => calc.Divide(5, 0));
Assert.Equal("不能除以零", ex.Message);
}
}
}
執行測試指令:
dotnet test
輸出結果會像這樣:
Starting test execution, please wait...
Passed! - 2 passed, 0 failed, 0 skipped
在上面測試程式碼中
[Theory]
[InlineData(2, 3, 5)]
[InlineData(-1, 5, 4)]
public void Add_VariousInputs_ShouldReturnCorrectSum(int a, int b, int expected)
{
var calc = new Calculator();
Assert.Equal(expected, calc.Add(a, b));
}
這樣就能一次測試多組輸入資料。
今日學到的幾個重點如下:
功能 | 說明 |
---|---|
xUnit | 現代化的 .NET 測試框架 |
[Fact] / [Theory] | 測試不同型態的輸入情境 |
Assert 類別 | 驗證預期結果 |
dotnet test | 執行所有測試 |
到目前為止,本次的 C# 學習之旅從語法基礎、物件導向、非同步、檔案存取一路走來,今天終於學會了如何確保程式的品質與穩定性。程式寫得再好,不測試都只是幻覺,而測試讓我們有信心在未來繼續改進與擴充程式。接下來也會繼續努力!!