当测试依赖于全局变量和本地数据库服务器时,使用 go test 对子目录下的多个包运行测试可能会具有挑战性。当 go test ./... 运行测试时,由于数据库中潜在的争用而失败。
理解问题
问题的出现是因为 go test 。 /... 并行执行不同包的测试。当每个测试文件包含带有数据库指针的全局变量并且测试依赖于数据库操作时,这种并行性可能会导致由于数据争用而导致测试失败。
潜在修复
1.串行运行测试
要强制跨包进行顺序测试,请考虑在运行 go test 时使用未记录的标志 -p 1。此标志强制所有包按顺序构建和测试。
<code class="bash">go test -p 1 ./...</code>
2.使用 Shell 脚本
如果 -p 1 不合适,请考虑使用模拟 go test ./... 行为但强制顺序测试的 shell 脚本。这可以通过列出带有 *.go 文件的子目录、删除重复项并对每个子目录逐一执行 go 测试来实现。
<code class="bash">find . -name '*.go' -printf '%h\n' | sort -u | xargs -n1 -P1 go test</code>
3.数据库感知测试
另一种方法是修改测试代码以提高并发感知能力。这可能涉及使用包级数据库并将数据库初始化和拆卸分别推迟到每个测试的开始和结束。确保数据库操作同步并且每个测试都有自己的一组数据库资源至关重要。
示例:
下面是如何确保数据库的示例每个测试中的隔离:
<code class="go">import ( "database/sql" "testing" ) type DBWrapper struct { *sql.DB } func (db DBWrapper) TearDown(t *testing.T) { if err := db.Close(); err != nil { t.Errorf("Failed to close database: %v", err) } } func TestDatabase(t *testing.T) { defer DBWrapper{sql.Open(...)}.TearDown(t) // Conduct test operations using the isolated DBWrapper }</code>
通过使用这些技术,可以对涉及数据库操作的多个包运行测试,而不会遇到与争用相关的故障。
以上是如何在 Go 中跨多个包运行并发测试而不发生数据库争用?的详细内容。更多信息请关注PHP中文网其他相关文章!