将测试移至子文件夹并导入main包的Golang实践
将测试移至子文件夹并导入main包的Golang实践 你好。
我在根目录下构建了一个应用程序,其 *.go 文件的包设置为 main。
我还在同一个“根”目录下构建了一些测试文件 *_test.go。
后来,我将所有 *_test.go 文件移到了一个名为 test 的子文件夹中。我将包名改为了 test,但测试代码无法访问根目录(main 包)中的代码。
有没有办法像相对路径“向上跳一级”(../.)那样进行导入?因为我无法让它正常工作。
我花了几个小时创建了一个 go.mod 文件。我是否需要 go.mod 文件以及它所隐含的一切,比如 go mod tidy、带有包名的 requires 等等。
将测试代码与主代码分离的最佳/最简单方法是什么?
我必须说,我觉得模块结构非常令人困惑。
请帮帮我。
更多关于将测试移至子文件夹并导入main包的Golang实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html
一个包的测试文件与该包位于同一文件夹中。这是Go语言中的工作方式。
更多关于将测试移至子文件夹并导入main包的Golang实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的。谢谢。那我就不担心了。
我想正确地处理它,现在我知道正确的方式是什么了 😊
此致
Stuart
除了 @NobbZ 的建议,请注意 main 包不能被其他包导入。
如果你想保持根目录中没有 _test.go 文件,可以考虑将所有包含测试的代码从主包中提取出来,放到一个库包中。
这样,你的 main 包将只包含一些启动代码和粘合代码,这些代码本身也不适合进行单元测试。
感谢您的建议,但我注意到测试文件中的任何声明在所有文件中都变得可见。
例如,一个测试方法调用一个“测试”工具方法,以避免在测试代码中重复编写。
我犯了一个错误,在测试文件中创建了一个 close(t *testing.T, name string) 方法。这导致我在使用 close(c) 关闭通道时出现了错误。当时有点奇怪,因为 VSCode 高亮了错误,但最终还是编译了。
我花了一些时间才解决这个问题,因为代码编译通过了,但运行时却出错了!
我现在已经掌握了它的规律,但我发现这可能会给代码引入错误。有没有更好的方法呢?
将测试文件移动到子目录后,确实无法直接导入 main 包。这是因为 Go 的模块系统不允许从外部导入 main 包。以下是解决方案:
方案一:重构代码结构(推荐)
将可测试的代码从 main 包中分离出来:
// 根目录/main.go
package main
import (
"fmt"
"yourmodule/internal" // 假设模块名为 yourmodule
)
func main() {
result := internal.DoSomething()
fmt.Println(result)
}
// internal/service.go
package internal
func DoSomething() string {
return "Hello from internal package"
}
// test/service_test.go
package test
import (
"testing"
"yourmodule/internal"
)
func TestDoSomething(t *testing.T) {
result := internal.DoSomething()
if result != "Hello from internal package" {
t.Errorf("Expected 'Hello from internal package', got %s", result)
}
}
方案二:使用 go test 的 -coverpkg 参数
保持测试在子目录,但通过构建标签或特定测试命令:
# 从根目录运行测试
go test ./test -coverpkg=./...
方案三:使用 _test 包模式
在 test 目录中,使用 package main_test 并确保有 go.mod 文件:
// test/main_test.go
package main_test
import (
"testing"
_ "yourmodule" // 导入主模块
)
// 测试导出的函数
必需的 go.mod 配置
是的,你需要 go.mod 文件。在根目录创建:
go mod init yourmodule
// go.mod
module yourmodule
go 1.21
对于测试子目录,如果它需要独立的模块(不推荐),可以创建:
cd test
go mod init yourmodule/test
// test/go.mod
module yourmodule/test
go 1.21
replace yourmodule => ../
require yourmodule v0.0.0
最佳实践
最简单的解决方案是:
- 保持测试文件与源代码在同一目录
- 或将可测试代码移到独立的包中
- 使用
internal目录存放不希望外部导入的代码
项目结构:
├── go.mod
├── main.go
├── internal/
│ └── service.go
└── internal/
└── service_test.go # 测试文件与源码同目录
运行测试:
go test ./...
这种结构既保持了代码组织性,又符合 Go 的测试惯例。

