golang-testing-part-3-test-suite preview

Go Testing Part 3 - จัดระเบียบ Test Case ด้วย testify/suite

Project ขนาดใหญ่มักจะมีจำนวน domain ที่เยอะตาม การเขียน unit test ให้ครอบคลุมการทำงานของแต่ละ domain จึงต้องมีการจัดการ test case ที่ดี

วันนี้มารู้จัก testify/suite เป็นเครื่องมือที่ช่วยจัดแบ่งหมวดหมู่ของ test case ตามแต่ละ domain หรือ component ให้เป็นระเบียบ สามารถจัดการ lifecycle ของ test case ให้สะดวกและง่ายดายยิ่งขึ้นครับ

ติดตั้ง

go get github.com/stretchr/testify

การใช้งาน

เริ่มจากการสร้าง test suite ขึ้นมาก่อนครับ โดยใน test suite จะเป็นโครงสร้างข้อมูลที่เราจะใช้สำหรับเก็บ components ที่จำเป็นสำหรับการทดสอบ เช่น mocked services, database connection หรือ http client ที่จำเป็นในการทดสอบครับ

package main

import (
  "testing"

  "github.com/stretchr/testify/suite"
)

type MySuite struct {
  suite.Suite
  // สามารถเพิ่ม components ที่จำเป็นสำหรับการทดสอบได้ตรงนี้
}

func TestMySuite(t *testing.T) {
  suite.Run(t, new(MySuite))
}

โดยการฝัง suite.Suite เข้าไปใน struct MySuite จะทำให้ MySuite สามารถเรียกใช้ method ของ testify/suite ได้ครับ

เราสามารถเพิ่ม test case ลงไปใน MySuite ได้ดังนี้

import (
  "github.com/stretchr/testify/assert"
  "github.com/stretchr/testify/suite"
)

func (s *MySuite) TestSomething() {
  result := user.DoSomething()
  assert.Equal(s.T(), "something", result)
}

Lifecycle

เราสามารถใช้ method ของ testify/suite ในการจัดการ lifecycle ของ test case ได้

โดยทั่วไปแล้วเราจะใช้สำหรับ setup และ teardown state ของแต่ละ test case เพื่อไม่ให้มีผลกระทบกันระหว่างแต่ละ test case ครับ เช่น test ที่ 1 ได้ทำการ mock http response ไว้ state ของการ mock จะต้องถูกเคลียร์ก่อนที่ test ถัดไปจะถูกรัน เพื่อให้การทำงานของ test case ถัดไปทำงานไดถูกต้อง

มาดูตัวอย่างการเขียน lifecycle กันครับ

func (s *MySuite) SetupSuite() {
  // Setup before all tests
}

func (s *MySuite) TearDownSuite() {
  // Tear down after all tests
}

func (s *MySuite) SetupTest() {
  // Setup before each test
}

func (s *MySuite) TearDownTest() {
  // Tear down after each test
}

ตัวอย่าง

เรามาลองสร้าง test suite สำหรับการบวกเลขกันดูครับ

package main

import (
  "testing"

  "github.com/stretchr/testify/assert"
  "github.com/stretchr/testify/suite"
)

type CalculatorSuite struct {
  suite.Suite
  calculator *Calculator
}

func (s *CalculatorSuite) SetupTest() {
  // สร้าง instance ของ Calculator ขึ้นมาใหม่ทุกครั้งก่อนที่จะเริ่มทดสอบ
  // เพื่อ ให้ test case แต่ละตัวไม่มีผลกระทบกัน
  s.calculator = NewCalculator()
}

func (s *CalculatorSuite) TestAdd() {
  // method ที่ขึ้นต้นด้วยคำว่า Test จะถูกเรียกใช้เป็น test case
  assert.Equal(s.T(), 3, s.calculator.Add(1, 2))
}

func (s *CalculatorSuite) TestSubtract() {
  assert.Equal(s.T(), 1, s.calculator.Subtract(3, 2))
}

func TestCalculatorSuite(t *testing.T) {
  suite.Run(t, new(CalculatorSuite))
}

เสร็จแล้วววว ไม่ยากใช่มั้ย? เพียงเท่านี้ unit test ของเราก็จะเป็นระเบียบ มัดรวมกันเป็นก้อนๆ เพื่อให้การทดสอบระบบที่มีความซับซ้อนเป็นไปอย่างง่ายดายและสะดวกยิ่งขึ้น

สรุป

Happy coding!

← เชื่อมต่อ Golang กับ OracleDB บน Apple Silicon (m1, m2) ใช้ Honojs กับ Cloudflare Pages Functions →