原文

单元测试类通常都会有share setup和cleanup的相关代码。xUnit.net根据共享的范围提供了几种share setup和cleanup的方法。

Constructor and Dispose

使用场景: 当你想在每次测试后clean测试上下文 (shared setup/cleanup code 无共享对象实例)。

每次测试运行时xUnit.net会创建测试类的实例,所以测试类构造函数里的代码每次测试时都会运行。因此如果你想有些想可复用的上下文,构造函数是个非常适合放置这些可复用上下文的地方。

如果你想cleanup上下文,只需让你的测试类实现IDisposable, 并将cleanup上下文的代码写在Dispose() 方法中即可。

例子:

public class StackTests : IDisposable
{
Stack<int> stack; public StackTests()
{
stack = new Stack<int>();
} public void Dispose()
{
stack.Dispose();
} [Fact]
public void WithNoItems_CountShouldReturnZero()
{
var count = stack.Count; Assert.Equal(0, count);
} [Fact]
public void AfterPushingItem_CountShouldReturnOne()
{
stack.Push(42); var count = stack.Count; Assert.Equal(1, count);
}
}

有时候将上面的结构称为 "test class as context" 模式, 因为测试类本身自包含了setup上下文和cleanup上下文的代码。你甚至可以根据setup上下文后的情况来命名你的测试类,这样可以更容易的看出这个测试类的初始点是什么样的:

public class StackTests
{
public class EmptyStack
{
Stack<int> stack; public EmptyStack()
{
stack = new Stack<int>();
} // ... tests for an empty stack ...
} public class SingleItemStack
{
Stack<int> stack; public SingleItemStack()
{
stack = new Stack<int>();
stack.Push(42);
} // ... tests for a single-item stack ...
}
}

因为每个context是处于某种情况的Stack。我们把EmptyStackSingleItemStack类放在StackTests类里面。

Class Fixtures

使用场景: 你想创建一个测试上下文对象并在一个测试类中的多个测试方法中共享它,并在这个类中打得所有的测试结束后cleanup它。

有的时候setup和cleanup上下文是非常耗时的。如果你每个测试都去setup和cleanup上下文,那会非常耗时。这时你可以使用xUnit.net提供的fixture特性用来在一个测试类中的所有测试方法中共享同一个上下文对象。

我们已经知道 xUnit.net会为每次测试创建一个测试类的实例。当我们使用class fixture时, xUnit.net会确保在任何test测试前先创建fixture实例,并且一旦测试全部完成会调用Dispose执行cleanup。

使用class fixture步骤如下:

  • 创建fixture class, 将startup代码放在fixture class的构造函数中。
  • 如果fixture class要执行cleanup,那么需要实现IDisposable, 并在Dispose()中写cleanup的代码。
  • 测试类需要实现IClassFixture<>
  • 如果测试类想获取fixture class的实例,只需将fixture类作为参数传到测试类的构造函数中即可。

    例子:
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString"); // ... 在测试数据库中初始化数据 ...
} public void Dispose()
{
// ... 清除测试数据 ...
} public SqlConnection Db { get; private set; }
}
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture fixture; public MyDatabaseTests(DatabaseFixture fixture)
{
this.fixture = fixture;
} // ... write tests, using fixture.Db to get access to the SQL Server ...
}

MyDatabaseTests的测试运行前, xUnit.net会创建一个DatabaseFixture的实例。每个测试都会创建一个MyDatabaseTests的实例, 并将共享的DatabaseFixture实例传到测试类的构造函数中去。

注意: 如果你只在没有实现IClassFixture<>的情况下将fixture class做为了测试类的构造函数参数, xUnit.net会报错。

如果你需要多个fixture对象,只要实现多个IClassFixture<>,并将这些fixture对象作为测试类的构造函数参数就行了。构造函数参数的顺序不重要。

注意你没法控制fixture对象创建的顺序,fixture不能依赖其他的fixture。如果你想控制顺序或者在fixture之间有依赖关系,你需要创建一个类并在其中封装另外两个fixture。

注意: Fixtures必须和使用它的测试类在同一个程序集。

Collection Fixtures

使用场景: 你想在多个测试类中共享一个测试上下文对象,并在所有测试类的测试都跑完了后执行cleanup。

使用collection fixtures步骤如下:

  • 创建fixture class, 将startup代码放在fixture class的构造函数中。
  • 如果fixture class要执行cleanup,fixture class需要实现IDisposable, 将cleanup代码放在Dispose()方法中。
  • 创建collection definition class, 且添加[CollectionDefinition]attribute, 给一个唯一的名。
  • collection definition class实现 ICollectionFixture<>
  • 为所有要用collection fixtures的测试类添加[Collection]attribute, 并使用在collection definition class的[CollectionDefinition]attribute的唯一名。
  • 如果测试类想获取fixture class的实例,只需将fixture类作为参数传到测试类的构造函数中即可。

例子:

public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString"); // ... initialize data in the test database ...
} public void Dispose()
{
// ... clean up test data from the database ...
} public SqlConnection Db { get; private set; }
} [CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
} [Collection("Database collection")]
public class DatabaseTestClass1
{
DatabaseFixture fixture; public DatabaseTestClass1(DatabaseFixture fixture)
{
this.fixture = fixture;
}
} [Collection("Database collection")]
public class DatabaseTestClass2
{
// ...
}

xUnit.net对collection fixtures的处理可class fixtures类似, 除了collection fixture对象的生命周期更长: 在所有测试类的测试前创建,在所有测试类的测试完成后cleanup。

Test collections can also be decorated with IClassFixture<>. xUnit.net treats this as though each individual test class in the test collection were decorated with the class fixture.

Test collections also influence the way xUnit.net runs tests when running them in parallel. For more information, see Running Tests in Parallel.

注意: Fixtures和使用它的测试类必须在同一个程序集。

XUnit - Shared Context between Tests的更多相关文章

  1. Selenium + Chrome headless 报ERROR:gpu_process_transport_factory.cc(1007)] Lost UI shared context 可忽略并配置不输出日志

    Selenium不再推荐使用PhantomJS,会报如下警告 UserWarning: Selenium support for PhantomJS has been deprecated, plea ...

  2. 体验 ASP.NET Core 集成测试三剑客:xUnit.net、TestServer、EF Core InMemory

    这是昨天解决的一个问题,针对一个 web api 的客户端代理类写集成测试,既要测试 web api,又要测试 web api 客户端. 测试 web api,就要在运行测试时自动启动 web api ...

  3. setup in xunit

    https://xunit.github.io/docs/shared-context Shared Context between Tests It is common for unit test ...

  4. 单元测试过多,导致The configured user limit (128) on the number of inotify instances has been reached.

    最近在一个asp.net core web项目中使用TDD的方式开发,结果单元测试超过128个之后,在CI中报错了:"The configured user limit (128) on t ...

  5. Xunit

    Attributes Note: This table was written back when xUnit.net 1.0 has shipped, and needs to be updated ...

  6. XUnit 依赖注入

    XUnit 依赖注入 Intro 现在的开发中越来越看重依赖注入的思想,微软的 Asp.Net Core 框架更是天然集成了依赖注入,那么在单元测试中如何使用依赖注入呢? 本文主要介绍如何通过 XUn ...

  7. xUnit随笔

    XUnit入门 1.如果之前安装了xUnit.net Visual Studio Runner扩展包,通过"工具"菜单下的"扩展和更新"先将该扩展包卸载. 2. ...

  8. 使用 xunit 编写测试代码

    使用 xunit 编写测试代码 Intro xunit 是 .NET 里使用非常广泛的一个测试框架,有很多测试项目都是在使用 xunit 作为测试框架,不仅仅有很多开源项目在使用,很多微软的项目也在使 ...

  9. 使用xUnit为.net core程序进行单元测试(3)

    第1部分: http://www.cnblogs.com/cgzl/p/8283610.html 第2部分: http://www.cnblogs.com/cgzl/p/8287588.html 请使 ...

随机推荐

  1. 烂泥:zabbix3.0安装与配置

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 这个月又快过完了,最近也比较忙,没时间写文章,今天挤点时间把zabbix3.0安装与配置 ...

  2. java中的浮点数

    浮点数值不适用于禁止出现舍入误差的金融计算中.例如,命令System.out.println(2.0-1.1)将打印出0.8999999999999999999999999,而不是人们想象的0.9.其 ...

  3. XML中的转义字符

    HTML中<, >,&等有特别含义,(前两个字符用于链接签,&用于转义),不能直接使用.使用这三个字符时,应使用他们的转义序列,如下所示: & 或 & &a ...

  4. 异步方法的意义何在,Async和await以及Task的爱恨情仇,还有多线程那一家子。

    前两天刚感受了下泛型接口的in和out,昨天就开始感受神奇的异步方法Async/await,当然顺路也看了眼多线程那几个.其实多线程异步相关的类单个用法和理解都不算困难,但是异步方法Async/awa ...

  5. 如何快速清除ZBrush画布中多余图像

    ZBrush是一款数字雕刻与绘画软件,它以强大的功能和直观的工作流程彻底改变了整个三维行业.它的简洁化.智能化和人性化的设计无不让众多用户所折服.刚接触它的用户可能会因为找不到相关命令或不熟悉而觉得它 ...

  6. [No00008D]腾讯通RTX联系方式批量获取

    公司用的RTX让我一直很不爽,QQ比RTX好多少为啥不让用,微信都有企业版了为啥还用腾讯通?终于今天发现唯一的好处是可以从服务器上拉公司妹子们的联系方式!!当然,我要这些联系方式,只是为了联tiao系 ...

  7. 新手学跨域之iframe

    https://segmentfault.com/a/1190000000702539 页面嵌套iframe是比较常见的,比如QQ相关业务页面的登录框一般都是iframe的.使用ifrmae跨域要满足 ...

  8. WPF简单模拟QQ登录背景动画

    介绍 之所以说是简单模拟,是因为我不知道QQ登录背景动画是怎么实现的.这里是通过一些办法把它简化了,做成了类似的效果 效果图 大体思路 首先把背景看成是一个4行8列的点的阵距,X轴Y轴都是距离70.把 ...

  9. Ubuntu 16.04 LAMP server 指南 - 配置 Apache2.4,PHP7,和MariaDB(而不是MySQL)

    翻译自:https://www.howtoforge.com/tutorial/install-apache-with-php-and-mysql-on-ubuntu-16-04-lamp/ 昨天在虚 ...

  10. 浏览器内核控制Meta标签说明文档【转】

    背景介绍 由于众所周知的情况,国内的主流浏览器都是双核浏览器:基于Webkit内核用于常用网站的高速浏览.基于IE的内核用于兼容网银.旧版网站.以360的几款浏览器为例,我们优先通过Webkit内核渲 ...