










当本地写好了一个go文件之后,希望通过单元测试来验证写的go文件中代码逻辑是否正确,减少后期发现问题成本。本案例介绍如何在VSCODE 工具中触发执行和单点debug执行单元测试函数(注意:VSCODE工具有一个致命不好的点就是慢)
假设:当前业务逻辑go文件为 sqldm.go,且其中有一个 NewDmDataSource 函数,现在需要对该函数进行单元测试。
其中 sqldm.go 代码如下
package sqldb import ( "database/sql" "fmt" _ "dm" "test.com/pkg/middleware/database/dbconfig" "test.com/pkg/tools/logger" ) type DmDataSource struct { dataSource *SqlDataSource } func (dmDataSource *DmDataSource) GenerateDBsn() string { return dmDataSource.generateDBsn(dmDataSource.dataSource.dbconfig) } func (dmDataSource *DmDataSource) generateDBsn(dbconfig *dbconfig.DbConfig) string { return fmt.Sprintf("dm://%s:%s@%s:%d", dbconfig.GetUsername(), dbconfig.GetPwd(), dbconfig.GetHost(), dbconfig.GetPort()) } func NewDmDataSource(dbconfigP *dbconfig.DbConfig) (*DmDataSource, error) { dmDataSource := &DmDataSource{} db, err := sql.Open(dbconfig.DmAliasDbDriver.DriverAlias, dmDataSource.generateDBsn(dbconfigP)) if err != nil { logger.Error("cannot generate datasource for postgres.[host:%s,port:%d,username:%s,dbname:%s,pwd:%s]", dbconfigP.GetHost(), dbconfigP.GetPort(), dbconfigP.GetUsername(), dbconfigP.GetDbname(), dbconfigP.GetPwd(), err) return nil, err } dmDataSource.dataSource = &SqlDataSource{dbconfigP, db} return dmDataSource, nil }
具体需要做如下工作:
1) 在sqldm.go 同级目录下创建 sqldm_test.go文件(单元测试文件必须以_test.go 结尾)
2)在 sqldm_test.go 引入 testing 包
3) 所有测试函数必须以 Test 开头,创建 TestDmConn 函数,参数为 *testing.T 类型
sqldm_test.go 文件内容如下:
package sqldb import ( "testing" "test.com/pkg/middleware/database/dbconfig" ) func TestDmConn(t *testing.T) { _dbconfig, _err := dbconfig.NewDBConfig("10.19.219.160", "SYSDBA", "SYSDBA", "SYSDBA", 5236, dbconfig.Dameng) if _err != nil { t.Fatal("config for dameng is wrong", _err) } _dbconfig.SetPoolMaxIdleConns(0) _dbconfig.SetPoolMaxOpenConns(1) _pg_data_source, err := NewDmDataSource(_dbconfig) if err != nil { t.Fatal("cannot create datasource for dameng", err) } defer _pg_data_source.dataSource.getDb().Close() _err = _pg_data_source.dataSource.db.Ping() if _err != nil { t.Fatal("cannot connect dameng", _err) } t.Logf("get connction for dameng success,%v", _dbconfig) }
在VSCODE 中,可以通过以下方式进行单独运行该函数方法:



直接打开 单元测试文件,每个可执行的 Test 开头的单元测试函数前面会自动出现 绿色图标,见上图,点击 可执行该单元测试函数




效果图上图,如下:




需要先配置 launch.json文件,左侧菜单点击 debug 图标,然后点击顶部的 设置图标,选择添加配置,自动生成右侧的 launch.json文件内容,此时需要将 program 值调整成 main函数所在go文件


当程序执行到断点处,会停止下来,可以点击顶部的调试debug图标,进行相应的操作。



VSCODE终端上执行结果如下:

该问题是由于无法加载需要的DLL导致的。
分析思路:在该工程中有加载 C++ 库 调用其中提供的方法的逻辑,go 编写中 是去加载当前运行程序所在同级目录下的一个子目录(lib)下的dll文件。当正式运行时,通过打包的确是会将这个lib放到运行程序二进制成果物同级下,但是 单元测试则不会。
通过 go test -x -run ^TestGetLastExecution$ ./internal/monitor/ 命令 (-x 表示输出详细信息),不通过 VSCODE 提供的菜单方式执行 单元测试,可以看到如下详细信息:

从中可以看出,go test 实际是编译了整个工程,且生成 test.exe 这个可执行程序,将其放在服务器上的一个临时目录中,在该目录中执行了这个 test.exe 程序,根据上述分析 需要加载 test.exe 所在同级目录中的lib下的dll ,基于此,必须要想办法设置这个dll 路径才能解决。
Win + R,输入 cmd 回车。set PATH=%PATH%;E:\gowork\lib\ go test -v -run ^TestYourFuncName$ ./...
PowerShell 的语法与 CMD 不同,需使用 $env:PATH:
# 临时添加PATH(仅当前会话有效) $env:PATH += ";E:\gowork\lib" # 验证是否添加成功 echo $env:PATH # 运行测试 go test -v -run ^TestYourFuncName$ ./...

从上可以看到 已经可以执行了,不报 0xc0000135 错误了。
# 检查文件是否存在 Test-Path "E:\gowork\src\git\USTA-brs\code\brsweb\identify_lib\win64\yourlib.dll" # 查看DLL依赖项(需安装Visual Studio或dumpbin工具) dumpbin /dependents E:\gowork\src\git\USTA-brs\code\brsweb\identify_lib\win64\yourlib.dll
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。