Go 支持两种测试策略:黑盒测试与白盒测试。黑盒测试关注点在功能层面,测试代码仅允许访问被测试包的 Exported API ;而白盒测试关注点在实现层面,测试代码需要访问被测试包的所有内容。
Go 规范中约定测试文件与被测试文件在同一目录下,那么如何限制测试代码的访问权限呢?答案是将测试文件申明为不同的包。我们知道 Go 要求同一个目录下所有文件只能隶属于同一个包,但测试文件例外,测试文件的包名可以申明为package xxx_test, 其中 xxx 是被测试文件的包名,这样测试文件就处在单独的包中,以此达到黑盒测试的目的。
因为设置了conf.Trace = true, 我们将看到非常详细的检查结果,这里仅仅截取 main 函数的函数体的检查结果作为演示:
== processDelayed ==
testTypecheckConst:7:23: --- name: func()
testTypecheckConst:8:1: --- <end>
testTypecheckConst:12:13: --- main: func()
testTypecheckConst:13:10: type B
testTypecheckConst:13:10: => B (under = *A) // *types2.Named
testTypecheckConst:15:7: expr b.name()
testTypecheckConst:15:2: . expr b.name
testTypecheckConst:15:1: . . expr b
testTypecheckConst:15:1: . . => b (variable of type B)
testTypecheckConst:15:3: . . ERROR: b.name undefined (type B has no field or method name)
Typecheck Error: testTypecheckConst:15:3: b.name undefined (type B has no field or method name)
testTypecheckConst:15:2: . => b.name (invalid operand)
testTypecheckConst:15:7: => b.name() (invalid operand)
testTypecheckConst:16:1: --- <end>
对于方法调用b.name(), 类型检查器合理地报告了错误。
这样我们就可以任意修改源代码,并通过 UT 的方式查看效果,或者通过调试器查看每个细节是如何工作的了。