自动生成代码的单元测试:自动还是手动?

3 投票
4 回答
2784 浏览
提问于 2025-04-15 11:30

我知道之前有类似的问题被问过,但那些回答并没有我想要的信息——我并不是在询问如何生成单元测试的具体方法,而是在问这样做是否值得。

我写了一个Python模块,里面包含了表示物理常数和计量单位的对象。很多单位是通过在基本单位前加上前缀来形成的——比如从m(米)可以得到cm(厘米)、dm(分米)、mm(毫米)、hm( hectometer)、um(微米)、nm(纳米)、pm(皮米)等等。其他单位如s(秒)、g(克)、C(摄氏度)等也是如此。当然,我写了一个函数来处理这些,因为最终结果有超过1000个单位,手动写出来实在是太麻烦了 ;-) 它的工作原理大致是这样的(不是实际代码):

def add_unit(name, value):
    globals()[name] = value
    for pfx, multiplier in prefixes:
        globals()[pfx + name] = multiplier * value

add_unit('m', <definition of a meter>)
add_unit('g', <definition of a gram>)
add_unit('s', <definition of a second>)
# etc.

问题在于,当我想为这些单位编写单元测试时(没有双关的意思),以确保它们都有正确的值。如果我写的代码是自动为每个单位生成一个测试用例,那么在单位生成函数中出现的任何问题,很可能也会出现在测试生成函数中。但是考虑到另一种选择(手动写出1000多个测试),我是否应该继续写一个测试生成函数,仔细检查它并希望它能正常工作?还是说我只测试一系列单位(比如mcmdmkmnmum,以及所有其他米的倍数),仅仅确保单位生成函数看起来正常?或者有其他的做法?

4 个回答

1

我觉得最好的办法是对生成的结果进行单元测试。在单元测试中,你可以选取一个生成的样本结果(只要这个样本和其他情况有明显的不同就可以),然后把它放到单元测试里,确保生成的过程是正确的。除此之外,自动化地定义每一种情况进行单元测试的价值不大。你可以考虑做一些功能测试,这样可以测试生成的代码是否能完成你想要的功能,这样可以更全面地覆盖各种可能的情况。

1

如果你是自动生成测试:

  • 你可能会发现,查看所有测试(检查它们是否正确)比手动写所有测试要快得多。

  • 这些测试可能也更容易维护(如果你想以后修改它们,会更简单)。

1

你说得对,自动生成测试用例确实有它的不足之处。测试的价值在于通过两种不同的方式(你的代码和你自己的思考)得出相同的结果。如果你每次都走同样的路,那就没有真正测试到东西。

总结一下:除非生成测试结果的算法比你要测试的算法简单得多,否则永远不要写自动生成的测试。比如,测试一个排序算法就是一个适合自动生成测试的例子,因为验证一串数字是否按顺序排列很简单。另一个好的例子是解决谜题的程序,正如ChrisW在评论中提到的那样。在这两种情况下,自动生成测试是合理的,因为验证一个给定的解决方案是否正确比生成一个正确的解决方案要容易得多。

我对你的建议是:手动测试一小部分具有代表性的可能性。

[澄清一下:某些类型的自动化测试是合适且非常有用的,比如模糊测试。我想说的是,对于生成的代码,自动生成单元测试并没有太大帮助。]

撰写回答