我正在使用go“testing”包。像下面那样运行我的测试。
func TestMain(m *testing.M) {
...
// Setup
os.Exit(m.Run())
// Teardown
}
这将在运行任何测试之前运行设置,并在所有测试完成后进行拆卸。我确实需要这个,因为设置设置了DB。但是,我还需要找到一种方法来运行每次测试设置/拆卸。对于我正在运行的单元测试,我想在每次测试之前清除数据库,这样就不会出现导致意外行为的数据库内容问题。
答案 0 :(得分:17)
如文章" Go unit test setup and teardown"从Kare Nuorteva开始,你可以使用一个设置函数,它会让你推迟一个拆解功能。
请参阅this gist:
func setupSubTest(t *testing.T) func(t *testing.T) {
t.Log("setup sub test")
return func(t *testing.T) {
t.Log("teardown sub test")
}
}
设置功能负责定义和返回拆卸功能。
对于每个测试,例如在表驱动的测试场景中:
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
teardownSubTest := setupSubTest(t)
defer teardownSubTest(t)
result := Sum(tc.a, tc.b)
if result != tc.expected {
t.Fatalf("expected sum %v, but got %v", tc.expected, result)
}
})
}
答案 1 :(得分:1)
如果表驱动测试模式适合您,则应坚持使用它。如果您需要更通用,更灵活的工具,请随时尝试https://github.com/houqp/gtest。
这是一个简单的例子:
import (
"strings"
"testing"
"github.com/houqp/gtest"
)
type SampleTests struct{}
// Setup and Teardown are invoked per test group run
func (s *SampleTests) Setup(t *testing.T) {}
func (s *SampleTests) Teardown(t *testing.T) {}
// BeforeEach and AfterEach are invoked per test run
func (s *SampleTests) BeforeEach(t *testing.T) {}
func (s *SampleTests) AfterEach(t *testing.T) {}
func (s *SampleTests) SubTestCompare(t *testing.T) {
if 1 != 1 {
t.FailNow()
}
}
func (s *SampleTests) SubTestCheckPrefix(t *testing.T) {
if !strings.HasPrefix("abc", "ab") {
t.FailNow()
}
}
func TestSampleTests(t *testing.T) {
gtest.RunSubTests(t, &SampleTests{})
}
答案 2 :(得分:0)
您可以考虑使用函数表subTestSetup,subTest和subTestTeardown传递结构中的db连接/其他公共项(subTestSetup可以返回此结构)。你可以重用一些/部分设置和放大器。同时拆除不同的功能&随着测试要求的增长,保持这种模块化。在调用subTest之前调用deTallTestTeardown(),以确保即使subTest存在任何问题也可以执行拆除代码。
答案 3 :(得分:0)
⚠️注意:这不是经过全面测试的解决方案;在临时测试场景中似乎效果很好。
在一个简单的情况下,我使用了自己的t.Run()
实现,该实现在完成子测试后进行清理:
func Run(t *testing.T, name string, f func(*testing.T)) bool {
result := t.Run(name, f)
// Do the cleanup.
return result
}
在我的测试中:
func TestSomethingWorks(t *testing.T) {
Run(t, "scenario 1", func(t *testing.T) {
// ...
})
Run(t, "scenario 2", func(t *testing.T) {
// ...
})
}