如何记录单元测试?

ddb*_*eck 22 python documentation unit-testing docstring

我正在努力提高Python项目中测试的数量和质量.随着测试次数的增加,我遇到的困难之一是知道每个测试的作用以及它应该如何帮助发现问题.我知道跟踪测试的部分是更好的单元测试名称(已在别处解决),但我也有兴趣了解文档和单元测试如何结合在一起.

当这些测试将来失败时,如何记录单元测试以提高其效用?具体来说,是什么让一个好的单元测试docstring?

我很欣赏这些描述性答案以及具有出色文档的单元测试示例.虽然我只使用Python,但我对其他语言的实践持开放态度.

Kal*_*see 15

我使用方法名称专门记录了我的单元测试:

testInitializeSetsUpChessBoardCorrectly()
testSuccessfulPromotionAddsCorrectPiece()
Run Code Online (Sandbox Code Playgroud)

对于几乎100%的测试用例,这清楚地解释了单元测试验证的内容以及我使用的所有内容.但是,在一些更复杂的测试用例中,我将在整个方法中添加一些注释来解释几行正在做什么.

我之前看到过一个工具(我相信它适用于Ruby),它会通过解析项目中所有测试用例的名称来生成文档文件,但我不记得这个名字.如果您有国际象棋女王级的测试用例:

testCanMoveStraightUpWhenNotBlocked()
testCanMoveStraightLeftWhenNotBlocked()
Run Code Online (Sandbox Code Playgroud)

该工具将生成一个HTML文档,内容如下:

Queen requirements:
 - can move straight up when not blocked.
 - can move straight left when not blocked.
Run Code Online (Sandbox Code Playgroud)

  • 不,方法名称准确地解释了它正在测试的内容 - 该测试用例验证了initalize()正确设置了棋盘.繁荣,自动记录. (11认同)

Mik*_*zur 13

也许问题不在于如何最好地编写测试文档字符串,而是如何自己编写测试?以他们自我记录的方式重构测试可能会有很长的路要走,并且当代码更改时,您的docstring不会过时.

您可以采取一些措施来使测试更加清晰:

  • 清晰和描述性的测试方法名称(已经提到)
  • 测试体应清晰简洁(自我记录)
  • 在方法中抽象出复杂的设置/拆解等
  • 更多?

例如,如果你有这样的测试:

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
Run Code Online (Sandbox Code Playgroud)

您可以使用方法调用替换setup语句:

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
Run Code Online (Sandbox Code Playgroud)

请注意,您的测试方法现在由一系列具有意图揭示名称的方法调用组成,这是一种特定于您的测试的DSL.这样的测试是否还需要文档?

另外需要注意的是,您的测试方法主要是在一个抽象层次上.阅读测试方法的人会看到算法是:

  • 创建一个小部件
  • 在小部件上调用run
  • 声明代码完成了我们的期望

他们对测试方法的理解并没有被设置窗口小部件的细节混淆,这是一个比测试方法更低的抽象级别.

测试方法的第一个版本遵循内联设置模式.第二个版本遵循Creation MethodDelegated Setup模式.

一般来说,我反对评论,除非他们解释代码的"原因".阅读叔叔鲍勃马丁的清洁法典使我确信这一点.有一章关于评论,有一章关于测试.我推荐它.

有关自动测试最佳实践的更多信息,请查看xUnit模式.