Skip to content

Testing

แพ็กเกจ coretest ประกอบ fixture ที่เทสของ service ต้องใช้ — App, IContext ที่ต่อ database จริง, HTTP client ที่เข้าใจรูปแบบ error ของ framework และตัวรัน job

มีไว้เพื่อไม่ให้ทุก service ต้องเขียน wiring ซ้ำกันคนละ 40 บรรทัด

go
import "gitlab.finema.co/finema/idin-core/v2/coretest"

import จากไฟล์ _test.go เท่านั้น (มันขึ้นกับ testing) และทุก helper รับ *testing.T เพื่อให้ failure ชี้กลับมาที่บรรทัดของผู้เรียก ไม่ใช่ในตัว helper

เริ่มเร็วที่สุด

go
func TestCreateUser(t *testing.T) {
    ctx := coretest.NewContext(t, coretest.WithAutoMigrate(&models.User{}))

    user, err := services.NewUserService(ctx).Create(payload)

    coretest.RequireNoError(t, err)
    assert.Equal(t, "[email protected]", user.Email)
}

NewContext คืน core.IContext ที่ผูกกับ database แยกของเทสนั้น service รับ IContext อยู่แล้ว จึงเทสได้ตรงๆ ไม่ต้องมี interface พิเศษ ไม่ต้อง mock

นี่คือผลจากการที่ทุกอย่างใน framework รับ IContext ตัวเดียวกัน — โค้ดที่รันใน handler, ใน job และในเทส เป็นโค้ดชุดเดียวกันจริงๆ ไม่มีทางแยกสำหรับเทส

หน้าต่างๆ ในหมวดนี้

เขียนเทสแต่ละแบบ

หน้าเนื้อหา
Unit testsตรรกะล้วน ไม่แตะ database — table-driven, เทสที่ผ่านโดยไม่พิสูจน์อะไร
Integration testsservice / repository บน database จริง — soft delete, pagination, transaction
End-to-end testsServe กับ NewClientFromEnv — socket จริงและ process จริง
Mocks และของปลอมปลอมอะไรควร ปลอมอะไรไม่ควร และปลอมอย่างไร

อ้างอิง API

หน้าเนื้อหา
FixturesNewContext / NewApp / NewDB, options ทั้งหมด, การแยกเทส
Database backendssqlite กับ postgres, migration จริง, กลไก schema ชั่วคราว
HTTPNewServer, ยิง request, ตรวจ error body และ field sources
JobsNewJob, params, retry, การตรวจ job ที่ fail
Assertionsassert กับ core.IError และ validation error

รันยังไง

sh
go test ./...                                    # sqlite in memory
TEST_DATABASE_URL=postgres://... go test ./...   # postgres ของจริง
E2E_BASE_URL=http://localhost:3000 go test ./... # เพิ่ม e2e เข้าไปด้วย

ตัวแปรทั้งสองอ่านจาก process environment ตรงๆ ผ่าน os.Getenv — ไม่ผ่าน .env และไม่มี prefix APP_ ใส่ใน .env แล้วจะไม่มี error ไม่มีคำเตือน เทสจะรันแบบเดิมเงียบๆ (ดู Database backends)

หลักการที่ใช้ออกแบบ

ไม่ mock database — mock repository จะเทสแค่ว่า "เราเรียก method ถูกไหม" แต่สิ่งที่ พังจริงคือ SQL: soft-delete filter, ORDER BY ที่ซ้ำ, transaction ที่ไม่ rollback, unique index ที่ขัดกับ validation พวกนี้ mock จับไม่ได้เลยสักอย่าง

assert จาก wire shape — helper ทุกตัวที่อ่าน error จะ marshal เป็น JSON ก่อน แล้ว ค่อยอ่านกลับ สิ่งที่เทสยืนยันจึงเป็นสิ่งที่ client ได้รับจริง ไม่ใช่ field ภายใน ถ้า response shape เปลี่ยน เทสจะพัง — ซึ่งถูกแล้ว เพราะนั่นคือ breaking change

แต่ละเทสมี database ของตัวเอง ไม่ต้องมี teardown ไม่ต้องกลัวลำดับการรัน และ รันขนานกันได้ (รายละเอียด)

config มาจาก environment ล้วนๆ fixture ชี้ NewEnvPath ไปโฟลเดอร์ว่าง ไฟล์ .env หรือ test.env ในเครื่องใครจึงไม่มีผลต่อผลเทส

ไม่มี Sentry ถ้าไม่ได้ตั้ง DSN tracker เป็น no-op เทสไม่ยิงออกเน็ต

Maintained by Passakon Puttasuwan & Dev Core Team.