2010-02-18 92 views
3

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

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

回答

1

我想我确实会对method_A()结果在每个测试依托其结果断言,即使这会产生一些重复。然后我会使用断言消息指向method_A()失败

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

也许我会在最后提取method_A()调用断言为辅助函数删除重复。

现在让我们设想一下method_A()查询一个对象并返回它,或者当没有找到对象时返回NULL。那么这个断言是一个guard;并且对于没有NullPointerException的语言如C,C++是必要的。

0

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

使用Visual Studio,您可以订购您的测试:see here。但我想建议您尽可能远离这种技术:单元测试旨在随时随地按任何顺序运行。

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

3

您不能(也不应该)以特定顺序执行单元测试。造成这种情况的根本原因是为了防止Interacting Tests - 我意识到你请求这种功能的动机是不同的,但这就是单元测试框架不允许你订购测试的原因。实际上,我上次查看的时候,xUnit.net甚至随机化了这个命令。

有人可能会争辩说,一些测试依赖于同一类上的不同方法调用的事实是严密耦合的症状,但情况并非总是如此(状态机可以想到)。

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

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

下面是一个例子:

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

    public void SecondMethod() {} 
} 

由于FirstMethod是虚拟的,你可以从MyClass的派生并覆盖其行为。您还可以使用动态模拟为您做到这一点。随着起订量,它应该是这样的:

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(); 
+0

感谢链接到Gerard Meszaros的网站... – trendl 2010-02-18 10:29:35