编写和执行单元测试

 

    编写和执行单元测试2.1.       使用NUnit2.2.       测试技巧:测试哪些内容

在这个部分中,主要包括两个方面的内容。如何编写NUnit测试代码(测试代码的格式),以及测试的基本原则(测试代码的内容)。

 

2.1.1.      构建单元测试

测试代码必须做以下几件事情:

1.    准备测试所需的条件

2.    调用要测试的方法

3.    验证被测方法的行为和期望的行为是否一致

4.    完成后清理各种资源

为了使用NUnit框架,需要做这些工作:

1.    使用using声明引用必要的NUnit类(并添加一个指向NUnitDll的引用)

2.    定义一个测试类,必须是Public的、包换一个public的没有参数的构造函数,并且在类定义上加上[TestFixture]attribute标记

3.    在测试类中包含用[Test]attribute标记的方法。

2.1.2.      有用的特性

在使用NUnit框架时,除了上面提到的[TestFixture][Test]特性外,还有一些有用的特性。灵活使用这些特性,将有助于提高测试代码开发的效率。各个特性及其作用请参见表2.1NUnit中的特性)。

2.1  NUint中的特性

1. Per-methodSetupTeardown

 

[Setup]:用此Attribute指定的方法用于环境的建立,NUnit在调用每个[Test]方法之前,将调用此特性标记的方法

[Teardown][Setup]一样,只是调用的时机是在每个[Test]方法完成后,用于环境的清理。

2. Per-class SetupPer-class Teardown

 

[TestFixtureSetup]以及[TestFixtureTearDown]特性和上述的[Setup]以及[Teardown]类似,只是其作用于整个[TestFixture]类而已。可以使用这两个特性标记的方法对整个test class设置和清理环境。

3. 使用Categories分类

 

[Category(“分类名”)]用于指定某个测试方法所属的“类型”。用此特性将各个测试方法分类后,可以在NUnit环境中指定需要执行的类型。

可以将此特性写在[Test]特性一起,如:

[Test, Category(“test_0001”)]

也可以分开两行:

[Test]

[Category(“test_0001”)]

Category还有一个Explicit属性,可以显式排除该Category的运行(除非在NUnit GUI中指定),写法如下:

[Category(“test_0001”, Explicit=true)]

4.测试预期的异常:ExpectedException

 

对测试而言有两种异常:

从测试代码抛出的异常

由于某个模块错误而引发的异常

第二种异常会在NUnit中捕获并作测试失败处理。而有时我们需要测试被测试方法是否抛出了期望的异常(例如,特意传入的错误参数),就可以用以下方法。

[ExpectedException(typeof(SomeException))]

或:[Test,ExpectedException(typeof(SomeException))]

注意,一旦期望的异常抛出了,剩余的代码就会被跳过。

5.临时忽略一些测试:Ignore

 

当你写了一些测试代码,但并不打算马上执行时,可以使用Ignore特性。

[Test,Ignore(“message”)]

这个测试将被跳过,并且在NUnit GUI中给出黄色的状态栏。

 

2.1.3.      使用NUnit断言

断言是单元测试最基本的组成部分,NUnit程序库以Assert类的静态方法的形式提供了不同形式的断言,这些断言都列在表2.2NUnit中的断言)中。

2.2 NUnit中的断言

1. AreEquals   检查两个值是否相等

 

Assert.AreEqual(expected, actual [,string message])

expected: 期望值

actual: 被测代码产生的实际值

message: 可选的参数,表示错误的报告消息

PS:在浮点数的比较中还需要提供一个参数表示可以接受的误差

Assert.AreEqual(expected, actual, tolerance [, string message] )

其中tolerance可以写成如0.01,表示精确到小数点后两位

2. IsNull   检查一个Object是否为NULL

 

Assert.IsNull(object [, string message])

Assert.IsNotNull(object [, string message])

message: 可选的参数,错误报告消息

3. AreSame   检查是否引用同一个对象

 

Assert.AreSame ( expected, actual [, string message] )

message: 可选的参数,错误报告消息

4. IsTrue   检查给定的二元条件是否为真

 

Assert.IsTrue ( bool condition [, string message] )

message: 可选的参数,错误报告消息

5. Fail   使测试立即失败

 

Assert.Fail( [ string message] )

message: 可选的参数,错误报告消息

NUnit中,还可以自定义断言,用于在特定条件下的检查

 

有六个值得测试的具体部位,它们能够提高你的测试水平。这六个方面可以统称为Right_BICEP:

l        Right : 结果是否正确(Right

l        B    : 边界(boundary)条件是否正确

l        I    : 是否可以检查反向(inverse)关联

l        C    : 是否可以使用其它方法来跨检查(cross-check)结果

l        E    : 错误条件(error condition)是否可以重现

l        P    : 性能(performance)方面是否满足条件

2.2.1.      结果是否正确

对于测试而言,首要的也是最明显的任务就是查看所期望的结果是否正确-验证结果。

这里的结果是指确认代码所做的和你的期望是一致的。

2.2.2.      边界条件

边界条件包括许多内容,将在下一节(2.3.边界条件)中集中描述。

2.2.3.      检查反向关联

对一些方法,可以用反向的逻辑关系来验证它们。例如,为了检查某条记录是否成功的插入了数据库,可以通过查询这条记录来验证,等等。

值得注意的是,当同时编写原方法和它的反向测试时,一些BUG可能会被两者中都有的错误所掩饰。在可能的情况下,应该用不同的原理来实现反向测试。

2.2.4.      实现交叉检查

通常,计算一个量有一种以上的算法。可以使用那些没有在程序中用到的算法来交叉检查结果--这个算法可能比较慢或不太灵活,但用于交叉检查将非常有效。

2.2.5.      强制产生错误条件

应该能够通过强制引发真实世界中的错误-网络断开、程序崩溃等-来测试代码如何处理这些问题。简单的无效参数之类的错误会很简单,但要模拟复杂的错误就需要一些特殊的技术。在下面的文字中,将讨论使用Mock技术来解决如何强制产生错误的问题。

2.2.6.      性能特性

这里的性能特征并不是指程序的性能本身,而是指性能的那种“随着规模增大,问题越来越复杂”的趋势。我们应该使用一个性能特性的快速回归测试,避免出现某些修改使得程序变得很慢却无法对其进行定位的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值