在这篇文章中,我们将介绍用于单元测试的布尔断言方法assertTrue和assertFalse与身份断言assertIs之间的区别。定义下面是当前单元测试模块文档中对assertTrue和assertFalse的描述,代码高亮:assertTrue(expr,msg=None)assertFalse(expr,msg=None)测试表达式是否为真(或假).注意:这等同于bool(expr)isTrue而不是exprisTrue(在后一种情况下使用assertIs(expr,True))。MozillaDeveloperNetwork对truth的定义如下:在布尔上下文中变为“true”的值在Python中等同于:bool(expr)isTrue这完全符合assertTrue测试的目的。所以文档已经声明assertTrue返回true,assertFalse返回false。这些谓词方法根据接收到的值构造一个布尔值,然后对其求值。文档还建议我们根本不应该使用assertTrue和assertFalse。如何在实践中理解它?让我们使用一个非常简单的示例-一个名为always_true的函数,它返回True。我们为它编写一些测试用例,然后更改代码并查看测试用例的行为方式。首先,让我们编写两个测试用例。一种是“松散”:使用assertTrue来测试真实性。另一个是“严格的”:按照文档中的建议使用assertIs函数。importunittestfromfuncimportalways_trueclassTestAlwaysTrue(unittest.TestCase):deftest_assertTrue(self):"""always_truereturnstruthyvalue"""result=always_true()self.assertTrue(result)deftest_assertIs(self):"""always_truereturnsTrue"""result=always(result,True)下面是func.py中非常简单的函数代码:defalways_true():"""I'malwaysTrue.Returns:bool:True"""returnTrue当你运行时,所有测试都通过:always_truereturnsTrue...okalways_truereturnstruthyvalue...ok--------------------------------------------------------------------Ran2testsin0.004sOK快乐~现在,有人将always_true函数更改为以下内容:defalways_true():"""I'malwaysTrue.Returns:bool:True"""return'True'现在用返回字符串“True”替换之前的True(布尔值)。(当然,那个“某人”并没有更新文档——我们稍后会让它变得更难。)这次结果不那么开心:always_truereturnsTrue...FAILalways_truereturnstruevalue...ok=============================================================================失败:always_true返回真的-----------------------------------------------追溯(mostrecentcalllast):文件“/tmp/assertttt/test.py”,第22行,intest_is_trueself.assertIs(结果,真)AssertionError:'True'isnotTrue-----------------------------------------------------------------Ran2testsin0.004sFAILED(failures=1)只有一个测试用例失败!这意味着assertTrue给了我们一个误报。它在不应该通过的时候通过了测试。幸运的是,我们的第二个测试是使用assertIs编写的。因此,正如手册中了解到的信息,为了保证always_true的功能与更严格测试的结果一致,应该使用assertIs而不是assertTrue。使用assertIs来测试返回True和False的辅助方法非常冗长。所以,如果你有一个项目需要经常检查返回的是True还是False,那你可以自己写一些辅助方法来断言。这样看起来并没有节省多少代码,但是个人感觉提高了代码的可读性。defassertIsTrue(self,value):self.assertIs(value,True)defassertIsFalse(self,value):self.assertIs(value,False)总结一般来说,我的建议是让你的测试尽可能严格。如果您想测试真假,请遵循文档的建议并使用assertIs。除非必须,否则不要使用assertTrue和assertFalse。如果您遇到一个可以返回多种类型的函数,例如,有时返回布尔值,有时返回整数,请考虑重构它。这是一种代码味道。在Python中,抛出异常比使用False指示错误更好。此外,如果您确实想使用断言来确定函数的返回值是否为真,则可能会有第二种代码味道——代码是否被正确封装?如果assertTrue和assertFalse是针对正确的if语句执行的,则值得检查下一步是否打包了所需的所有内容。也许那些if语句应该包含在被测函数中。测试愉快!
