如何在测试时允许一个包访问另一个包的未导出数据?

时间:2017-03-21 15:08:55

标签: testing go integration-testing

The Go Programming Language ,第11.2.4节中,通过IsSpacefmt的声明访问export_test.go的外部测试示例}的a/a.go文件。这似乎是完美的解决方案,所以这就是我所做的:

package a var x int func Set(v int) { x = v }

a/a_test.go

package a import "testing" func TestSet(t *testing.T) { Set(42) if x != 42 { t.Errorf("x == %d (expected 42)", x) } } func Get() int { return x }

go test

(在a/中运行b/b.go可以正常工作。)

package b import "path/to/a" func CallSet() { a.Set(105) }

b/b_test.go

package b import ( "testing" "path/to/a" ) func TestCallSet(t *testing.T) { CallSet() if r := a.Get(); r != 105 { t.Errorf("Get() == %d (expected 105)", r) } }

go test

不幸的是,当我在b/中运行./b_test.go:11: undefined: a.Get 时,我得到了:

go test ./...

尝试使用a.Get同时运行这两组测试并没有帮助。

经过一番相当大的探索之后,我发现了“The *_test.go files are compiled into the package only when running go test for that package”(强调我的)。 (换句话说,我可以从a_test中的a/外部测试包访问a/,但不能访问echo "<h2>".$pagename."</h2>"; $User_FName = $_POST['U_fname']; $User_SName = $_POST['U_sname']; $User_Address = $_POST['U_address']; $User_Postcode = $_POST['U_postcode']; $User_telNo = $_POST['U_telNo']; $User_Email = $_POST['U_email']; $User_Password = $_POST['U_password']; $User_confirmPassword = $_POST['U_confirmPassword']; $emailCheck="SELECT userEmail FROM Users"; $exeEmailCheck=mysql_query($emailCheck) or die (mysql_error()); $emailArray=mysql_fetch_array($exeEmailCheck); if (!empty($User_FName) AND !empty($User_SName) AND !empty($User_Address) AND !empty($User_Postcode) AND !empty($User_telNo) AND !empty($User_Email) AND !empty($User_Password) AND !empty($User_confirmPassword)) //empty is php function to check variables if empty { if (!($User_Password==$User_confirmPassword)){ echo "<p>Passwords don't match!</p>"; echo "<p>Go back to <a href=register.php>register page</a></p>"; } else{ $reg = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/'; if(preg_match($reg,$User_Email)) { $addUserSQL= "insert into Users (userType,userFName, userSName, userAddress, userPostcode, userTelNo, userEmail, userPassword) values ('C','".$User_FName."', '".$User_SName."','".$User_Address."','".$User_Postcode."', '".$User_telNo."', '".$User_Email."', '".$User_Password."')"; $exeaddUserSQL=mysql_query($addUserSQL); if(mysql_errno($conn) == 0 ){ echo "<p>You've successfully registered"; echo "<p>To continue, please <a href=login.php>login</a></p>"; } else{ echo "<p>You've not successfully registered</p>"; if (mysql_errno($conn) == 1062){ echo "<p>Email already taken</p>"; echo "<p>Go back to <a href=register.php>register page</a></p>"; } } } else{ "<p>Email not in the right format</p>"; } } } else{ echo "<p>Please fill in all the fields</p>"; } 之外的任何包。)

是否有其他方法可以允许一个软件包中的测试从另一个软件包访问其他内部数据,以进行集成测试?

2 个答案:

答案 0 :(得分:6)

如上所述,没有任何方法可以“授予”对未导出标识符的访问权限。

虽然需要/证明对fmt包测试的一些澄清。

有两种测试:黑盒测试和白盒测试。

黑盒测试是指您将包视为“黑盒子”,并且仅通过其导出的标识符(通过其“公共API”,其他包看到的内容)对其进行测试。在这种情况下,测试文件具有不同的包名称(例如,在测试fmt_test包时fmt)。

白盒测试是指您使用包的导出和未导出的标识符。要创建白盒测试,请在测试文件中指定与正在测试的包相同的包名称(因此,fmt包测试时为fmt

标准lib的fmt打算中包含的测试是黑盒测试,但是它无法测试所有内容。所以Go作者去了一个混合版本:它们包含一个export_test.go测试文件,该文件使用相同的包声明(package fmt),因此它可以访问未导出的标识符fmt包,它“导出”2个标识符,以便其他(黑盒)测试文件可以访问:

var IsSpace = isSpace
var Parsenum = parsenum

作者这样做是因为他们希望尽量减少未使用的标识符的使用,因此这明确标记了未使用的标识符的使用,并且基本上充当fmt包与...之间的“桥梁”。 fmt包的黑盒测试。

这里要注意的一点是,这些只会被“导出”到fmt包的(黑盒)测试(当然是fmt的白盒测试),并且不适用于其他包装或其他包装的测试。原因很简单,因为只有在运行包测试时,才会在构建包时解析和编译测试文件。

<强>解决方案吗

未经传播的标识符适用于包本身,并且它们不是别人的业务。这意味着没有其他包应该想要测试它们。如果需要进行测试,必须在软件包自己的测试中完成。

如果要进行集成测试,您需要访问未导出的标识符,那么包必须导出“某些东西”,这些东西要么暴露值(或它们的某些部分),要么在不导出敏感数据或实现细节的情况下帮助进行测试。如果软件包API设计得很好并且测试是彻底的,那么就不应该(很少)这样做。

答案 1 :(得分:2)

  

是否有其他方法可以允许一个软件包中的测试从另一个软件包访问其他内部数据,以进行集成测试?

没有。没有。