我想测试主包中包含的几个函数,但我的测试似乎无法访问这些函数。
我的main.go示例文件如下所示:
package main
import (
"log"
)
func main() {
log.Printf(foo())
}
func foo() string {
return "Foo"
}
我的main_test.go文件看起来像这样:
package main
import (
"testing"
)
func Foo(t testing.T) {
t.Error(foo())
}
当我运行go test main_test.go
时我得到
# command-line-arguments
.\main_test.go:8: undefined: foo
FAIL command-line-arguments [build failed]
据我所知,即使我将测试文件移到其他地方并尝试从main.go文件导入,我也无法导入它,因为它是package main
。
构建这样的测试的正确方法是什么?我应该从main
包中删除所有的东西,只留下一个简单的main函数来运行所有的东西,然后在它们自己的包中测试这些函数,还是有一种方法可以让我在测试过程中从main文件中调用这些函数?
6条答案
按热度按时间zzwlnbp81#
在命令行上指定文件时,必须指定所有文件
以下是我的跑步记录:
注意,在我的版本中,我在命令行上运行了main.go和main_test.go
另外,your _test文件不太正确,您需要将test函数命名为TestXXX,并获取指向testing.T的指针
以下是修改后的版本:
以及修改后的输出:
8tntrjer2#
单元测试也就到此为止了。在某个时候你必须实际运行程序。然后你测试它是否能用真实的输入,从真实的源,产生真实的输出到真实的目的地。真的。
如果你想对一个东西进行单元测试,请把它移出main()。
xytpbqjk3#
这不是OP问题的直接答案,我大体上同意之前的答案和评论,即
main
应该主要是打包函数的调用者。也就是说,我发现这里有一个测试可执行文件的有用方法。它使用log.Fataln
和exec.Command
。1.使用延迟函数编写
main.go
,该函数调用log.fatalln(),以便在返回之前将消息写入stderr。1.在
main_test.go
中,使用exec.Command(...)
和cmd.CombinedOutput()
运行程序,并选择参数来测试某些预期结果。例如:
在
main_test.go
中,针对(比如)会导致somefunc
失败的错误参数的测试可能如下所示:注意
err
fromCombinedOutput()
是log.Fatalln对os.Exit(1)
的底层调用中的非零退出代码,这就是为什么我们需要使用out
从somefunc
中提取错误消息。exec
包还提供了cmd.Run
和cmd.Output
。对于某些测试,这些可能比cmd.CombinedOutput
更合适。我还发现有一个TestMain(m *testing.M)
函数在运行测试之前和之后进行设置和清理是很有用的。o8x7eapl4#
如何使用标志测试
main
并Assert退出代码@MikeElis的答案让我走了一半,但有一个主要部分是围棋自己的flag--test,去帮我弄清楚。
免责声明
你本质上是想运行你的应用程序并测试正确性。所以请随意标记此测试并将其归入该类别。但值得尝试这种类型的测试并看到其好处。特别是如果你正在编写CLI应用程序。
其思想是照常运行
go test
,并且1.使用
go test
生成的应用程序的测试构建版本,在子流程中运行"自身"单元测试(参见第86行)1.我们还将环境变量(参见第88行)传递给子进程,该子进程将执行运行
main
的代码段,并导致测试以main
的退出代码退出:注解:如果主功能未退出,则测试将挂起/循环。
1.然后Assert从子进程返回的退出代码。
注意:在本例中,如果返回的不是预期的退出代码,测试将从子进程输出STDOUT和/或STDERR,以帮助调试。
完整示例见此处:go-gitter:测试CLI
ahy6op9u5#
因为您只为测试设置了一个文件,所以它不会使用其他的go文件。
运行
go test
而不是go test main_test.go
。同时将测试函数签名
Foo(t testing.T)
更改为TestFoo(t *testing.T)
。xtupzzrd6#
在两个源文件中将包名从main改为foobar。将源文件移到src/foobar下。
确保将GOPATH设置为src/foobar所在的文件夹。
测试它