我正在尝试提高Python项目中测试用例的数量和质量。随着测试用例数量的增加,我遇到的一个困难是知道每个测试用例的作用以及它如何帮助检测问题。我知道跟踪测试用例的一部分是更好的单元测试名称(已在其他地方解决),但我也对了解文档和单元测试如何结合感兴趣。
如何记录单元测试,以在将来这些测试失败时提高其效用?具体而言,什么样的单元测试文档字符串才是好的?
我期待有描述性的答案和具有优秀文档描述的单元测试示例。虽然我只使用Python,但我可以接受其他语言的做法。
我正在尝试提高Python项目中测试用例的数量和质量。随着测试用例数量的增加,我遇到的一个困难是知道每个测试用例的作用以及它如何帮助检测问题。我知道跟踪测试用例的一部分是更好的单元测试名称(已在其他地方解决),但我也对了解文档和单元测试如何结合感兴趣。
如何记录单元测试,以在将来这些测试失败时提高其效用?具体而言,什么样的单元测试文档字符串才是好的?
我期待有描述性的答案和具有优秀文档描述的单元测试示例。虽然我只使用Python,但我可以接受其他语言的做法。
我主要使用方法名来记录我的单元测试:
testInitializeSetsUpChessBoardCorrectly()
testSuccessfulPromotionAddsCorrectPiece()
对于近乎100%的我的测试用例,这清楚地解释了单元测试正在验证什么,这就是我使用的全部内容。然而,在一些更复杂的测试用例中,我会在方法中添加一些注释来解释几行代码正在做什么。
我曾经见过一个工具(我相信它是针对Ruby的),它通过解析项目中所有测试用例的名称生成文档文件,但我不记得它的名称了。如果您有一个棋后类的测试用例:
testCanMoveStraightUpWhenNotBlocked()
testCanMoveStraightLeftWhenNotBlocked()
Queen requirements:
- can move straight up when not blocked.
- can move straight left when not blocked.
def test_widget_run_returns_0():
widget = Widget(param1, param2, "another param")
widget.set_option(true)
widget.set_temp_dir("/tmp/widget_tmp")
widget.destination_ip = "10.10.10.99"
return_value = widget.run()
assert return_value == 0
assert widget.response == "My expected response"
assert widget.errors == None
def test_widget_run_returns_0():
widget = create_basic_widget()
return_value = widget.run()
assert return_value == 0
assert_basic_widget(widget)
def create_basic_widget():
widget = Widget(param1, param2, "another param")
widget.set_option(true)
widget.set_temp_dir("/tmp/widget_tmp")
widget.destination_ip = "10.10.10.99"
return widget
def assert_basic_widget():
assert widget.response == "My expected response"
assert widget.errors == None
在编写文档字符串时,应该使用描述性的方法名称和注释的组合。一个好的方法是在文档字符串中包含基本的过程和验证步骤。然后,如果您从某种自动化运行测试并收集结果的测试框架中运行这些测试,您可以让框架记录每个测试方法的文档字符串内容以及其stdout+stderr。
以下是一个基本示例:
class SimpelTestCase(unittest.TestCase):
def testSomething(self):
""" Procedure:
1. Print something
2. Print something else
---------
Verification:
3. Verify no errors occurred
"""
print "something"
print "something else"
在测试过程中使用该程序可以更轻松地弄清楚测试的内容。如果您将文档字符串与测试输出一起包含,那么在稍后查看结果时确定出错原因就会变得更加容易。我之前工作的地方也是这样做的,当出现故障时效果非常好。我们自动在每次提交时运行单元测试,使用CruiseControl。
当测试失败时(应该在它通过之前),您应该看到错误消息并能够知道出了什么问题。这只有在您计划的情况下才会发生。
这完全取决于测试类、测试方法和断言消息的命名方式。当测试失败时,如果您无法从这三个线索中知道出了什么问题,则重命名一些内容或拆分一些测试类。
如果夹具的名称是ClassXTests,测试的名称是TestMethodX,错误消息是“期望为true,返回为false”,那么这就是测试编写不规范的迹象。
大多数情况下,您不必阅读测试或任何注释就可以知道发生了什么。
test_
前缀。不过我使用的是 nosetest,它依赖于方法名中出现单词 'test' 来进行单元测试发现。http://somethingaboutorange.com/mrl/projects/nose/0.11.1/ - Mike Mazur