Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 在测试类中组织单元测试_Unit Testing_Vsunit - Fatal编程技术网

Unit testing 在测试类中组织单元测试

Unit testing 在测试类中组织单元测试,unit-testing,vsunit,Unit Testing,Vsunit,假设我在一个测试类中有几个单元测试(在我的例子中是VSUnit中的[TestClass])。我试图在每个测试中只测试一件事情(但并不意味着只测试一个断言)。假设有一个测试(例如test_MethodA())也测试其他测试中使用的方法。我不想在其他测试中使用断言来避免重复性/可维护性问题,因此我只在这一个测试中使用断言。现在,当这个测试失败时,所有依赖于被测试方法正确执行的测试也会失败。我希望能够更快地定位问题,因此我希望以某种方式指向Test_MethodA。例如,如果我能让测试类中的一些测试按

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


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

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

使用Visual Studio,您可以订购测试:。但我想建议您尽可能远离这种技术:单元测试意味着可以在任何地方、任何时间、任何顺序运行

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

您不能(也不应该)以特定的顺序执行单元测试。这样做的根本原因是为了防止——我意识到您请求这种特性的动机是不同的,但这就是为什么单元测试框架不允许您订购测试的原因。事实上,上一次我检查时,甚至将顺序随机化

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

但是,如果可能的话,考虑使用A代替其他方法。

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

下面是一个例子:

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();
var-sutsub=new Mock();
//默认情况下,Moq覆盖所有虚拟方法,而不调用base
//现在按顺序调用这两个方法:
sutsub.Object.FirstMethod();//被Moq覆盖,所以它什么也不做
sutb.Object.SecondMethod();

我想我确实会在依赖其结果的每个测试中使用
方法A()
结果的断言,即使这会引入一些重复。然后我将使用断言消息指向
方法A()
failure

assert("method_A() returned true", true, rc);
也许我将结束将方法_A()调用和断言提取到一个helper函数中以消除重复

现在让我们想象一下方法_A()查询一个对象并返回它,或者在找不到对象时返回NULL。那么这个断言就是一个例子;而且,对于C、C++,不需要有<代码> Null PoExtExeals< /C> >的语言是必要的。