Golang单元测试:如何指定测试路径或待测包

Golang单元测试:如何指定测试路径或待测包 我正在为我的代码创建一些单元测试,这是我在Go语言中的第一次尝试。

当所有文件都放在同一个目录下时,我已经成功地运行了测试(例如,main.go 包中的函数由 main_test.go 进行测试)。通过运行命令 go test,测试和相关的代码都能成功执行。

然而,在我看来,将测试包/文件与实际项目文件分开存放似乎更为妥当,所以我把 main_test.go 文件移到了一个名为 Unit_tests 的子目录中。现在,我对于如何再次运行这些测试感到困惑。

我尝试过(在命令行界面中)运行:go test /home/user/go_directory/project/main.go

但这只会导致一个错误,提示我不能使用绝对路径。我认为不应该把测试文件放在 $PATH 中,因为这可能会与其他测试/包混淆。

关于单元测试文件的存储位置和方式,普遍接受的做法是什么?我应该把它们存储在哪里?当它们不与我的项目存储在同一个目录时,我该如何执行它们?

我也不太确定,当执行命令 go test xyz.go 时,xyz 是指单元测试本身,还是指被测试的包。网上没有人澄清这一点。

我使用的环境是:VS Code 1.47.3,Ubuntu 18.04(全部是最新版本),Go 版本 go1.15.2 linux/amd64


更多关于Golang单元测试:如何指定测试路径或待测包的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

感谢您的解答,这澄清了一些问题。是的,发帖后我在 Stack Overflow 上找到了一个针对非常相似问题的答案,似乎将测试文件放在待测项目/包的同级目录中是标准做法。再次感谢您的确认。我将遵循 Go 的最佳实践,并采用同样的方式。

更多关于Golang单元测试:如何指定测试路径或待测包的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


然而,对我来说,将测试包/文件与实际项目文件分开似乎更为谨慎

一般来说,我持相同观点,但在 Go 语言中,将 _test.go 文件与被测系统放在同一文件夹内确实是惯用的做法。

所以我把 main_test.go 文件移到了一个名为 Unit_tests 的子目录中

如果 main.gomain_test.go 都属于 package main,那么这样做是行不通的。main 包是不可导入的。

关于单元测试文件的存放位置和方式,普遍接受的做法是什么?

如上所述:与被测系统放在一起。

惯用的做法是,为了更好的可发现性,在名为 $name_test.go 的测试文件中测试 $name.go 中的函数和方法。

当它们不存储在与我的项目相同的目录中时,我如何执行它们?

在这种情况下,你的单元测试必须像其他需要导入的包一样,通过 import 来导入你想要测试的包。

我也不确定,当执行命令 go test xyz.go 时,xyz 指定的是单元测试本身,还是被测试的包。网上没有人澄清这一点。

根据 go help testgo test 不接受文件名,只接受包名。不过,遵循惯用的测试文件同目录存放规则,你需要指定被测试的包,它会搜索同目录下的 *_test.go 文件并运行其中的测试。

如果你确实希望将测试文件放在不同的位置,你仍然可以通过使用 go test ./... 或指定包含测试文件的包来运行它们,go 工具会根据导入关系推断出还需要编译哪些内容。

在Go中,测试文件必须与被测试的包位于同一目录下,这是go test工具的设计要求。将测试文件移到单独的Unit_tests目录会导致测试无法运行,因为Go的测试工具无法跨目录关联测试文件与源文件。

正确做法

测试文件应与被测试的包文件放在同一目录中。例如:

project/
├── main.go
├── main_test.go      # 测试main包
├── utils/
│   ├── helper.go
│   └── helper_test.go # 测试utils包
└── models/
    ├── user.go
    └── user_test.go   # 测试models包

运行测试的几种方式

  1. 运行当前目录所有测试
go test
  1. 运行指定包的测试
go test ./utils
  1. 运行子目录所有测试
go test ./...
  1. 运行特定测试函数
go test -run TestFunctionName
  1. 运行测试并显示详细信息
go test -v

示例代码结构

假设你有以下项目结构:

myproject/
├── go.mod
├── main.go
├── calculator.go
└── calculator_test.go

calculator.go:

package main

func Add(a, b int) int {
    return a + b
}

calculator_test.go:

package main

import "testing"

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5
    if result != expected {
        t.Errorf("Add(2, 3) = %d; want %d", result, expected)
    }
}

运行测试:

# 在myproject目录下
go test
# 或者
go test -v

关于go test xyz.go

go test命令的参数是包路径,而不是文件名。例如:

  • go test . - 测试当前目录的包
  • go test ./utils - 测试utils子目录的包
  • go test github.com/user/project - 测试远程包

你不能使用go test main.go这样的语法,因为Go测试是以包为单位组织的,而不是单个文件。

测试覆盖率

要查看测试覆盖率:

go test -cover
go test -coverprofile=coverage.out
go tool cover -html=coverage.out

测试不同构建标签

如果需要条件编译测试:

// +build integration

package main

import "testing"

func TestIntegration(t *testing.T) {
    // 集成测试代码
}

运行集成测试:

go test -tags=integration

将测试文件移回与被测试包相同的目录,然后使用go test命令运行测试。这是Go社区的标准做法,也是Go工具链的预期工作方式。

回到顶部