Chuyển đến nội dung chính
Mô-đun 9 · Bài học 1 trong tổng số 541/50 trong khóa học~12 min
Bài học theo mô-đun (1/5)

Gói `thử nghiệm`

Trong Go, các bài kiểm tra là một phần của stdlib: không có thư viện bên ngoài, không có khung để định cấu hình. Tất cả những gì bạn cần là tệp *_test.go bên cạnh mã, một vài hàm TestXxx và lệnh go test.

Các quy ước cơ bản

  • Tệp kiểm tra có tên là <something>_test.go và nằm trong cùng gói với mã mà chúng kiểm tra (hoặc trong gói <name>_test dành cho "kiểm tra hộp đen").
  • Hàm kiểm tra có chữ ký chính xác: func TestXxx(t *testing.T) trong đó Xxx bắt đầu bằng chữ in hoa.
  • Bạn nhập testing từ stdlib.
  • Không assertEquals: bạn sử dụng if got != want { t.Errorf(...) } với động từ fmt.
Go
// math.go
package math

func Sum(a, b int) int { return a + b }

// math_test.go
package math

import "testing"

func TestSum(t *testing.T) {
    got := Sum(2, 3)
    if got != 5 {
        t.Errorf("Sum(2,3) = %d; voglio %d", got, 5)
    }
}

Chạy nó với:

Bash
go test ./...        # all packages in the module
go test -v ./pkg     # verbose: prints test names
go test -run TestSum  # only tests matching the regex

t.Error đấu với t.Fatal

Đây là hai động từ cơ bản để báo hiệu sự thất bại:

Phương phápHiệu ứng
t.Log(args...)Ghi nhật ký nhưng không bị lỗi (chỉ hiển thị với -v hoặc khi bị lỗi).
t.Error(args...)Ghi nhật ký, đánh dấu THẤT BẠI, tiếp tục chức năng kiểm tra.
t.Errorf(fmt, ...)Giống như Error với định dạng.
t.Fatal(args...)Ghi nhật ký, đánh dấu THẤT BẠI, dừng bài kiểm tra (gọi runtime.Goexit).
t.Fatalf(fmt, ...)Giống như Fatal với định dạng.

Nguyên tắc chung: sử dụng Fatal khi việc tiếp tục không có ý nghĩa gì (ví dụ: thiết lập không thành công, sắp hủy đăng ký con trỏ nil); nếu không thì Error, cho phép bạn xem tất cả các lỗi trong một lần chạy.

Go
func TestOpen(t *testing.T) {
    f, err := os.Open("fixtures/sample.txt")
    if err != nil {
        t.Fatal(err) // if it doesn't open, the next steps would fail on nil
    }
    defer f.Close()
    // ... assert on content with t.Errorf
}

Thiết lập và phân tích bằng t.Cleanup

Để giải phóng tài nguyên khi kết thúc thử nghiệm (hoặc thử nghiệm phụ), hãy sử dụng t.Cleanup thay vì defer:

Go
func TestDB(t *testing.T) {
    db := newTestDB(t)
    t.Cleanup(func() { db.Close() })
    // ... test
}

Ưu điểm so với defer: người trợ giúp tạo db có thể đăng ký dọn dẹp nội bộ, vì vậy người gọi không cần phải nhớ nó.

Người trợ giúp kiểm tra

Phương thức t.Helper() đánh dấu một hàm là "trình trợ giúp": khi thử nghiệm thất bại, dấu vết ngăn xếp bỏ qua hàm trợ giúp và trỏ trực tiếp đến lệnh gọi:

Go
func mustParseInt(t *testing.T, s string) int {
    t.Helper()
    n, err := strconv.Atoi(s)
    if err != nil {
        t.Fatalf("parse %q: %v", s, err)
    }
    return n
}

Bài tập

tập thể dục#go.m9.l1.e1
Nỗ lực: 0Đang tải…

Xác định hàm TestSum xác minh Sum(2,3) == 5 bằng cách sử dụng t.Errorf với thông báo được định dạng.

Đang tải trình chỉnh sửa…

Giải pháp khả dụng sau 3 lần thử

tập thể dục#go.m9.l1.e2
Nỗ lực: 0Đang tải…

Trong TestDiv, hãy sử dụng t.Fatal để dừng ngay việc kiểm tra nếu Div trả về giá trị không mong muốn.

Đang tải trình chỉnh sửa…

Giải pháp khả dụng sau 3 lần thử

Quiz#go.m9.l1.e3
Sẵn sàng

Sự khác biệt cơ bản giữa t.Error và t.Fatal là gì?

Go
if err != nil {
  t.???(err)
}
Tùy chọn trả lời