VS2013 单元测试(使用VS2013自带的单元测试)

本文是官方文档的学习笔记,官方文档在这里

1、打开VS3013,随便建一个解决方案,比如叫:UnitTest,建一个类库项目UnitTest_Bank,该项目中添加一个BankAccount类,这个类及类中的方法就是我们要测试的对象。

2、给UnitTest添加一个测试项目:在解决方案名称上右键=》添加=》新建项目=》VisualC#=》测试=》单元测试项目,项目名称叫UnitTest_BankTest,将UnitTest_Bank添加为UnitTest_BankTest的引用项目,将测试项目UnitTest_BankTest里默认生成的类重命名为BankAccountTest。

对于BankAccountTest类,类上有注解TestClass,方法上有注解TestMethod。可以在这类文件里添加其他类和方法,供测试方法使用。

首个测试:

3、现在我们测试BankAccount类的Debit方法,我们预先确定此次测试要检查如下方面:

  a、如果信用余额(credit amount)比账户余额大,该方法就抛异常ArgumentOutOfRangeException

  b、如果信用余额小于0也抛异常

  c、如果a和b都满足,该方法会从账户余额里减去amount(函数参数)

  注意:由a、b、c可以看邮BankAccount类中的Debit方法最后一行应该是-=,而不是+=——当然了,这个是故意留下的bug,而不是微软的失误,就等着在这次测试中把它测出来,然后修正掉。

  

  在测试类里添加如下方法测试Debit方法:

// unit test code
[TestMethod]
public void Debit_WithValidAmount_UpdatesBalance()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = 4.55;
    double expected = 7.44;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);

    // act
    account.Debit(debitAmount);

    // assert
    double actual = account.Balance;
    Assert.AreEqual(expected, actual, 0.001, "Account not debited correctly");
}

  

测试方法的要求:

  必须要有TestMethod注解,返回类型为void,不能有参数。

经过测试,我们发现了bug,把+=改为-=即可。

使用单元测试改善代码:

  依然是测试Debit,本次测试想完成以下意图:

  a、如果credit amount(指的应该就是debit amount)比balance大,方法就抛ArgumentOutOfRangeException

  b、如果credit amount比0小,也抛ArgumentOutOfRangeException异常

(1)创建测试方法

首次尝试创建一个测试方法来处理上述问题:

代码:

//unit test method
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = -100.00;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);

    // act
    account.Debit(debitAmount);

    // assert is handled by ExpectedException
}

注意这个方法:Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange,意思是:当debit amount小于0时,本次测试应该会导致被测试的方法抛出ArgumentOutOfRange异常,否则本次测试就失败了,没有达到期望,需要修改Debit代码以达成本次测试期望——正所谓TDD开发。

我们使用了ExpectedExceptionAttribute特性来断言期望的异常应当被抛出。除非方法抛出ArgumentOutOfRangeException异常,否则该特性就会导致测试失败(要注意本次测试的意图)。用正的和负的debitAmount运行这个测试,然后临时把被测试的方法(Debit方法)修改一下:当demit amount小于0时抛出一个ApplicatinException。捣腾完这些,发现本次测试基本没什么问题。

为了测试debit amount 大于balance的情形,我们做下面几个操作:

  a、创建一个新的测试方法名叫    Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange

  b、从上一个测试方法

Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange

复制方法体到本测试方法

  c、把debitAmount设置为一个比balance大的值

(2)运行测试方法

用不同的debitAmount值运行Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange

和 Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange

然后运行三个测试,这样我们最开始设定的三个cases都被覆盖了。

(3)继续分析

后面两个测试方法Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange

和Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange

有些问题:两个测试运行的时候根据抛出的异常,你不知道是谁抛出的,靠ExpectedException特性做不到这件事。

可以这样修改:

在类里定义两个常量:

// class under test
public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount less than zero";

// method under test
// ...
    if (amount > m_balance)
    {
        throw new ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
    }

    if (amount < 0)
    {
        throw new ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage);
    }
// ...

(4)重构测试方法

首先,移除ExpectedException特性。取而代之的处理是:我们捕获异常,来核实是在哪种条件下抛出的。

修改一下Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange

方法:

[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = 20.0;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
    // act
    try
    {
        account.Debit(debitAmount);
    }
    catch (ArgumentOutOfRangeException e)
    {
        // assert
        StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
    }
}

(5)再次测试,再次重写,再次分析

当我们用不的参数再次运行测试方法Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange

的时候,会遇到下面一些问题:

1、如果我们使用一个比balance大的debitAmount运行,产生的测试结果是所期望的。

2、如果使用了一个debitAmount运行,使得assert 断言失败了(比如在Debit方法的某一行返回了一个非期望的异常),也没什么问题,在本测试的情理之中。

3、如果debitAmount是有效的(比0大比balance小)会发生什么呢?没有异常抛出,断言也不会失败,测试方法通过了。——这不是我们想要的,注意我们此次的测试初衷:要么断言成功,要么断言失败,如果压根进入不了断言代码,只能说明测试方法写的问题!

为了解决这个问题,我们在测试方法的最后一行加入一个Fail断言,来处理没有异常发生的情况:没有异常发生,就说明此次测试没有达到期望!

但是修改好再次运行,会发现如果所期望的异常被捕获了,测试总会失败。为了解决这个问题,我们在StringAssert之前加一个return。

最终我们的Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange

方法如下:

[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = 20.0;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
    // act
    try
    {
        account.Debit(debitAmount);
    }
    catch (ArgumentOutOfRangeException e)
    {
        // assert
        StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
        return;
    }
    Assert.Fail("No exception was thrown.")
}

最终我们让测试代码变得更加强健,但更重要的是,在这个过程中,我也们也改善了被测试的代码——这才是测试的最终目的。

微软接下来讲的是测试驱动开发。链接如下:

测试驱动开发

本文源码:UnitTest.rar

时间: 2024-08-25 10:56:31

VS2013 单元测试(使用VS2013自带的单元测试)的相关文章

IOS-使用XCODE自带的单元测试UnitTest

什么是单元测试? 一听到单元测试这个词感觉很高端,其实单元测试就是为你的方法多专门写一个测试函数.以保证你的方法在不停的修改开发中.保持正确.如果出错,第一时间让你知道,这样从最小单位开始监控来保证软件的质量. 什么时候用到单元测试: 1.写完代码以后:想要验证一下自己写的代码是否有问题. 2.写代码之前:就是写代码之前所有的功能分模块的设计好,测试通过了再写.(我反正是没用过). 3.修复某个bug后:一般修复完某个bug,为了确保修复是成功的,会写测试. 怎么写单元测试 好像废话有点多了,还

使用Xcode自带的单元测试

今年苹果推出的iOS8和Swift的新功能让人兴奋.同时,苹果对于Xcode的测试工具的改进却也会影响深远.现在我们来看下XCTest,Xcode内置的测试框架.以及,Xcode6新增的XCTestExpectation和性能测试. 现在Xcode项目已经支持out-of-the-box的测试.比如,创建一个新的iOS应用项目后,项目会自动配置两个顶层的group:一个是"应用名称"的group,一个是"项目名称Test"group.对应于这两个顶层的group的是

【vs2013】使用VS2013打包程序

如何用 VS 2013 打包 程序? 摘自:http://www.zhihu.com/question/25415940 更多请见摘自. 答案就在这里,想要你的exe独立运行在XP中:1.将平台工具集选择为"Visual Studio 2013 - Windows XP (v120_xp)".2.将运行库选择为 [多线程 /MT ]或[多线程调试 /MTd].3.当然如果使用了MFC,同理的要设置[在静态库中使用MFC].

学习MVC之租房网站(四)-实现Service层并进行单元测试

在上一篇<学习MVC之租房网站(三)-编写Eneity类并创建数据库>中,记录了编写Eneity类并采用CodeFirst的方式创建数据库的过程,接下来就到了Service层的实现了,并且在开始后续工作前,首先进行充分的单元测试. 长久以来,一直为写出很多bug而苦恼,这儿用过单元测试后,惊喜地发现,这不正是保证代码质量的好方法嘛,虽然会耗费额外的时间,但决定以后要把单元测试运用到工作和学习的实践中. 一.实现Service层 1. 为了减少模块.层之间的耦合,在Service层上面增加了IS

如何在VS2013中进行Boost单元测试

对于如何在VS2013中进行Boost单元测试,这方面资料太少.自己也因此走了不少弯路.下文将会阐述一下如何在VS2013中进行Boost单元测试. 在开始Boost单元测试之前,我们需要先安装VS2013插件Boost Unit Test Adapter (Update 3) 以及编译Boost库.Boost Unit Test Adapte可以在VS2013中的“工具->扩展与更新”中找到并安装.对于Boost Unit Test Adapter所支持的Boost库版本请参考网页.我选择的是

Visual Studio 2005 自带单元测试

一 单元测试简介 单元测试是代码正确性验证的最重要的工具,也是系统测试当中最重要的环节.也是唯一需要编写代码才能进行测试的一种测试方法.在标准的开发过程中,单元测试的代码与实际程序的代码具有同等的重要性.每一个单元测试,都是用来定向测试其所对应的一个单元的数据是否正确. 单元测试是由程序员自己来完成,最终受益的也是程序员自己.可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试.执行单元测试,就是为了证明这段代码的行为和我们期望的一致. 单元测试还具有一下几个好处:  能

带着大家走进iOS单元测试世界

摘要 今天给大家着重介绍一下单元测试,很多人可能没有听过单元测试或者是只是听说过,而没有实际的去实践过,没有关系,今天就给大家普及普及这方面的知识,并且带着大家进行实践,切身体验一下单元测试好处. 如果一个移动端的开发人员对单元测试不去重视他,这种开发人员往往表现一种"无知的自信",总觉得自己写的代码质量很高,直到一次次虫子(Bug)把自己咬的头破血流时,出现重大问题时,才发现原来自己的代码已经到了剪不断理还乱的状态,而每一次修改一个bug,都需要走一遍"墨镜迷宫"

基于静态分配的数组的顺序表(兼具Boost单元测试)

首先,我们来搞明白几个概念吧(参考自网站数据结构及百度百科). 线性表 线性表是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表的逻辑结构简单,便于实现和操作.在实现线性表数据元素的存储方面,一般可用顺序存储结构和链式存储结构两种方法. 顺序表 用顺序存储方法存储的线性表简称为顺序表(Sequential List).顺序表的存储方法是把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元

在Visual Studio 2013 中使用C++单元测试

本文主要介绍在Visual Studio 2013中对代码进行单元测试的方法,包含了两方面的内容:对已有的Dll文件进行单元测试,以及对已有的源文件进行单元测试. 1. VS2013对DLL文件的单元测试 对已有的dll文件进行单元测试. 首先,新建一个待测试的DLL项目CalculationDll,共包含3个文件: CalculationDll.cpp.CalculationDll.h.CalculationDll.def. 然后,新建了一个单元测试项目CalculationTest. 继而,