当我运行go test
时,我的输出:
--- FAIL: TestGETSearchSuccess (0.00s)
Location: drivers_api_test.go:283
Error: Not equal: 200 (expected)
!= 204 (actual)
--- FAIL: TestGETCOSearchSuccess (0.00s)
Location: drivers_api_test.go:391
Error: Not equal: 200 (expected)
!= 204 (actual)
但是在我再次运行go test
之后,我的所有测试都通过了。
仅当我重置mysql数据库时测试失败,然后第一次运行go test
。
对于每个GET
请求,我之前都会执行POST
请求,以确保在数据库中创建了数据。
有人可以帮我确定如何按顺序运行测试吗?那就是POST
请求在GET
请求之前运行?
答案 0 :(得分:23)
您不能/不应该依赖测试执行顺序。未定义执行测试的顺序,并且使用testing flags可以将测试排除在运行之外,因此您无法保证它们将完全运行。
例如,以下命令仅运行名称包含'W'
字母的测试:
go test -run W
另请注意,如果某些测试函数使用T.Parallel()
方法标记自己有资格并行执行,则go工具会将测试重新排序为首次运行非并行测试,然后在某些情况下并行运行并行测试(由-p
等测试标志控制。您可以在此答案中查看此示例:Are tests executed in parallel in Go or one by one?
测试应该彼此独立。如果测试函数具有先决条件,则无法在另一个测试函数中完成/实现。
在运行测试功能之前执行其他任务的选项:
init()
文件本身的包_test.go
函数中。这将在执行测试功能之前运行一次。TestMain()
函数,该函数将首先被调用,您可以在调用M.Run()
之前进行其他设置以触发测试函数的执行。在包init()
或TestMain()
的情况下,您应检查您的数据库是否已初始化(是否已插入测试记录),如果没有,请插入测试记录。
请注意,从Go 1.7开始,您可以使用子测试来定义子测试的执行顺序。有关详细信息,请参阅博文:Using Subtests and Sub-benchmarks以及testing
包的包文档。
答案 1 :(得分:9)
对于像Convey和Ginkgo这样的第三方库,使用普通的Golang 1.7,您可以按顺序运行测试。您可以阅读更多here
func TestFoo(t *testing.T) {
// <setup code>
t.Run("A=1", func(t *testing.T) { ... })
t.Run("A=2", func(t *testing.T) { ... })
t.Run("B=1", func(t *testing.T) { ... })
// <tear-down code>
}
你可以通过以下方式有条件地运行它们:
go test -run '' # Run all tests.
go test -run Foo # Run top-level tests matching "Foo", such as "TestFooBar".
go test -run Foo/A= # For top-level tests matching "Foo", run subtests matching "A=".
go test -run /A=1 # For all top-level tests, run subtests matching "A=1".
因此,假设您从要测试的REST API中获得了user
个包。您需要测试创建处理程序才能测试登录处理程序。通常我会在user_test.go
type UserTests struct { Test *testing.T}
func TestRunner(t *testing.T) {
t.Run("A=create", func(t *testing.T) {
test:= UserTests{Test: t}
test.TestCreateRegularUser()
test.TestCreateConfirmedUser()
test.TestCreateMasterUser()
test.TestCreateUserTwice()
})
t.Run("A=login", func(t *testing.T) {
test:= UserTests{Test: t}
test.TestLoginRegularUser()
test.TestLoginConfirmedUser()
test.TestLoginMasterUser()
})
}
然后我可以将方法附加到任何go test
文件中_test.go
命令不会执行的UserTest类型
func (t *UserTests) TestCreateRegularUser() {
registerRegularUser := util.TableTest{
Method: "POST",
Path: "/iot/users",
Status: http.StatusOK,
Name: "registerRegularUser",
Description: "register Regular User has to return 200",
Body: SerializeUser(RegularUser),
}
response := util.SpinSingleTableTests(t.Test, registerRegularUser)
util.LogIfVerbose(color.BgCyan, "IOT/USERS/TEST", response)
}
答案 2 :(得分:4)
答案 3 :(得分:2)
实现这一目标的最佳方法是创建TestMain
,如呈现here。
import (
"testing"
"os"
)
func TestMain(m *testing.M) {
// Do your stuff here
os.Exit(m.Run())
}