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.govà nằm trong cùng gói với mã mà chúng kiểm tra (hoặc trong gói<name>_testdà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 đóXxxbắt đầu bằng chữ in hoa. - Bạn nhập
testingtừ stdlib. - Không
assertEquals: bạn sử dụngif got != want { t.Errorf(...) }với động từfmt.
// 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:
go test ./... # all packages in the module
go test -v ./pkg # verbose: prints test names
go test -run TestSum # only tests matching the regext.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áp | Hiệ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.
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:
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:
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
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.
Giải pháp khả dụng sau 3 lần thử
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.
Giải pháp khả dụng sau 3 lần thử
Sự khác biệt cơ bản giữa t.Error và t.Fatal là gì?
if err != nil {
t.???(err)
}