我在src/下的子目录下有多个包,用go test
对每个包运行测试都很好。
当尝试使用go test ./...
运行所有测试时,测试正在运行,但失败。
测试是针对本地数据库服务器运行的,每个测试文件都具有带DB指针的全局变量。
我尝试使用-parallel 1
运行测试以防止数据库中的争用,但测试仍然失败。
这里的问题是什么?
编辑:一些测试在丢失数据库条目时失败,我在每次测试之前和之后完全清除数据库。我能想到的唯一原因是测试之间的一些争用。
编辑2:
我的每个测试文件都有2个全局变量(使用mgo):
var session *mgo.Session
var db *mgo.Database
它还具有以下设置和拆卸功能:
func setUp() {
s, err := cfg.GetDBSession()
if err != nil {
panic(err)
}
session = s
db = cfg.GetDB(session)
db.DropDatabase()
}
func tearDown() {
db.DropDatabase()
session.Close()
}
每个测试使用setUp()
和defer tearDown()
启动
cfg也是:
package cfg
import (
"labix.org/v2/mgo"
)
func GetDBSession() (*mgo.Session, error) {
session, err := mgo.Dial("localhost")
return session, err
}
func GetDB(session *mgo.Session) *mgo.Database {
return session.DB("test_db")
}
编辑3:
我更改了cfg以使用随机数据库,测试通过。似乎来自多个包的测试在某种程度上并行运行。
是否可以强制go test
在包中顺序运行所有内容?
5条答案
按热度按时间lp0sw83n1#
更新:正如@Gal Ben-Haim所指出的,添加
go test -p 1
标志(未记录)可以串行地构建和测试所有的包,正如Go语言源代码中的testflag用法消息所指出的:-p=n:并行构建和测试多达n个包
旧答案:
当运行
go test ./...
时,不同包的测试实际上是并行运行的,即使您设置了parallel=1
(只有特定包中的测试才保证一次运行一个)。如果按顺序测试包很重要,比如涉及数据库设置/拆卸时,看起来现在唯一的方法是使用shell来模拟go test ./...
的行为,并强制一个接一个地测试包。例如,在Bash中可以这样做:
该命令首先列出包含
*.go
文件的所有子目录。然后使用sort -u
仅列出每个子目录一次(删除重复项)。最后通过xargs
将包含go文件的所有子目录提供给go test
。-P1
表示一次最多运行一个命令。不幸的是,这比仅仅运行
go test ./...
要难看得多,但如果将其放入shell脚本或别名到更令人难忘的函数中,它可能是可以接受的:现在所有测试都可以在当前目录中运行,方法是调用:
zi8p0yeb2#
显然,运行
go test -p 1
会按顺序运行所有内容(包括构建),但我在go help test
或go help testflag
中没有看到此参数ctrmrzij3#
我假设,因为包单独通过,在这种情况下,您也会在测试之前删除DB。
因此,听起来每个包测试的DB状态都应该是空的。
因此,在每一组包测试之间,DB必须清空。有两种方法可以解决这个问题,不知道你的整个情况,我将简要解释这两种选择:
选项1.测试设置
在每个package _test文件的开头添加一个
init()
函数,然后放置处理以删除DB。这将在实际包的init()
方法之前运行:假设包也有类似的打印行,您将在输出中看到(注意,只有当a测试失败或您提供
-v
选项时,才会显示stdout输出)。选项2.模拟数据库
为数据库创建一个mock(除非你特别要测试的是这个数据库)。对于每个测试的开始状态,mock数据库总是可以表现得像数据库是空白的。
vxf3dgd44#
我使用了一种廉价的方法来选择多个包中的测试。
只要给你的测试命名,让他们被抓住:
func TestUnitCountriesStructs(t *testing.T)
您提到需要对测试进行某种设置和拆卸。我使用testify。简而言之:
daupos2t5#
请尝试以下github仓库。
https://github.com/appleboy/golang-testing
将
coverage.sh
复制到/usr/local/bin/coverage
并更改权限。