Golang中如何测试多个函数
Golang中如何测试多个函数 我创建了10个测试文件和一个主文件来调用这些文件,但文件没有按预期顺序调用。比如…
- 删除表
- 插入表
- 创建表
它按照上述顺序运行,但这样是不对的。如果按这个顺序运行,会产生表未创建的错误。
如何让它按照3、2、1的顺序运行?
谢谢。
好的。这意味着在插入数据函数中,我需要创建一个表并插入数据。
谢谢。
更多关于Golang中如何测试多个函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的,所以你根本没有使用 main.go,而是运行 go test?不,你无法改变测试运行的顺序。你需要重新设计你的测试。
在一个良好的测试套件中,每个测试都不应依赖于其他测试。
你不能直接调用"文件",只能调用函数和方法。而且它们通常应该按照你指定的顺序运行。
也许你可以展示一些能重现你所观察行为的代码?
// 代码示例
func main() {
fmt.Println("示例代码")
}
你能提供一些重现此行为的代码吗?这样我们就不需要安装和运行IBM-DB了。
乍看之下,main函数似乎是以正确的顺序运行内容的。
另外能否详细说明截图与此问题的关联性?
func main() {
fmt.Println("hello world")
}
您的代码存在一些问题:
- 不要多次使用数据库
open db必须是全局变量- 使用带参数的函数来创建表、插入数据等操作
- 在完全了解如何使用之前不要使用
prepare con看起来更像是常量而非变量- 在每次
exec调用后立即处理错误,而不是在3次调用后才处理
- 缩进代码行以提高可读性
在Go语言中,测试函数的执行顺序默认是按字母顺序或文件系统顺序,而不是按你期望的逻辑顺序。要控制测试的执行顺序,可以使用子测试(subtests)配合TestMain函数来显式定义顺序。以下是解决方案:
1. 使用子测试(Subtest)组织测试顺序
将你的测试函数重构为单个主测试函数内的子测试,并使用t.Run按指定顺序调用它们。
示例代码:
package main
import (
"testing"
)
func TestMain(m *testing.M) {
// 可选:在测试前后执行全局设置或清理
m.Run()
}
func TestAllInOrder(t *testing.T) {
// 按逻辑顺序定义子测试:创建表 -> 插入表 -> 删除表
tests := []struct {
name string
fn func(*testing.T)
}{
{"CreateTable", testCreateTable},
{"InsertTable", testInsertTable},
{"DeleteTable", testDeleteTable},
}
for _, tc := range tests {
t.Run(tc.name, tc.fn)
}
}
func testCreateTable(t *testing.T) {
// 实现创建表的测试逻辑
t.Log("Creating table...")
// 示例:执行创建表操作并验证
}
func testInsertTable(t *testing.T) {
// 实现插入数据的测试逻辑
t.Log("Inserting into table...")
// 示例:依赖表已存在,执行插入操作
}
func testDeleteTable(t *testing.T) {
// 实现删除表的测试逻辑
t.Log("Deleting table...")
// 示例:清理表
}
2. 使用测试标志或依赖管理
如果子测试不适用(例如测试分布在多个文件中),可以通过环境变量或构建标签控制执行,但这需要手动干预。更直接的方法是将所有相关测试合并到一个包中,并使用上述子测试方法。
3. 运行测试命令
执行测试时,Go会按TestAllInOrder内定义的顺序运行子测试:
go test -v
输出将显示子测试按"CreateTable"、“InsertTable”、"DeleteTable"顺序执行。
关键点:
- Go测试框架不保证跨文件的测试顺序,因此将依赖顺序的测试组织在同一个测试函数内。
- 使用
t.Run确保子测试按顺序执行,每个子测试会阻塞直到完成。 - 避免在测试间共享状态(如数据库表),除非使用明确的设置/清理逻辑(如
TestMain)。
如果测试涉及外部资源(如数据库),建议在TestMain中使用全局设置和清理,确保环境一致性。例如:
func TestMain(m *testing.M) {
setup() // 例如创建测试数据库连接
code := m.Run()
teardown() // 清理资源
os.Exit(code)
}
这种方法能解决你的表操作顺序问题,确保"创建表"先于"插入表"执行。
package main
import (
"fmt"
)
func Createconnection()(int){
fmt.Println("this is Createconnection")
return 1
}
func Createtable( ) error{
fmt.Println("this is Createtable")
return nil
}
func Insert() error{
fmt.Println("this is Insert")
return nil
}
func Drop() error{
fmt.Println("this is Drop")
return nil
}
func Prepare() error{
fmt.Println("this is Prepare")
return nil
}
func Query() error{
fmt.Println("this is Query")
return nil
}
func Scan() error{
fmt.Println("this is Scan")
return nil
}
func Next() error{
fmt.Println("this is Next")
return nil
}
func Columns() error{
fmt.Println("this is Columns")
return nil
}
func Queryrow() error{
fmt.Println("this is Queryrow")
return nil
}
func Begin() error{
fmt.Println("this is Begin")
return nil
}
func Commit() error{
fmt.Println("this is Commit")
return nil
}
func Close()(error){
fmt.Println("this is Close")
return nil
}
func PoolOpen() (int){
fmt.Println("this is PoolOpen")
return 1
}
func main(){
result:=Createconnection()
if(result != 1){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result1:=Createtable()
if(result1 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result2:=Insert()
if(result2 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result3:=Drop()
if(result3 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result4:=Prepare()
if(result4 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result5:=Query()
if(result5 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result6:=Scan()
if(result6 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result7:=Next()
if(result7 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result8:=Columns()
if(result8 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result9:=Queryrow()
if(result9 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result10:=Begin()
if(result10== nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result11:=Commit()
if(result11 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result12:=Close()
if(result12 == nil){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
result13:=PoolOpen()
if(result13 ==1){
fmt.Println("Pass")
} else {
fmt.Println("fail")
}
}
输出:

检查主函数中的调用顺序和输出(两者是不同的)。
屏幕截图如何相关?(来自上面的评论)
这些是主文件正在使用的测试文件。

