Thêm một bài kiểm thử

Bây giờ mã của bạn đã ổn định (làm tốt lắm), hãy thêm một bài kiểm thử. Kiểm thử mã trong quá trình phát triển giúp phát hiện lỗi có thể xuất hiện khi bạn thay đổi code. Trong phần này, bạn sẽ thêm một bài kiểm thử cho hàm Hello.

Hỗ trợ kiểm thử đơn vị tích hợp sẵn của Go giúp việc kiểm thử trở nên dễ dàng hơn. Cụ thể, bằng cách sử dụng quy ước đặt tên, gói testing của Go và lệnh go test, bạn có thể nhanh chóng viết và chạy các bài kiểm thử.

  1. Trong thư mục greetings, tạo một tệp có tên greetings_test.go.

    Kết thúc tên tệp bằng _test.go sẽ báo cho lệnh go test biết tệp này chứa các hàm kiểm thử.

  2. Trong greetings_test.go, dán đoạn mã sau vào và lưu tệp.
    package greetings
    
    import (
        "testing"
        "regexp"
    )
    
    // TestHelloName calls greetings.Hello with a name, checking
    // for a valid return value.
    func TestHelloName(t *testing.T) {
        name := "Gladys"
        want := regexp.MustCompile(`\b`+name+`\b`)
        msg, err := Hello("Gladys")
        if !want.MatchString(msg) || err != nil {
            t.Errorf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want)
        }
    }
    
    // TestHelloEmpty calls greetings.Hello with an empty string,
    // checking for an error.
    func TestHelloEmpty(t *testing.T) {
        msg, err := Hello("")
        if msg != "" || err == nil {
            t.Errorf(`Hello("") = %q, %v, want "", error`, msg, err)
        }
    }
    

    Trong đoạn mã này, bạn:

    • Triển khai các hàm kiểm thử trong cùng gói với mã bạn đang kiểm thử.
    • Tạo hai hàm kiểm thử để kiểm thử hàm greetings.Hello. Tên hàm kiểm thử có dạng TestName, trong đó Name mô tả nội dung kiểm thử cụ thể. Ngoài ra, các hàm kiểm thử nhận một con trỏ tới kiểu testing.T của gói testing làm tham số. Bạn dùng các phương thức của tham số này để báo cáo và ghi log trong quá trình kiểm thử.
    • Triển khai hai bài kiểm thử:
      • TestHelloName gọi hàm Hello, truyền vào một giá trị name mà hàm phải có khả năng trả về một thông điệp hợp lệ. Nếu lời gọi trả về lỗi hoặc thông điệp không như mong đợi (không chứa tên bạn đã truyền vào), bạn dùng phương thức Errorf của tham số t để in thông báo ra console.
      • TestHelloEmpty gọi hàm Hello với một chuỗi rỗng. Bài kiểm thử này được thiết kế để xác nhận rằng cơ chế xử lý lỗi của bạn hoạt động đúng. Nếu lời gọi trả về chuỗi không rỗng hoặc không có lỗi, bạn dùng phương thức Errorf của tham số t để in thông báo ra console.
  3. Tại dòng lệnh trong thư mục greetings, chạy lệnh go test để thực thi bài kiểm thử.

    Lệnh go test thực thi các hàm kiểm thử (có tên bắt đầu bằng Test) trong các tệp kiểm thử (có tên kết thúc bằng _test.go). Bạn có thể thêm cờ -v để nhận đầu ra chi tiết liệt kê tất cả các bài kiểm thử và kết quả của chúng.

    Các bài kiểm thử sẽ vượt qua.

    $ go test
    PASS
    ok      example.com/greetings   0.364s
    
    $ go test -v
    === RUN   TestHelloName
    --- PASS: TestHelloName (0.00s)
    === RUN   TestHelloEmpty
    --- PASS: TestHelloEmpty (0.00s)
    PASS
    ok      example.com/greetings   0.372s
    
  4. Phá hàm greetings.Hello để xem một bài kiểm thử thất bại.

    Hàm kiểm thử TestHelloName kiểm tra giá trị trả về có chứa tên bạn chỉ định làm tham số cho hàm Hello hay không. Để xem kết quả kiểm thử thất bại, hãy thay đổi hàm greetings.Hello để nó không còn chứa tên nữa.

    Trong greetings/greetings.go, dán đoạn mã sau để thay thế hàm Hello. Lưu ý rằng các dòng được đánh dấu thay đổi giá trị mà hàm trả về, như thể tham số name đã bị vô tình bỏ đi.

    // Hello returns a greeting for the named person.
    func Hello(name string) (string, error) {
        // If no name was given, return an error with a message.
        if name == "" {
            return name, errors.New("empty name")
        }
        // Create a message using a random format.
        // message := fmt.Sprintf(randomFormat(), name)
        message := fmt.Sprint(randomFormat())
        return message, nil
    }
    
  5. Tại dòng lệnh trong thư mục greetings, chạy go test để thực thi bài kiểm thử.

    Lần này, hãy chạy go test mà không có cờ -v. Đầu ra sẽ chỉ bao gồm kết quả của các bài kiểm thử thất bại, điều này rất hữu ích khi bạn có nhiều bài kiểm thử. Bài kiểm thử TestHelloName sẽ thất bại -- TestHelloEmpty vẫn vượt qua.

    $ go test
    --- FAIL: TestHelloName (0.00s)
        greetings_test.go:15: Hello("Gladys") = "Hail, %v! Well met!", <nil>, want match for `\bGladys\b`, nil
    FAIL
    exit status 1
    FAIL    example.com/greetings   0.182s
    

Trong phần tiếp theo (và cuối cùng), bạn sẽ học cách biên dịch và cài đặt mã của mình để chạy nó cục bộ.