Sử dụng Golang để thực hiện automation test - Tại sao không


Xin chào mọi người, mình là Cường, hiện đang làm automation tester tại công ty CMC Global. Trong bài viết này mình muốn chia sẻ với mọi người hành trình mình sử dụng Golang để viết automation test, mà cụ thể hơn là viết automation test cho API.

Trước khi biết đến Golang thì mình cũng đã sử dụng qua một vài ngôn ngữ như Java, Python, hay Node.js. Điểm chung của các ngôn ngữ này mình thấy là dễ học, có cộng đồng lớn, và có nhiều thư viện để hỗ trợ cho việc viết automation testing. Tuy nhiên, có một vấn đề là việc áp dụng chạy test đồng thời (concurrent test) trên những ngôn ngữ và nền tảng trên không được tiện lợi như với Golang. Thường thì bạn sẽ cần phải cài thêm thư viện mới như với Java, hoặc nếu như được hỗ trợ sẵn như trong trường hợp của Python và Node.js thì bạn sẽ phải dùng asynchronous function, cũng khá khó khăn cho người mới bắt đầu.

Với Golang, việc hỗ trợ viết concurrent tests giữa các tests với nhau, hoặc tạo ra nhiều tiến trình chạy đồng thời trong 1 test cũng khá dễ dàng. Dưới đây là một ví dụ tạo ra một concurrent process sử dụng goroutine trong Golang: 

const { Vonage } = require('@vonage/server-sdk')

const vonage = new Vonage({
  apiKey: "724876c4",
  apiSecret: "5AR613NkSBn6TEg2"
})



package test

import (
	"github.com/go-resty/resty/v2"
	"github.com/stretchr/testify/assert"
	"log"
	"net/http"
	"os"
	"testing"
)

func getUser(username string, token string) {

client := resty.New()
	resp, err := client.R().
		Get("https://api.github.com/users/" + username + "/repos")

	if err != nil {

		log.Fatal("Error happens")

	}

	return resp
    
}

func TestExample(t *testing.T ) {

    f("direct")

    go getUser("donald","token")

    getUser("anna","token")


}
Trong ví dụ trên, ở hàm `TestExample` ngoài tiến trình chính được tạo ra lúc chạy test, mình có tạo thêm 1 tiến trình nữa sử dụng câu lệnh `go getUser`. Khi test được thực thi sẽ có 2 API request được chạy đồng thời, 1 API request được gửi đi sử dụng param là "anna", "token. API còn lại sẽ được chạy trong 1 tiến trình mới sử dụng params là "donald", "token". Việc chạy 2 tiến trình đồng thời như vậy sẽ giúp giảm thiểu thời gian chạy test xuống rất nhiều. Thử tưởng tượng bạn có 100 đến vài trăm tests cần chạy, nếu áp dụng chạy tests đồng thời một cách hợp lý, bạn sẽ giảm tải thời gian chạy xuống rất nhiều.

Mặt khác một lý do để bạn có thể sử dụng Go để viết automation test là cộng đồng sử dụng Golang hiện tại cũng khá nhiều, và hầu hết những thư viện bạn cần để tích hợp trong quá trình test đều đã có sẵn. Điều này giúp cho quá trình học Golang và áp dụng Golang vào các dự án thực tế sẽ không gặp quá nhiều khó khăn.

Để giúp bạn hiểu hơn về cách áp dụng Golang vào automation test thì mình cùng tìm hiểu về ví dụ sau nhé. Giả dụ mình sẽ cần phải viết API test cho API của GitHub phục vụ tính năng là lấy ra tất cả thông tin repositories của người dùng hiện tại. Dưới đây là toàn bộ code của testcase.

 package go_example

import (
    "github.com/go-resty/resty/v2"
    "github.com/stretchr/testify/assert"
    "log"
    "net/http"
    "os"
    "testing"
)

func getReposList(token string, username string) *resty.Response {

    client := resty.New()
    resp, err := client.R().
       SetHeader("Accept", "application/json").
       SetHeader("Authorization", "Bearer "+token).
       Get("https://api.github.com/users/" + username + "/repos")

    if err != nil {

       log.Fatal("Error happens")

    }

    return resp
}
func TestIntMinTableDriven(t *testing.T) {

    token := os.Getenv("TOKEN")
    username := os.Getenv("USERNAME")
    response := getReposList(token, username)
    assert.Equal(t, response.StatusCode(), http.StatusOK, "response status code should be 200")
    t.Log(string(response.Body()))

}
- Ở đoạn code phía trên, mình có tạo một function tên là `getReposList` để tạo API request tới API get thông tin repos của user. Mình sử dụng thư viện là `go-resty` để có thể tạo API request.
- Mình sử dụng thư viện test mặc định trong Golang để viết test
- Để kiểm tra `StatusCode` trả về của API có thành công hay không, mình sử dụng thư viện `testify`

Để chạy test được thì bạn cần cung cấp thông tin username và token trước khi chạy test. Bạn có thể tạo token cho tài khoản của bạn trên GitHub qua trang "Developer Settings" ở mục "Profile". Chạy câu lệnh sau để cung cấp thông tin username và token vào biến môi trường (ví dụ cho trường hợp bạn đang sử dụng PowerShell trên Windows):

$env:TOKEN = "your_token"
$env:USERNAME = "your_username"

Sau đó bạn chạy câu lệnh sau để chạy test, chú ý option `-v` mục đích để show ra log ra màn hình console trong quá trình bạn chạy test.
go test github_test.go -v
 Sau khi chạy câu lệnh trên, bạn sẽ nhận được kết quả là test đã chạy thành công với một số thông tin repo của bạn.

ze":4,"stargazers_count":5,"watchers_count":5,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":4,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":1,"license":null,"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"public","forks":4,"open_issues":1,"watchers":5,"default_branch":"master","permissions":{"admin":true,"maintain":true,"push":true,"triage":true,"pull":true}}]
--- PASS: TestIntMinTableDriven (0.92s)
PASS
ok      command-line-arguments  1.020s


Bài viết của mình đến đây là hết.
Hy vọng bạn cảm thấy bài viết này hữu ích và có thể cân nhắc sử dụng Go để viết automation test trong các dự án sắp tới.
~~Happy testing~~
----------------------
Đôi điều về bản thân minh.
Tên đầy đủ của mình là : Lê Đình Cường
Hiện tại mình đang làm automation tester tại công ty CMC Global.
Mình có hơn 10 năm kinh nghiệm làm tester nói chung, và 6 năm kinh nghiệm làm automation test nói riêng.
Một số bài viết của mình có liên quan đến automation testing, các bạn có thể tham khảo tại những đường link phía dưới:
https://earthly.dev/blog/playwright-python-api-testing/
Ngoài ra, mình luôn mong muốn được kết nối với tất cả các bạn có đam mê về lập trình, kiểm thử, hoặc viết blog. Nếu bạn có cùng những sở thích trên thì có thể kết nối với mình tại LinkedIn ở liên kết : https://www.linkedin.com/in/%F0%9F%91%8B%F0%9F%91%8Bcuong-le%F0%9F%92%81%E2%80%8D%E2%99%82%EF%B8%8F%F0%9F%92%81%E2%80%8D%E2%99%82%EF%B8%8F-209003b0/

donald-le.JPEG 178 KB