在测试课程中组织单元测试

时间:2010-02-18 08:28:00

标签: unit-testing vsunit

假设我在测试类中有几个单元测试(在我的情况下,VSUnit中的[TestClass])。我试图在每个测试中只测试一件事(但并不仅仅意味着一个Assert)。想象一下,有一个测试(例如Test_MethodA())测试其他测试中使用的方法。我不想在其他使用它的测试中对此方法设置断言以避免重复性/可维护性问题,所以我只在这一个测试中使用断言。现在,当此测试失败时,依赖于正确执行该测试方法的所有测试也会失败。我希望能够更快地找到问题所以我想以某种方式指向Test_MethodA。它会例如如果我可以让测试类中的某些测试按特定顺序执行,并且当它们失败时,我会在第一次失败的测试中查找失败的原因。你知道怎么做吗?

编辑:通过建议解决方案是按特定顺序执行测试,我可能走得太远,方向错误。我不关心测试的顺序。只是如果先决条件无效,某些测试将始终失败。例如。我有一个测试DAO类的测试类(好吧,可能不是UNIT测试,但是数据库存储过程中的逻辑需要测试但是我认为这不是重点)。我需要在表中插入一些记录,以便测试负责检索记录的方法(让我们称之为GetAll())以正确的顺序获取所有记录,例如我通过在DAO类上使用方法来执行插入操作。我们称之为Insert()。我有测试验证Insert()方法按预期工作。现在我想测试GetAll()方法。为了使数据库处于所需的状态,我使用Insert()方法。如果Insert()不起作用,则GetAll()的大多数测试都将失败。我更喜欢标记无法通过的测试,因为Insert()不起作用而不是失败。如果我知道首先要查看哪种方法/测试,它将很容易找到问题的原因。

3 个答案:

答案 0 :(得分:3)

您不能(也不应该)按特定顺序执行单元测试。这样做的根本原因是阻止Interacting Tests - 我意识到你请求这样一个功能的动机是不同的,但这就是为什么单元测试框架不允许你订购测试的原因。事实上,我上次检查时,xUnit.net甚至随机化了订单。

有人可能会争辩说,你的某些测试依赖于对同一个类的不同方法调用的事实是紧耦合的症状,但情况并非总是这样(状态机会浮现在脑海中)。

但是,如果可能,请考虑使用Back Door而不是其他相关方法。

如果您无法做到这一点或解耦相互依赖性(例如,通过将第一个方法设为虚拟并使用提取和覆盖技术),您将不得不忍受它。

以下是一个例子:

public class MyClass
{
    public virtual void FirstMethod() { // do something... }

    public void SecondMethod() {}
}

由于FirstMethod是虚拟的,您可以从MyClass派生并覆盖其行为。您还可以使用动态模拟为您执行此操作。使用Moq,它看起来像这样:

var sutStub = new Mock<MyClass>();
// by default, Moq overrides all virtual methods without calling base

// Now invoke both methods in sequence:
sutStub.Object.FirstMethod(); // overriden by Moq, so it does nothing
sutSutb.Object.SecondMethod();

答案 1 :(得分:1)

我认为我确实会在依赖于其结果的每个测试中对method_A()结果进行断言,即使这会引入一些重复。然后我使用断言消息指向method_A()失败

assert("method_A() returned true", true, rc);

也许我会结束提取method_A()调用断言到一个辅助函数来删除重复。

现在让我们假设method_A()查询对象并返回它,或者在没有找到对象时返回NULL。然后这个断言是guard;并且必须使用没有NullPointerException的C,C ++等语言。

答案 2 :(得分:0)

我担心你不能这样做。唯一的解决方案是重新设计代码并将其分解为更小的方法,以便单元测试可以逐个调用它们。当然,这并不总是可取的。

使用Visual Studio,您可以订购测试:see here。但是我建议你尽可能远离这种技术:单元测试应该在任何地方,任何时间和每个顺序运行。

编辑:为什么这对你来说是个问题?所有失败的测试无论如何都指向相同的方法......