-
发生时间:2024-01-25
-
问题描述:
- push 服务端代码到 gitlab 远端,跑测试用例时报错:
2024/01/25 11:44:51 /maker/model/mysqldb/mysqldb_init.go:46 [error] failed to initialize database, got error dial tcp 192.168.144.3:0: connect: connection refused -
问题类别:软件测试
-
原因分析:
- 从报错信息来看,在跑 testresult 模块的测试用例时,无法连接到 MySQL 数据库,导致以上报错。
- 首先检查测试环境的 MySQL 数据库是否正常运行:在服务器上执行
docker ps,看到对应的 MySQL 容器是正常运行的。 - 然后怀疑是环境变量导错了,经过多次确认,容器内
/maker目录下使用的.env文件没有问题。 - 后来怀疑是
LoadEnv和BindEnv的调用顺序有误,但交换顺序后问题仍然存在,说明与此无关。 - 同时我观察到只有 testresult 模块有这个问题,mysqldb 模块的测试用例能够正常运行,只是 testresult 模块导入环境变量有问题。
- 添加调试打印,发现 testresult 模块的环境变量是空的,而 mysqldb 模块的环境变量是正确的,说明 testresult 模块导入环境变量失败;
- testresult 和 mysqldb 模块都是调用
LoadEnv函数来导入环境变量,为什么前者失败而后者成功呢? - 仔细阅读
LoadEnv函数的代码(如下所示),终于找到原因:LoadEnv在查找.env文件时,最多只搜索2层目录;而 testresult 模块与.env文件相差3层目录,导致搜索失败。 - 而由于我在测试用例中没检查
LoadEnv的返回值,导致没能发现这个异常。
// LoadEnv loads the environment variables from .env file. func LoadEnv() error { envPath, err := myfilepath.FindFileUpward(".env", 3) // ... } -
解决方案:
- 给
LoadEnv函数增加一个输入参数level,以控制搜索目录级数;testresult 模块的测试用例在调用LoadEnv时,将 level 设置为 5.
- 给
-
实施结果:测试用例运行成功,maker gitlab CI pass。
-
经验总结:
- 如果函数的实现逻辑需要用到变量,尽量将其设计为输入参数,而不应该在函数内部写死。尤其要避免在函数调用链的中间写死参数,这种隐晦的操作会给问题定位带来极大的麻烦。