为我不明白目的的代码编写测试


59

我最近完成了黑盒重构。我无法检入它,因为我无法确定如何进行测试。

在较高的层次上,我有一个其初始化涉及从某些类B获取值的类。如果类B为“空”,它将生成一些合理的默认值。我将这一部分提取到一种方法中,该方法将B类初始化为相同的默认值。

我还没有弄清这两个类的目的/背景,或如何使用它们。因此,我无法从空的类B初始化对象并检查其是否具有正确的值/是否做正确的事情。

我最好的主意是运行原始代码,根据初始化的成员在公共方法的结果中进行硬编码,然后对此进行测试。我不太清楚为什么我对这个想法含糊不清。

这里有更好的进攻方式吗?


28
我觉得您的起点错误。您应该首先了解代码,然后对其进行测试,然后进行重构。为什么在不知道代码用途的情况下进行重构?
雅各布·赖勒

11
@JacobRaihle对于那些从未接触过学位的人来说,这是一个相当专业的程序。我正在逐步了解上下文,但是在开始之前等待有深入的了解根本不切实际。
JETM '17

4
不切实际的是重写事物,并且在生产中进行更改时,发现您不应该拥有的原因。如果您能够在此之前进行全面测试,那么很好,这可能是了解代码库的好方法。如果没有,那么必须在更改之前先了解一下。
雅各布·赖尔

37
当您要测试系统的实际行为时,有一种称为“ 特性测试”的特定测试。您只需要使用原始系统,然后添加测试以声明其实际功能(不一定是要执行的操作!)。它们充当系统的支架,您可以安全地对其进行修改,因为可以确保它保留其行为。
Vincent Savard

3
你能不能问/得到它的人谁审查理解呢?
pjc50

Answers:


122

你还好!

创建自动化回归测试通常是使组件可重构的最佳方法。可能令人惊讶,但是只要您了解输入和输出“接口”(按该词的一般含义),通常就可能在不完全了解组件内部功能的情况下编写此类测试。过去,我们对成熟的遗留应用程序(不仅是类)进行了几次这样的操作,它通常可以帮助我们避免破坏我们不完全了解的内容。

但是,您应该具有足够的测试数据,并确保从该组件用户的角度对软件的功能有深刻的了解,否则可能会忽略重要的测试用例。

恕我直言,开始重构之前(而不是重构之后)实施自动化测试是一个好主意,因此您可以分步进行重构,并验证每一步。重构本身应该使代码更具可读性,因此它可以帮助您逐步了解内部。因此,此过程中的订购步骤为

  1. 理解代码“从外部”,
  2. 编写回归测试,
  3. 重构,从而可以更好地理解代码的内部结构

21
完美的答案,也正好与“使用旧版代码”一书中所述
Altoyr

我不得不做一次这样的事情。在修改之前,请从应用程序中收集典型的输出数据,然后通过运行相同的测试数据来检查应用程序的新版本。30年前... Fortran ...这是某种图像处理/映射的东西,因此我真的无法通过查看或编写测试用例来了解输出“应该”是什么。而且,我是在Tektronix矢量(持久)显示器上完成的。政府工作... 2电传打字机在我身后荡漾。

4
可能会补充说,事实发生后,您仍然可以为旧代码编写测试。然后,您可以在重构的版本上尝试使用它们,如果发现有问题,请按照提交历史进行二等分搜索,以查找开始崩溃的地方。
CodeMonkey

2
我建议再做一件事。收集测试数据时,请尽可能收集代码覆盖率统计信息。您将知道您的测试数据对相关代码的描述程度。
liori

2
@nocomprende,很有趣,上周我用遗留的科学fortran 77代码做了那件事。将ascii数据打印添加到文件中,使用输入和预期输出设置测试目录,而我的测试用例只是两组输出的区别。如果他们的角色不匹配,我就会破坏某些东西。当代码主要是两个子例程,每个子例程的2-3k LoC时,您必须从某个地方开始。
Godric Seer

1

编写单元测试的一个重要原因是它们以某种方式记录了组件API。在这里,不了解被测代码的目的确实是一个问题。代码覆盖率是另一个重要目标,如果不知道存在哪些执行分支以及如何触发它们就很难实现。

但是,如果可以干净地重置状态(或每次构造新的测试对象),则可以编写“垃圾进垃圾出”类型的测试,该测试仅将大部分随机输入馈入系统并观察输出。

这样的测试很难维护,因为当它们失败时,说出原因和严重程度可能很复杂。覆盖范围可能令人怀疑。但是,它们总比没有好。当此类测试失败时,开发人员可以更加关注地修订最新的更改,并希望在那里发现该错误。


1
任何种类的信息总比盲目走动更好。我曾经通过在故障转储文件(Unix)上调用调试器并要求堆栈跟踪来定位生产中的服务器程序中的错误。它为我提供了发生故障的函数的名称。即使没有其他知识(我不知道如何使用此调试器),它也可以帮助解决本来是神秘且不可复制的情况。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.