上一篇文章《[小北De编程手记] : Lesson 03 玩转 xUnit.Net 之 Fixture(上)》向大家介绍了xUnit.Net 共享数据的方式、Test Case的构造函数 & IDisposable.Dispose、Class级别的Fixture : IClassFixture。这一篇,我们接着讲解后面的内容,回顾一下本文要讨论的内容:

  • xUnit.Net 共享数据的方式(上)
  • Test Case的构造函数 & IDisposable.Dispose(上)
  • Class级别的Fixture : IClassFixture(上)
  • Collection级别的Fixture : ICollectionFixture(下)
  • 依赖注入以及输出日志(下)

(四)Collection级别的Fixture : ICollectionFixture

  回想一下上一篇中我们虚拟的应用场景。其中,关于问题三:“在应用程序级别统一创建数据库连接,Test Case 使用的数据库连接是同一份(或是统一管理的)”。 针对这一需求的实现,我们可以使用xUnit.Net的ICollectionFixture来实现。Collection级别的Fixture为我们提供了可以在多个测试类之间数据共享的能力。包含在同一个Collection之下的所有测试用例共享一份上下文数据。下面我们就来动手实现一下虚拟场景问题三之中的那个功能吧。

  Step 01:定义CollectionFixture(Demo中的DatabaseFixture

  与ClassFixture类似,自定义的CollectionFixture类,需要完成其构造函数 & IDisposable.Dispose的定义。而CollectionFixture类的构造和Dispose方法最终会在所有被标记使用该Collection的Test Class对应的Case执行前后被调用。即所有标记使用该Collection的测试方法运行之前会执行CollectionFixture的构造函数。所有标记使用该Collection的测试方法全部运行完毕之后会执行CollectionFixture的IDisposable.Dispose函数。我们定义一个DatabaseFixture,代码如下:

     public class DatabaseFixture : IDisposable
{
public object DatabaseContext { get; set; } public static int ExecuteCount { get; set; } public DatabaseFixture()
{
ExecuteCount++;
//初始化数据连接
} public void Dispose()
{
//销毁数据连接
}
}

  代码中,省略了得创建和销毁数据库连接的Code。只是使用了一个object类型的属性来表示数据库上下文,并且创建了一个静态变量ExecuteCount用于标记构造函数的使用频率。

  Step 02:定义Collection。

  对于ClassFixture而言,因为是基于Class级别的数据共享。so... ... xUnit.Net提供了直接用类继承IClassFixture接口并结合构造函数注入的方式优雅的实现了数据共享的功能。而对于Collection(一组类)的数据共享又该如何实现呢?先看一下示例代码:

     /// <summary>
/// 定义Collection名称,标明使用的Fixture
/// </summary>
[CollectionDefinition("DatabaseCollection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
}

  可以看到,我们定义了一个没有任何内容的类DatabaseCollection,该类的主要功能是定义了一个名字为“DatabaseCollection”(此名称可以和类名不同)的Collection,并指明该Collection所对应了Fixture。需要说明的是ICollectionFixture和IClassFixture一样是一个泛型标记接口(即没有任何需要实现的方法,只是用来标记对应的Fixture的类型)。而定义Collection代码中使用了CollectionDefinition标签,其定义如下:

 namespace Xunit
{
// Summary:
// Used to declare a test collection container class. The container class gives
// developers a place to attach interfaces like Xunit.IClassFixture<TFixture>
// and Xunit.ICollectionFixture<TFixture> that will be applied to all tests
// classes that are members of the test collection.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class CollectionDefinitionAttribute : Attribute
{
// Summary:
// Initializes a new instance of the Xunit.CollectionDefinitionAttribute class.
//
// Parameters:
// name:
// The test collection name.
public CollectionDefinitionAttribute(string name);
}
}

  被CollectionDefinition标记的Class在运行时会被xUnit.Net框架实例化为一个对象,该对象将用于标记其他的Class(有兴趣的话可以去GitHub看看xUnit.Net的源代码)。这里需要一个CollectionName作为参数,该参数将会用标记那些需要使用这个CollectionFixture的类。

  Step 03:用Collection来标记需要使用Fixtrue的测试类。

  xUnit.Net提供了Collection类,它的作用是用来指明测试类需要使用哪个Collection的。所有被标记了Collection测试类中的测试方法在其运行之前会调用一次对应的CollectionFixture的构造函数,所有方法运行完毕之后会调用一次CollectionFixture的IDisposable.Dispose函数(如果定义了的话)。值得注意的是测试类中依旧是通过构造函数注入的方式获取DatabaseFixture实例对象的。那么,我们来看一下Demo:

     [Collection("DatabaseCollection")]
public class SharedContext_CollectionFixture_01
{
private DatabaseFixture _dbFixture;
private ITestOutputHelper _output;
public SharedContext_CollectionFixture_01(ITestOutputHelper output, DatabaseFixture dbFixture)
{
_dbFixture = dbFixture;
_output = output;
} [Fact(DisplayName = "SharedContext.CollectionFixture.Case01")]
public void TestCase01()
{
_output.WriteLine("Execute CollectionFixture case 01!");
_output.WriteLine("DatabaseFixture ExecuteCount is : {0}", DatabaseFixture.ExecuteCount);
}
} [Collection("DatabaseCollection")]
public class SharedContext_CollectionFixture_02
{
private DatabaseFixture _dbFixture;
private ITestOutputHelper _output;
public SharedContext_CollectionFixture_02(DatabaseFixture dbFixture, ITestOutputHelper output)
{
_dbFixture = dbFixture;
_output = output;
} [Fact(DisplayName = "SharedContext.CollectionFixture.Case02")]
public void TestCase01()
{
_output.WriteLine("Execute CollectionFixture case 02!");
_output.WriteLine("DatabaseFixture ExecuteCount is : {0}", DatabaseFixture.ExecuteCount);
}
}

  Dome中定义了两个测试类,每个测试类中有一个测试方法,并用Collection指明了需要使用的Collection的名称。运行结果如下:

aaarticlea/png;base64,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" alt="" />

  可以看到,DatabaseFixture中的构造函数只是被执行了一次(IDisposable.Dispose也有相同的逻辑)。因此,实际的单元测试中,我们可以此处构建、管理数据库连接以节省资源的开销。

(五)依赖注入以及输出日志

  依赖注入是一个重要的OOP的法则,用来削减计算机程序的耦合问题。如今已成为许多不同领域软件框架的核心。关于依赖注入的概念,我想大家都不会陌生。这里我列出了几种依赖注入的主要方式:

  • 类型1 (基于接口): 可服务的对象需要实现一个专门的接口,该接口提供了一个对象,可以重用这个对象查找依赖(其它服务)。
  • 类型2 (基于setter): 通过JavaBean的属性(setter方法)为可服务对象指定服务。
  • 类型3 (基于构造函数): 通过构造函数的参数为可服务对象指定服务。

  这里谈到依赖注入,主要是想跟大家分享本人对xUnit.Net的设计理念的一点点理解。我在第一篇xUnit.Net系列文章《[小北De编程手记] : Lesson 01 玩转 xUnit.Net 之 概述》中曾提到过:xUnit.Net的一个改进就是在处理每个Test Case的初始化和清理方法时不再使用属性标签来标记,而是采用了构造函数和IDisposable.Dispose方法。这样做的一个直接好处就是使得依赖注入更容易的运用于xUnit.Net之中。前面例子中各个级别的Fixture,日志对象... ...都是通过依赖注入的方式简单,优雅的被我们所获取到。而对于日志对象,使用者也无需去关注它会输出到哪里(这个是由运行Case的工具<即Runner>决定),我们甚至不用关心它是如何被实例化。当使用不同的Runner运行Case时,Runner会针对xUnit.net的接口去实现一套属于自己的输出方式。下面我们来回顾一下输出接口以及它的使用方式:

 namespace Xunit.Abstractions
{
public interface ITestOutputHelper
{
void WriteLine(string message);
void WriteLine(string format, params object[] args);
}
}
  可以看到,ITestOutputHelper定义了两个输出方法,使用者可以通过下面的方式(构造函数注入)获取到运行时Runner提供的输出对象。而关于对象的实例化,管理等操作都是由运行Case的Runner(程序)来管理的。后面我会为大家讲解如何自定义Runner以及自定义Runner的意义所在,这里就不再赘述了。
     public class SharedContext_ClassFixture : IClassFixture<SingleBrowserFixture>
{
ITestOutputHelper _output;
public SharedContext_ClassFixture(ITestOutputHelper output , SingleBrowserFixture fixture)
{
_output = output;
}
#region Test case
[Fact(DisplayName = "SharedContext.ClassFixture.Case01")]
public void TestCase01()
{
_output.WriteLine("Log here");
}
#endregion Test case
}

  日志对象本身的使用很简单,单独拉出来讲是为了向大家展示xUnit.Net设计的工匠精神(更靠近设计者的意图)。很多框架级别的改变虽小(NUnit使用属性标签标记初始化方法,而xUnit.Net使用构造函数),但是用意颇深。so... ... 我们就慢慢体会吧~~~

这两篇文章主要和大家探讨了以下问题:

  • xUnit.Net 共享数据的方式
  • Test Case的构造函数 & IDisposable.Dispose
  • Class级别的Fixture : IClassFixture
  • Collection级别的Fixture : ICollectionFixture
  • 依赖注入以及输出日志

  关于的xUnit.Net Fixture的基本使用就先介绍到这里了,下一篇为大家讲解一下如何在Fixture的层面上扩展xUnit.Net的功能。到时候,让我们一起来看看xUnit.Net在可扩展性方面有何过人之处?

小北De系列文章:

  《[小北De编程手记] : Selenium For C# 教程

  《[小北De编程手记]:C# 进化史》(未完成)

  《[小北De编程手记]:玩转 xUnit.Net》(未完成)

Demo地址:https://github.com/DemoCnblogs/xUnit.Net

如果您认为这篇文章还不错或者有所收获,可以点击右下角的【推荐】按钮,因为你的支持是我继续写作,分享的最大动力!
作者:小北@North
来源:http://www.cnblogs.com/NorthAlan
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

[小北De编程手记] : Lesson 04 玩转 xUnit.Net 之 Fixture(下)的更多相关文章

  1. [小北De编程手记] : Lesson 03 玩转 xUnit.Net 之 Fixture(上)

    在使用xUnit.Net Framework构建单元测试或自动化测试项目的时候,无论是针对一些比较耗费资源的对象亦或是为了支持Test case预设数据的能力,我们都需要有一些初始化或是清理相关的动作 ...

  2. [小北De编程手记] : Lesson 01 玩转 xUnit.Net 之 概述

    谈到单元测试,任何一个开发或是测试人员都不会觉得陌生.我想大多数的同学也都是接触过各种单元测试框架.关于单元测试的重要性,应该不会有太多的质疑.这个系列,我向大家介绍一下xUnit.Net的使用.就让 ...

  3. [小北De编程手记] : Lesson 06 玩转 xUnit.Net 之 定义自己的FactAttribute

    xUnit.Net本身提供了标记测试方法的标签Fact和Theory.在前面的文章<Lesson 02 玩转 xUnit.Net 之 基本UnitTest & 数据驱动>中,也对它 ...

  4. [小北De编程手记] : Lesson 02 玩转 xUnit.Net 之 基本UnitTest & 数据驱动

    关于<玩转 xUnit.Net>系列文章,我想跟大家分享的不是简单的运行一下测试用例或是介绍一下标签怎么使用(这样的文章网上很多).上一篇<Lesson 01 玩转 xUnit.Ne ...

  5. [小北De编程手记] : Lesson 05 玩转 xUnit.Net 之 从Assert谈UT框架实践

    这一篇,本文会介绍一下基本的断言概念,但重点会放在企业级单元测试的相关功能上面.下面来跟大家分享一下xUnit.Net的断言,主要涉及到以下内容: 关于断言的概念 xUnit.Net常用的断言 关于单 ...

  6. [小北De编程手记] : Lesson 04 - Selenium For C# 之 API 上

    这一部分,我准备向大家介绍Selenium WebDriver的常用API,学习这部分内容需要大家最好有一些简单的HTML相关知识,本文主要涉及到以下内容: Selenium API:元素检查 Sel ...

  7. [小北De编程手记] : Lesson 08 - Selenium For C# 之 PageFactory & 团队构建

    本文想跟大家分享的是Selenium对PageObject模式的支持和自动化测试团队的构建.<Selenium For C#>系列的文章写到这里已经接近尾声了,如果之前的文章你是一篇篇的读 ...

  8. [小北De编程手记] : Lesson 07 - Selenium For C# 之 窗口处理

    在实际的自动化测试过程中,我们会遇见许多需要对窗口进行处理的情况.比如,点击删除某条信息的时候系统会显示一个Alert框.或者点击某个超链接时会在浏览器中打开一个新的页面.这一篇,来和大家分享一下Se ...

  9. [小北De编程手记] : Lesson 06 - Selenium For C# 之 流程控制

    无论你是用哪一种自动化测试的驱动框架,当我们构建一个复杂应用程序的自动化测试的时候.都希望构建一个测试流程稳定,维护成本较低的自动化测试.但是,现实往往没有理想丰满.而这一篇,我会为大家讲解我们在使用 ...

随机推荐

  1. git忽略以点开头的文件夹

    git忽略以点开头的文件夹 好像不是什么问题,可是我用的时候不好使,还是记录下 参考:http://www.oschina.net/question/1437985_2181276

  2. 【WP 8.1开发】解决摄像头翻转问题(RuntimeApp篇)

    昨天,我非常马虎地给大家说了有关处理物理摄像头翻转的话题,今天,还是这个话题,而且内容不差,只是为了完整性,顺便也提供了运行时API的版本,其实实现起来与SL框架版本差不多,毕竟这两个框架都有不少AP ...

  3. 史上最全github使用方法:github入门到精通

    [初识Github]首先让我们大家一起喊一句“Hello Github”.YEAH!就是这样. 原文 http://www.eoeandroid.com/thread-274556-1-1.htmlG ...

  4. 为大家分享一个 Ajax Loading —— spin.js

    我们在做Ajax 异步请求的时候,一般都会利用一个动态的 Gif 小图片来制作一个Ajax Loading ,以便增加用户体验. 今天在网上发现了一个 Spin.js ,该 js 脚本压缩后5k,可以 ...

  5. 深入理解CSS中的长度单位

    前面的话 本文分为绝对长度单位和相对长度单位来介绍CSS中的长度单位的主要知识 绝对长度单位 绝对长度单位代表一个物理测量 像素px(pixels) 在web上,像素px是典型的度量单位,很多其他长度 ...

  6. 拓扑排序(二)之 C++详解

    本章是通过C++实现拓扑排序. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑排序的代码说明 4. 拓扑排序的完整源码和测试程序 转载请注明出处:http://www.cnblogs. ...

  7. Java多线程系列--“基础篇”08之 join()

    概要 本章,会对Thread中join()方法进行介绍.涉及到的内容包括:1. join()介绍2. join()源码分析(基于JDK1.7.0_40)3. join()示例 转载请注明出处:http ...

  8. Yii2的深入学习--入口文件

    前一段时间,尝试去写一个 php 的简单框架,发现自己还欠缺很多,就暂时停掉了.准备先读完 Yii2 的源码,然后再去看完 laravel 的源码,最后再继续去写这个简单的 php 框架. 之后关于 ...

  9. Elasticsearch DSL中Query与Filter的不同

    Elasticsearch支持很多查询方式,其中一种就是DSL,它是把请求写在JSON里面,然后进行相关的查询. 举个DSL例子 GET _search { "query": { ...

  10. Javascript动画效果(四)

    Javascript动画效果(四) 前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下 ...