事物的隔离性属性
这是从此处开始的十项测试属性的最后,最后和第十个条目。 您应该阅读所有这些内容。
我们通常在模拟方面谈论隔离。 意思是,当我们想测试我们的代码并且代码具有依赖关系时,我们使用模拟来伪造那些依赖关系,并允许我们隔离地测试代码。
那就是代码隔离。 但是测试隔离是不同的。
隔离的测试可以以套件的任何顺序单独运行,独立于其他测试,并给出一致的结果。 我们已经在足迹中确定了可能影响结果的不同环境依赖性,当然,经过测试的代码与之相关。
其他测试也可以直接或不直接创建依赖关系。 实际上,有时我们可能依赖测试的顺序。
举个例子,我召集了起诉的证人:辛格尔顿。
这是一些使用单例的基本代码:
public class Counter
{
private static Counter instance;
private int count = 0;
public static void Init()
{
instance = new Counter();
}
public static Counter GetInstance()
{
return instance;
}
public int GetValue()
{
return count++;
}
}
非常简单:静态实例是在对Init的调用中初始化的。 我们可以编写以下测试:
[TestMethod]public void CounterInitialized_WorksInIsolation()
{
Counter.Init();
var result = Counter.GetInstance().GetValue();
Assert.AreEqual(0, result);
}
[TestMethod]public void CounterNotInitialized_ThrowsInIsolation()
{
var result = Counter.GetInstance().GetValue();
Assert.AreEqual(1, result);
}
请注意,第二个在第一个之后运行时经过。 但是,如果您单独运行它,则会崩溃,因为实例尚未初始化。 当然,这会使单身人士取一个不好的名字。 现在,您需要跳过箍以检查第二种情况。
顺便说一下,我们不仅依赖于测试的顺序,还依赖于测试运行者运行它们的方式。 可能是按照我们编写它们的顺序,但不一定。
虽然单例多数出现在测试的代码中,但由于测试本身可能会导致测试依赖关系。 只要您在测试类中保持状态(包括模拟操作),就有可能取决于运行顺序。
你知道这个把戏吗?
public class MyTests: BaseTest {
///...
为什么不将所有通用代码放在基类中,然后从中派生测试类呢?
嗯,除了使准备工作受到影响和调试困难之外,我们现在还有各种测试设置和行为都位于另一个共享的位置。 测试本身可能不会受到其他测试的干扰,但是我们通过将共享代码放入基类中引入了这种风险。 另外,您无需再了解初始化顺序。 如果基类使用单例该怎么办? 滑稽动作随之而来。
测试隔离问题很容易显示出来,因为一旦它们出现故障(哈哈),您将获得红灯。 问题是确定问题,因为它看起来像是“不可复制的问题”。
为了避免隔离问题:
- 检查代码。 如果您可以识别诸如singelton之类的用法模式,请注意并使用它:在整个运行之前初始化单例,或者在每次测试之前重新启动它。
- 改编。 如果还有其他依赖性(例如我们的计数器增加),请开始考虑重新安排测试。 因为代码的编写方式,所以您开始测试的不仅是小操作。
- 不要继承。 测试基类创建相互依赖关系并损害了隔离性。
- 嘲笑。 使用模拟来控制任何共享依赖项。
- 清理。 确保自己清理后的测试。 或者,而是在每次运行之前。
测试中的隔离问题非常令人讨厌,因为尤其是在单元测试中,可以轻松避免它们。 知道代码,了解依赖关系,从不依赖于另一个测试来设置当前测试所需的状态。
翻译自: https://www.javacodegeeks.com/2014/08/test-attribute-10-isolation.html
事物的隔离性属性