【问题标题】:Organizing unit test within a test class在测试类中组织单元测试
【发布时间】:2010-02-18 08:28:00
【问题描述】:

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

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

【问题讨论】:

    标签: unit-testing vsunit


    【解决方案1】:

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

    有人可能会争辩说,您的某些测试依赖于对同一类的不同方法调用这一事实是紧密耦合的一种表现,但情况并非总是如此(想到状态机)。

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

    如果您不能这样做或解耦相互依赖关系(例如,通过将第一个方法设为虚拟并使用 Extract and Override 技术),您将不得不忍受它。

    这是一个例子:

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

    【讨论】:

      【解决方案2】:

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

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

      也许我会结束将 method_A() 调用提取到辅助函数中以删除重复项。

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2012-12-25
          • 2011-07-06
          • 2013-02-04
          • 2016-02-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-05
          相关资源
          最近更新 更多