☰ Mục lục series
Tài liệu Go tiếng Việt
  1. Bắt đầu (Getting started)
    1. Tổng quan
    2. Tải về và cài đặt
    3. Bắt đầu với Go
    4. Quản lý các bản cài đặt Go
    5. Plugin trình soạn thảo và IDE
  2. Dạo quanh Go (A Tour of Go)
    1. Chào mừng
    2. Package, biến và hàm
    3. Điều khiển luồng
    4. Struct, slice và map
    5. Method và interface
    6. Generics
    7. Xử lý đồng thời
  3. Hướng dẫn (Tutorials)
    1. Danh sách hướng dẫn
    2. Tạo một Go module
    3. Gọi mã của bạn từ một module khác
    4. Trả về và xử lý lỗi
    5. Trả về lời chào ngẫu nhiên
    6. Trả về lời chào cho nhiều người
    7. Thêm một test
    8. Biên dịch và cài đặt ứng dụng
    9. Kết luận
    10. Bắt đầu với workspace nhiều module
    11. Phát triển RESTful API với Go và Gin
    12. Truy cập cơ sở dữ liệu quan hệ
    13. Bắt đầu với generics
    14. Bắt đầu với fuzzing
    15. Làm việc với JSON
    16. Tìm và sửa các dependency có lỗ hổng với govulncheck
    17. Tìm và khắc phục phụ thuộc có lỗ hổng với VS Code Go
    18. Viết ứng dụng web
  4. Viết code Go
    1. Cách viết mã Go
    2. Effective Go
    3. Doc Comment trong Go
  5. Module
    1. Phát triển và publish module
    2. Quản lý phụ thuộc
    3. Tổ chức một module Go
    4. Quản lý mã nguồn của module
    5. Cách đánh số phiên bản module
    6. Quy trình phát hành và đánh phiên bản module
    7. Publish một module
    8. Phát triển một bản cập nhật major version
    9. Tham chiếu tệp go.mod
    10. Ngừng hỗ trợ 'go get' cho việc cài đặt tệp thực thi
  6. Cơ sở dữ liệu (Database)
    1. Truy cập cơ sở dữ liệu quan hệ
    2. Mở một handle cơ sở dữ liệu
    3. Thực thi câu lệnh SQL không trả về dữ liệu
    4. Truy vấn dữ liệu
    5. Dùng prepared statement
    6. Thực thi transaction
    7. Huỷ các thao tác đang chạy
    8. Quản lý kết nối
    9. Tránh rủi ro SQL injection
  7. Chẩn đoán và hiệu năng
    1. Chẩn đoán
    2. Hướng dẫn về Go Garbage Collector
    3. Tối ưu hoá dựa trên profile
    4. Data Race Detector
    5. Gỡ lỗi mã Go bằng GDB
    6. Hỗ trợ coverage profiling cho integration test
  8. Bảo mật (Security)
    1. Tổng quan bảo mật
    2. Thực hành tốt về bảo mật cho lập trình viên Go
    3. Quản lý lỗ hổng trong Go
    4. Cơ sở dữ liệu lỗ hổng của Go
    5. Quét lỗ hổng trong IDE
    6. Chính sách CNA của Go
    7. Go Fuzzing
    8. Chi tiết kỹ thuật của Go Fuzzing
    9. Chính sách bảo mật của Go
    10. Threat Model của Go
    11. Các quyết định về bảo mật của Go
    12. Tuân thủ FIPS 140-3
  9. Công cụ và toolchain
    1. Tài liệu về các lệnh
    2. Về lệnh go
    3. Go Toolchains
    4. Telemetry của Go
    5. Cài đặt Go từ mã nguồn
    6. Cài đặt và sử dụng gccgo
  10. Tham khảo
    1. Câu hỏi thường gặp (FAQ)
    2. Go 1 và tương lai của các chương trình Go
    3. Hướng dẫn chuyển đổi sang encoding/json/v2
    4. Hướng dẫn đóng góp
    5. Đóng góp cho frontend gccgo
  11. Phụ lục
    1. Bảng thuật ngữ
Hướng dẫn (Tutorials)

Thêm một test

Bản dịch từ go.dev/doc/tutorial/add-a-test

Giờ mã của bạn đã ở trạng thái ổn định (nhân tiện, làm tốt lắm), hãy thêm một test. Kiểm thử mã trong lúc phát triển có thể phơi bày những lỗi lọt vào khi bạn thay đổi mã. Trong chủ đề này, bạn sẽ thêm test cho hàm Hello.

Lưu ý: Chủ đề này là một phần của loạt hướng dẫn nhiều phần, bắt đầu từ Tạo một Go module.

Việc Go hỗ trợ sẵn unit testing giúp bạn kiểm thử dễ dàng ngay trong quá trình làm. Cụ thể, nhờ các quy ước đặt tên, package testing của Go, và lệnh go test, bạn có thể viết và chạy test rất nhanh.

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

    Việc đặt tên tệp kết thúc bằng _test.go cho lệnh go test biết rằng tệp này chứa các hàm test.

  2. Trong greetings_test.go, dán đoạn mã sau vào và lưu tệp lại.

    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:

    • Hiện thực các hàm test trong cùng package với mã mà bạn đang kiểm thử.
    • Tạo hai hàm test để kiểm thử hàm greetings.Hello. Tên hàm test có dạng TestName, trong đó Name nói lên điều gì đó về test cụ thể. Ngoài ra, hàm test nhận một con trỏ tới kiểu testing.T của package testing làm tham số. Bạn dùng các method của tham số này để báo cáo và ghi log từ test của mình.
    • Hiện thực hai test:
      • TestHelloName gọi hàm Hello, truyền vào một giá trị name mà với nó hàm phải trả về được thông điệp hợp lệ. Nếu lời gọi trả về lỗi hoặc một thông điệp ngoài mong đợi (thông điệp không chứa tên bạn đã truyền vào), bạn dùng method 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. Test này được thiết kế để xác nhận phần xử lý lỗi của bạn hoạt động đúng. Nếu lời gọi trả về chuỗi khác rỗng hoặc không có lỗi, bạn dùng method 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 test.

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

    Các test sẽ pass.

    $ 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. Cố tình làm hỏng hàm greetings.Hello để xem một test thất bại.

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

    Trong greetings/greetings.go, dán đoạn mã sau thay cho hàm Hello. Hãy để ý rằng những dòng được đánh dấu đã thay đổi giá trị mà hàm trả về, như thể đối số name đã vô tình bị 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 test.

    Lần này, hãy chạy go test mà không có cờ -v. Đầu ra sẽ chỉ gồm kết quả của những test thất bại, điều này hữu ích khi bạn có nhiều test. Test TestHelloName sẽ thất bại – còn TestHelloEmpty vẫn pass.

    $ 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

Ở chủ đề tiếp theo (và cũng là cuối cùng), bạn sẽ thấy cách biên dịch và cài đặt mã của mình để chạy nó trên máy cục bộ.

Nội dung gốc: Go Documentation © The Go Authors, giấy phép CC BY 3.0. Bản dịch và ghi chú: Lê Văn Dũng.