登录golang测试是否可以?或者是没有登录测试的做法?
我的测试目前看起来像这样。我不确定我是否做得对,需要建议在golang进行测试的最佳实践。这是一个集成测试btw。
日志问题主要在初始化步骤TestMain,其中输入是* testing.M,没有日志功能。
var testDB *DB
func clearTable(name string) {
var err error
_, err = testDB.Exec(fmt.Sprintf("DELETE FROM %s", name))
if err != nil {
log.Fatalf("[FATA] Failed to clear a table in database. name=%q err=%q", name, err)
}
_, err = testDB.Exec(fmt.Sprintf("ALTER SEQUENCE %s_id_seq RESTART WITH 1", name))
if err != nil {
log.Fatalf("[FATA] Failed to reset ID sequence of a table in database. name=%q err=%q", name, err)
}
}
func TestMain(m *testing.M) {
var err error
testDB, err = NewDB(fmt.Sprintf("dbname=%s sslmode=disable", testDBName))
if err != nil {
log.Fatalf("[FATA] Failed to initialize test database. dbName=%q err=%q", testDBName, err)
}
defer testDB.Close()
code := m.Run()
clearTable("worker")
os.Exit(code)
}
func TestCreateWorker(t *testing.T) {
clearTable("worker")
createdWorkers := make(map[int]*Worker, 10)
for i := 0; i < 10; i++ {
username := strings.Join([]string{"worker", strconv.Itoa(i)}, "")
email := strings.Join([]string{username, "@gmail.com"}, "")
passwordHash := strings.Join([]string{username, "PasswordHash"}, "")
worker := Worker {
Username: username,
Email: email,
PasswordHash: passwordHash,
}
err := testDB.CreateWorker(&worker)
if err != nil {
t.Errorf("[ERRO] Failed to create a new worker in database. username=%q email=%q passwordHash=%q err=%q", username, email, passwordHash, err)
}
createdWorkers[i+1] = &worker
}
rows, err := testDB.Query("SELECT * FROM worker")
if err != nil {
t.Errorf("[ERRO] Failed to get all workers from database. err=%q", err)
}
defer rows.Close()
for rows.Next() {
returnedWorker := new(Worker)
err := rows.Scan(&returnedWorker.ID, &returnedWorker.Username, &returnedWorker.Email, &returnedWorker.PasswordHash, &returnedWorker.CreatedAt)
if err != nil {
t.Errorf("[ERRO] Failed to scan returned row into worker struct. err=%q", err)
}
createdWorker := createdWorkers[returnedWorker.ID]
if !reflect.DeepEqual(&createdWorker, &returnedWorker) {
t.Errorf("[ERRO] Worker created in database and worker returned from database are different. createdWorker=%v returnedWorker=%v", createdWorker, returnedWorker)
}
}
}
任何好的Golang github仓库能做好记录来学习吗?
答案 0 :(得分:2)
登录测试完全没问题;这就是为什么* testing.T有Log和Logf方法的原因。
您应该将测试结构传递给辅助函数并让测试失败,而不是调用log.Fatalf:
func clearTable(t *testing.T, name string) {
t.Helper() // optional; identifies our caller as the culprit if test fails
_, err := testDB.Exec(fmt.Sprintf("DELETE FROM %s", name))
if err != nil {
t.Fatalf("[FATA] Failed to clear a table in database. name=%q err=%q", name, err)
}
_, err = testDB.Exec(fmt.Sprintf("ALTER SEQUENCE %s_id_seq RESTART WITH 1", name))
if err != nil {
t.Fatalf("[FATA] Failed to reset ID sequence of a table in database. name=%q err=%q", name, err)
}
}
正如您在评论中已经提到的,这不适用于TestMain函数。
您应该避免定义TestMain,这很少是必要的。相反,在每个测试中调用setup和teardown函数。这使得测试自成一体,并且更容易理解正在发生的事情。
func TestCreateWorker(t *testing.T) {
clearTable(t, "worker")
defer clearTable(t, "worker")
// test follows
}
除此之外:想想你是否想在每次测试后调用clearTable都很长。第一次调用是多余的,会破坏测试失败的所有证据,并使调试更加困难。
如果你想保持你的TestMain,定义一个不依赖于测试的不同辅助函数.T。