Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 用于测试阻塞调用的有用助手相关的知识,希望对你有一定的参考价值。
// WithTimeout runs a function and fails if it didn't finish within the timeout
func (s *Suite) WithTimeout(timeout time.Duration, fn func()) {
ch := make(chan struct{})
go func() {
fn()
ch <- struct{}{}
}()
select {
case <-time.After(timeout):
s.Fail("The test stuck for more than expected timeout")
case <-ch:
return
}
}
Golang 测试中的夹具
【中文标题】Golang 测试中的夹具【英文标题】:Fixtures in Golang testing 【发布时间】:2016-04-25 16:33:05 【问题描述】:来自 python 世界,fixtures 非常有用(Fixtures 定义了一个 Python 合约用于可重用的状态/支持逻辑,主要用于单元测试)。我想知道 Golang 中是否有类似的支持,它可以让我使用一些预定义的装置来运行我的测试,比如设置服务器、拆除它、每次运行测试时执行一些重复的任务?有人可以指出一些在 Golang 中做同样事情的例子吗?
【问题讨论】:
BeforeEachAfterEach
【参考方案1】:
TestMain(m *testing.M)
来自testing package wiki:
func TestMain(m *testing.M)
flag.Parse()
os.Exit(m.Run())
【讨论】:
flag.Parse()TestMain
【参考方案2】:
我知道这是一个老问题,但它仍然出现在搜索结果中,所以我想我会给出一个可能的答案。
您可以将代码隔离到返回“teardown”函数以自行清理的辅助函数。这是启动服务器并在测试用例结束时关闭它的一种可能方法。
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
*testing.T*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)
【讨论】:
不错!我认为这与您使用的 pytest 固定装置差不多。【参考方案3】:我为使用类似于 pytest 的夹具编写了 golang 引擎: 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
【讨论】:
以上是关于golang 用于测试阻塞调用的有用助手的主要内容,如果未能解决你的问题,请参考以下文章