在测试类中组织单元测试

3
假设我在一个测试类中有几个单元测试(在我的情况下是VSUnit中的[TestClass])。我尝试在每个测试中只测试一件事情(不仅仅是一个Assert)。想象一下,有一个测试(例如Test_MethodA())测试了其他测试中使用的方法。我不想在使用它的其他测试中放置对该方法的断言,以避免重复性/可维护性问题,因此我只在这个测试中放置了断言。现在,当这个测试失败时,所有依赖于正确执行该测试方法的测试也会失败。我希望能够更快地找到问题所在,因此我希望能够指向Test_MethodA。例如,如果我可以使测试类中的某些测试按特定顺序执行,并且当它们失败时,我会开始查找第一个失败测试的原因,那么这将会有所帮助。你有任何想法如何做到这一点吗?
编辑:通过建议按特定顺序执行测试来解决问题,我可能走得太远而且方向错误。我不关心测试的顺序。只是有些测试如果先决条件无效就会始终失败。例如,我有一个测试类,测试DAO类(好吧,可能不是一个UNIT测试,但存储过程中有需要测试的逻辑,但我认为这不是重点)。我需要向表中插入一些记录,以便测试负责检索记录的方法(让我们称之为GetAll())是否按正确顺序获取它们。例如,我使用DAO类上的一个方法来进行插入。让我们称之为Insert()。我已经编写了测试,验证Insert()方法按预期工作。现在我想测试GetAll()方法。为了使数据库处于所需状态,我使用Insert()方法。如果Insert()不起作用,则大多数GetAll()测试将失败。我希望将无法通过的测试标记为不确定而不是失败。如果我知道要首先查看哪个方法/测试,那么找到问题的原因会更容易。
3个回答

3

您不能(也不应该)按特定顺序执行单元测试。其根本原因是为了防止 交互式测试 - 我知道您请求此功能的动机不同,但这就是为什么单元测试框架不允许您排序测试的原因。事实上,上次我检查时,xUnit.net 甚至会随机排列顺序。

有人可能会认为,您的一些测试依赖于同一类上的不同方法调用是紧密耦合的症状,但并非总是如此(状态机就是一个例子)。

但是,如果可能的话,请考虑使用 后门 而不是其他相关方法。

如果您既不能这样做,也不能解除相互依赖关系(例如通过使第一个方法虚拟并使用 提取和覆盖 技术),那么您将不得不接受它。

以下是一个示例:

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

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

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

也许我会将 method_A() 的调用和断言提取到一个辅助函数中,以消除重复代码。
现在假设 method_A() 查询一个对象并返回它,或者在未找到对象时返回 NULL。那么这个断言就是一个 保护;对于像 C、C++ 这样没有 NullPointerException 的语言来说,这是必要的。

0

很抱歉,您不能这样做。唯一的解决方案是重新设计您的代码,并将其拆分成较小的方法,以便单元测试可以逐个调用这些方法。当然,这并不总是理想的。

使用Visual Studio,您可以对测试进行排序:在此处查看。但我建议您尽可能远离这种技术:单元测试应该随时随地以任何顺序运行。

编辑:为什么这对您是个问题?所有失败的测试都指向同一个方法...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接