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

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

  2、给LearnUnitTest添加一个测试项目:在解决方案名称上右键=》添加=》新建项目=》VisualC#=》测试=》单元测试项目,项目名称叫LearnUnitTest_BankTest,将LearnUnitTest_Bank添加为LearnUnitTest_BankTest的引用项目,将测试项目LearnUnitTest_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.")

}

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

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-08-04 04:30:50

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

使用Xcode自带的单元测试

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

vs2013工具栏问题-vs2013 中工具栏为什么没有显示完全?请大侠指点

问题描述 vs2013 中工具栏为什么没有显示完全?请大侠指点 vs2013 中工具栏为什么没有显示完全?请大侠指点 解决方案 是不是工具拦宽度限制了. 解决方案二: 这是第三方的控件么?什么语言的,是不是嵌套在什么控件内了. 解决方案三: 将工具栏拖出来,看看后面有没有东西.如果拖出来之后,后面有东西,那说明工具栏宽度不够. 解决方案四: 工具栏宽度怎么设置?CMFCToolsBar里面好像没有这种方法

vs2013 局部变量窗口-vs2013 局部变量窗口背景变为黑色

问题描述 vs2013 局部变量窗口背景变为黑色 有谁知道为什么我的vs2013 局部变量窗口会这样,全部是黑色的了,调试时候很不方便.急急急.谢谢. 解决方案 看图就懂了吧.工具-选项 然后找这个界面就看到了!项前景为字体颜色,项背为背景颜色!你的应该背景颜色是黑色! 解决方案二: 我的是这样的,没有什么不对的吧?

不是很明白单元测试的作用,你们认为单元测试很有用吗?

问题描述 为什么这么多人使用单元测试呢?比如说[TestMethod]publicvoidTestStoredProcedure(){}自己写一个方法调用一下不就行了吗?为什么要单元测试呢?不是多此一举吗?还是有其它什么做用?望高人指点!!小弟感激不尽... 解决方案 解决方案二:1.要保证自己的代码是尽可能不出错的,所以要单元测试2.单元测试的方法往往是写在单独的类里,因为它和实际编写的代码逻辑上功能不同,自己写一个方法测试一下只适用于小的练习解决方案三:经典之作<代码大全>中的单元测试--

cunit 单元测试 keil-keil 工程可以添加Cunit单元测试框架吗?

问题描述 keil 工程可以添加Cunit单元测试框架吗? 请教高手,keil工程里面可以添加Cunit单元测试框架吗?怎么添加?

VS 2013之后,怎么对私有成员做单元测试

问题描述 在VS2010的时候,做单元测试非常便捷简单,在任何一个类.方法.属性上右击,在弹出菜单中,选择"创建单元测试".无论这个类.方法.属性是任何的保护级别(public,private,internal),都可以创建和进行测试.但在VS2013后,这个菜单选项没有了,然后我就另外安装了插件,还是MS的单元测试.但问题来了,只有public类下的方法.属性才能被创建单元测试.怎么办,在VS2013下,如何对私有的类.方法.属性进行单元测试? 解决方案 解决方案二:私有要做什么测试

Python的单元测试解析

  这篇文章主要介绍了Python的单元测试,代码基于Python2.x版本,需要的朋友可以参考下 如果你听说过"测试驱动开发"(TDD:Test-Driven Development),单元测试就不陌生. 单元测试是用来对一个模块.一个函数或者一个类来进行正确性检验的测试工作. 比如对函数abs(),我们可以编写出以下几个测试用例: 输入正数,比如1.1.2.0.99,期待返回值与输入相同; 输入负数,比如-1.-1.2.-0.99,期待返回值与输入相反; 输入0,期待返回0; 输入

单元测试与JUNIT

前言 考察目前关于单元测试和JUnit的文章,要么是介绍单元测试的理论,要么是通过一个简单的HelloWorld例子介绍工具的使用.这样很容易使读者在实际应用中无从下手.因为只有工具而没有理论的指导,将严重消弱了工具的作用,最终只能是沙滩建楼,达不到预期的目标:只有理论而没有工具的支持,也使得理论难有很好的着力点,最终使理论流于空泛.本文试图通过先讲解单元测试理论,进而将这些理论结合到JUnit的使用当中,最后通过对一个实用的.可以重用的时间操作类采用JUnit进行单元测试来完整阐述单元测试的思

c++-visual studio里对C++进行单元测试要怎么配置?

问题描述 visual studio里对C++进行单元测试要怎么配置? visual studio里对C++进行单元测试要怎么配置? 解决方案 请参见一下文章.前一个是第三方工具,后一个是vs2008以后vs的工具 http://www.vckbase.com/index.php/wv/1465 http://blog.csdn.net/b2b160/article/details/4245343 解决方案二: 你说的是打断点进行测试吗? 打断点测试就是打完断点 执行下一步就是F10 进到你想看