如何进行一项测试取决于另一项测试的结果?


13

假设有一个实用程序类,提供了许多其他类在代码中各处使用的一些常见静态方法。

您将如何为实用程序的使用者设计单元测试,以便在任何一项实用程序测试未通过的情况下使他们的测试失败?您可以这样做还是必须自己检查实用程序类测试是否全部为绿色?

例如,我有一个消息拆分器实用程序,它由消息解析器使用(或更确切地说,它的输出)。我想确保在测试邮件解析器之前,邮件拆分器能够正常工作。

我已经为它们两个编写了测试,但是有没有办法链接它们并使一个测试依赖于其他测试的结果?

我找不到适合的标签,但是我使用的是Visual Studio的单元测试引擎。


1
我了解如果实用程序失败,解析器将无法正常工作。但是,如果您运行测试,则会看到实用程序测试失败。为什么还要其他测试也失败?
Eugen Martynov 2015年

1
我从来没有听说过有人想要这个。您要达到什么目标?
Esben Skov Pedersen


我使用一些实用程序功能为解析器测试准备数据,因此我想绝对确保在测试其他任何程序之前该实用程序都能正常工作。
t3chb0t 2015年

3
@ t3chb0t如果要确保实用程序正常工作,则需要编写单元测试以验证实用程序。单元测试应该是原子的。您只希望他们测试单个组件。
maple_shaft

Answers:


11

没有必要确保系统中的每个缺陷都完全通过了一项测试。

测试套件有一项工作:验证没有已知的缺陷。如果存在缺陷,那么一个测试失败还是10无关紧要。如果您习惯了测试套件的失败,那么如果您通过计算失败的测试来衡量程序的“不良”程度,那您就不会使用正确的回归测试方法。在发布代码之前,测试套件应通过所有测试。

跳过测试的唯一正当理由是,如果他们测试不完整的功能花费过多的时间,您可以在实施他们应该测试的东西时更好地利用它们。(这只是一个问题,如果您不练习严格的测试驱动开发,那么毕竟这是一个有效的选择。)

否则,请不要试图将测试套件变成一个指标,以准确地告诉您出了什么问题。它永远不会是精确的,也不应该是。这样做可以保护您避免两次犯同样的错误。


8

这取决于您的工具,但您可能无法(也不应该)

一些单元测试框架(例如PHPUnit)允许您“链接”测试,以便一个级别上失败的测试不会执行其他测试。但是,我怀疑这样是否可以解决您的问题。

不允许有保证的测试订单执行会强制将测试彼此隔离,这通常被认为是一件好事。想象一下,如果测试不仅可以自己运行,而且还可以提供数据供其他测试进行,那将会发生什么……

您可以将这些实用程序方法放在单独的解决方案或测试类别中。确保它们在测试运行程序中以视觉方式“脱颖而出”,或者,如果该类别的测试失败*,则该类别首先运行并且不运行任何其他测试。当这些测试之一失败时,故障可能会在所有测试中级联,您应该确保首先运行这些失败的测试,以确保运行测试的人都知道要开始。单元测试和集成测试也是如此。如果单元测试失败,它将在集成测试中级联并引起各种混乱。大家都知道,当单元和集成测试失败时,您首先要检查单元测试...

*使用自动构建或测试脚本,您可以首先运行此类别,检查结果,仅在第一批测试通过时才运行其他测试。


5

尝试保持单元测试的原子性。请记住,自动化测试代码也是代码库的一部分,但是它本身并未处于测试中,因此请使其尽可能简单明了。

为了更直接地回答您的问题,我们无法保证测试的执行顺序,因此也无法保证在运行其他测试之前您的实用程序测试成功。因此,在为所有测试提供单个测试套件的同时,无法保证实现所需的方法。

您可以将实用程序移至其自己的解决方案,并在当前项目中添加对其生成的dll的引用。


4

总而言之,您不想使用工具/技术来完成除预期用途之外的其他事情。

您尝试做的事情听起来像是一个问题,可以通过CI(连续集成)实践轻松解决。

这样,您可以按照建议的方式保持测试的原子性,并让CI负责验证您的测试。

如果任何测试失败,则可以对其进行设置,以免其代码被发布。


4

我习惯于始终尝试将应用程序级代码与框架级代码区分开,所以我遇到了您经常描述的问题:您通常希望先测试所有框架级代码,然后再开始测试任何应用程序级代码。 。同样,即使在框架级别的代码中,所有其他框架模块也倾向于使用一些基础框架模块,如果在基础方面有些问题,那么测试其他任何东西实际上是没有意义的。

不幸的是,测试框架的提供者往往对如何使用其创作有一些僵化的想法,并且对这些想法持保护态度,而使用框架的人则倾向于接受预期的用法而不会提出质疑。这是有问题的,因为它扼杀了实验和创新。我不了解其他所有人,但我宁愿有自由尝试以一种奇怪的方式做某事,并亲自检查结果是否优于既定的方法,而不是没有自由去做。首先以我的方式做事。

因此,在我看来,测试依赖项将是一件令人敬畏的事情,而代替这一点,指定执行测试顺序的能力将是下一件最好的事情。

我发现解决排序测试问题的唯一方法是仔细命名,以便利用测试框架按字母顺序执行测试的趋势。

我不知道这在Visual Studio中是如何工作的,因为我还没有做任何涉及使用C#进行广泛测试的事情,但是在Java方面,它的工作方式如下:在项目的源文件夹下,我们通常有两个子文件夹,一个称为“ main”(包含生产代码),另一个称为“ test”(包含测试代码)。在“主”下,我们有一个文件夹层次结构,它与源代码的包层次结构完全对应。Java包大致对应于C#名称空间。C#不需要将文件夹层次结构与名称空间层次结构进行匹配,但是建议这样做。

现在,人们在Java世界中通常要做的是,在“ test”文件夹下,他们镜像在“ main”文件夹下找到的文件夹层次结构,因此每个测试都驻留在与它所测试的类完全相同的程序包中。其基本原理是测试类经常需要访问被测类的程序包私有成员,因此测试类需要与被测类在同一程序包中。在C#方面,没有名称空间本地可见性之类的东西,因此没有理由镜像文件夹层次结构,但是我认为C#程序员在构造其文件夹时或多或少遵循相同的原则。

无论如何,我发现允许测试类访问被测类的程序包本地成员的整个想法都是错误的,因为我倾向于测试接口,而不是实现。因此,测试的文件夹层次结构不必镜像生产代码的文件夹层次结构。

因此,我要做的是,将测试的文件夹(即软件包)命名为:

t001_SomeSubsystem
t002_SomeOtherSubsystem
t003_AndYetAnotherSubsystem
...

这保证了对“ SomeSubsystem”的所有测试将在对“ SomeOtherSubsystem”的所有测试之前执行,而依次对所有“ AndYetAnotherSubsystem”的测试之前执行,依此类推。

在文件夹中,各个测试文件的命名如下:

T001_ThisTest.java
T002_ThatTest.java
T003_TheOtherTest.java

当然,现代的IDE具有强大的重构功能将极大地帮助您,只需单击几下鼠标,便可以重命名整个程序包(以及所有子程序包以及引用它们的所有代码)。


2
I don't know about everyone else, but I would prefer to have the freedom to try to do something in an odd way, and see for myself whether the results are better or worse++队友。我不知道我喜欢解决方案,但是我喜欢您在那儿表现出的态度。
RubberDuck
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.