AdSense

網頁

2021/7/9

Golang 單元測試簡單範例 unit testing simple example

Go語言本身帶有輕量的測試框架testing package可用來撰寫單元測試,以下為簡單範例。


範例環境:

  • Go 1.18

專案目錄結構:

go-demo/
├── demo/
│   ├── demo_test.go
│   └── demo.go
├── go.mod
├── go.sum
└── main.go

package demodemo.go為被測試的程式,有三個函式Plus()Minus()AddBracket()

demo.go

package demo

func Plus(x, y int) int {
    return x + y
}

func Minus(x, y int) int {
    return x - y
}

func AddBracket(s string) string {
    return "[" + s + "]"
}


撰寫測試

demo.go的測試程式建立在同package中,命名為demo_test.go

每支測試函式的名稱以Test開頭,後接被測函式的名稱,固定傳入(t *testing.T)。例如測試Plus()的測試函式為func TestPlus(t *testing.T)

測試程式的撰寫為典型的AAA pattern:

  1. Arrange - 安排測試案例。參數初始化、輸入參數及預期結果。
  2. Act - 執行測試。呼叫被測對象並傳入測試案例參數。
  3. Assert - 驗證結果。比對執行結果與預期結果是否相符。

demo_test.go

package demo

import (
    "testing"
)

func TestPlus(t *testing.T) {
    // Arrange - prepare test cases, input arguments and expected result.
    testCase := struct{ x, y, expected int }{2, 1, 3}

    // Act - call function and pass test case arguments
    result := Plus(testCase.x, testCase.y) // test function Plus() in demo.go

    // Assert - compare actual result with expected result
    if result != testCase.expected {
        t.Errorf("Plus(%d, %d) == %d, but expect %d",
            testCase.x, testCase.y, result, testCase.expected)
    }
}

func TestMinus(t *testing.T) {
    testCases := []struct {
        x, y, expected int
    }{
        {2, 1, 1},    // test case 1
        {3, 1, 2},    // test case 2
        {100, 1, 99}, // test case 3
    }

    for _, testCase := range testCases { // execute test cases one by one
        result := Minus(testCase.x, testCase.y)
        if result != testCase.expected {
            t.Errorf("Minus(%d, %d) == %d, but expect %d",
                testCase.x, testCase.y, result, testCase.expected)
        }
    }

}

func TestAddBracket(t *testing.T) {
    testCases := []struct {
        s, expected string
    }{
        {"hello world", "[hello world]"},
        {"Nice", "[Nice]"},
    }

    for _, testCase := range testCases {
        result := AddBracket(testCase.s)
        if result != testCase.expected {
            t.Errorf("AddBracket(%s) == %s, but expect %s ",
                testCase.s, result, testCase.expected)
        }
    }
}

github


執行測試

在專案根目錄命令列輸入go test ./demo或在/demo目錄命令列輸入go test執行測試程式。

~/../go-demo/demo$ go test
PASS
ok      abc.com/demo/demo    0.297s

加上-v參數輸出每個測試的log。

~/../go-demo/demo$ go test -v
=== RUN   TestPlus
--- PASS: TestPlus (0.00s)
=== RUN   TestMinus
--- PASS: TestMinus (0.00s)
=== RUN   TestAddBracket
--- PASS: TestAddBracket (0.00s)
PASS
ok      abc.com/demo/demo       0.099s

執行特定測試函式輸入go test -run <TestFunctionName><TestFunctionName>為要執行的測試函式名稱。

例如下面執行demo_test.goTestMinus()

~/../go-demo/demo$$ go test -run TestMinus
PASS
ok      abc.com/demo/demo       0.297s

在專案根目錄執行特定測試函式,輸入go test ./... -run <TestFunctionName>

~/../go-demo$ go test ./... -run TestPlus
?       abc.com/demo    [no test files]
ok      abc.com/demo/demo       0.098s

不過go的testing並沒有提供單元測試常用的mock,要自己寫或使用testify或gomock套件。



沒有留言:

AdSense