3 回答

TA貢獻1797條經(jīng)驗 獲得超4個贊
如果你想使用標準的 Go 測試工具,你可以定義一個帶有簽名的函數(shù)TestMain(m *testing.M)并將你的夾具代碼放在那里。
從測試包維基:
有時,測試程序需要在測試之前或之后進行額外的設置或拆卸。有時也需要測試來控制哪些代碼在主線程上運行。為了支持這些和其他情況,如果測試文件包含一個函數(shù):
func TestMain(m *testing.M)
那么生成的測試將調(diào)用 TestMain(m) 而不是直接運行測試。TestMain 運行在主 goroutine 中,并且可以圍繞對 m.Run 的調(diào)用進行任何必要的設置和拆卸。然后它應該使用 m.Run 的結果調(diào)用 os.Exit。調(diào)用 TestMain 時,flag.Parse 尚未運行。如果 TestMain 依賴于命令行標志,包括測試包的那些,它應該顯式調(diào)用 flag.Parse。
TestMain 的一個簡單實現(xiàn)是:
func TestMain(m *testing.M) {
flag.Parse()
os.Exit(m.Run())
}

TA貢獻1906條經(jīng)驗 獲得超3個贊
我知道這是一個老問題,但這仍然出現(xiàn)在搜索結果中,所以我想我會給出一個可能的答案。
您可以將代碼隔離到輔助函數(shù)中,這些輔助函數(shù)返回一個“拆卸”函數(shù)以在其自身之后進行清理。這是啟動服務器并在測試用例結束時關閉它的一種可能方法。
func setUpServer() (string, func()) {
h := func(w http.ResponseWriter, r *http.Request) {
code := http.StatusTeapot
http.Error(w, http.StatusText(code), code)
}
ts := httptest.NewServer(http.HandlerFunc(h))
return ts.URL, ts.Close
}
func TestWithServer(t *testing.T) {
u, close := setUpServer()
defer close()
rsp, err := http.Get(u)
assert.Nil(t, err)
assert.Equal(t, http.StatusTeapot, rsp.StatusCode)
}
這將啟動一個服務器net/http/httptest并返回它的 URL 以及一個充當“拆卸”的函數(shù)。這個函數(shù)被添加到 defer 堆棧中,因此無論測試用例如何退出,它總是被調(diào)用。
或者,*testing.T如果您有更復雜的設置并且需要處理錯誤,您可以傳入。此示例顯示設置函數(shù)返回一個*url.URL而不是 URL 格式的字符串,并且解析可能會返回一個錯誤。
func setUpServer(t *testing.T) (*url.URL, func()) {
h := func(w http.ResponseWriter, r *http.Request) {
code := http.StatusTeapot
http.Error(w, http.StatusText(code), code)
}
ts := httptest.NewServer(http.HandlerFunc(h))
u, err := url.Parse(ts.URL)
assert.Nil(t, err)
return u, ts.Close
}
func TestWithServer(t *testing.T) {
u, close := setUpServer(t)
defer close()
u.Path = "/a/b/c/d"
rsp, err := http.Get(u.String())
assert.Nil(t, err)
assert.Equal(t, http.StatusTeapot, rsp.StatusCode)
}

TA貢獻1824條經(jīng)驗 獲得超5個贊
我寫了golang引擎來使用類似于pytest的fixtures:https : //github.com/rekby/fixenv
用法示例:
package example
// db create database abd db struct, cached per package - call
// once and same db shared with all tests
func db(e Env)*DB{...}
// DbCustomer - create customer with random personal data
// but fixed name. Fixture result shared by test and subtests,
// then mean many calls Customer with same name will return same
// customer object.
// Call Customer with other name will create new customer
// and resurn other object.
func DbCustomer(e Env, name string) Customer {
// ... create customer
db(e).CustomerStore(cust)
// ...
return cust
}
// DbAccount create bank account for customer with given name.
func DbAccount(e Env, customerName, accountName string)Account{
cust := DbCustomer(e, customerName)
// ... create account
db(e).AccountStore(acc)
// ...
return acc
}
func TestFirstOwnAccounts(t *testing.T){
e := NewEnv(t)
// background:
// create database
// create customer bob
// create account from
accFrom := DbAccount(e, "bob", "from")
// get existed db, get existed bob, create account to
accTo := DbAccount(e, "bob", "to")
PutMoney(accFrom, 100)
SendMoney(accFrom, accTo, 20)
if accFrom != 80 {
t.Error()
}
if accTo != 20 {
t.Error()
}
// background:
// delete account to
// delete account from
// delete customer bob
}
func TestSecondTransferBetweenCustomers(t *testing.T){
e := NewEnv(t)
// background:
// get db, existed from prev test
// create customer bob
// create account main for bob
accFrom := DbAccount(e, "bob", "main")
// background:
// get existed db
// create customer alice
// create account main for alice
accTo := DbAccount(e, "alice", "main")
PutMoney(accFrom, 100)
SendMoney(accFrom, accTo, 20)
if accFrom != 80 {
t.Error()
}
if accTo != 20 {
t.Error()
}
// background:
// remove account of alice
// remove customer alice
// remove account of bob
// remove customer bob
}
// background:
// after all test finished drop database
- 3 回答
- 0 關注
- 188 瀏覽
添加回答
舉報