转自:http://www.cnblogs.com/confach/archive/2005/06/20/177817.html
单元测试是在软件开发过程中要进行的最低级别的测试活动,在单元测试活动中,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
在一种传统的结构化编程语言中,比如C,要进行测试的单元一般是函数或子过程。在象C++这样的面向对象的语言中, 要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数,还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。
单元测试不仅仅是作为无错编码一种辅助手段在一次性的开发过程中使用,单元测试必须是可重复的,无论是在软件修改,或是移植到新的运行环境的过程中。因此,所有的测试都必须在整个软件系统的生命周期中进行维护。
经常与单元测试联系起来的另外一些开发活动包括代码走读(Code review),静态分析(Static analysis)和动态分析(Dynamic analysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作,来提供执行跟踪,时间分析,以及测试覆盖度方面的信息。
用NUnit进行单元测试
前一段时间,有人问我在.NET里如何进行TDD开发.这个问题促使我想对NUnit做一个详细的介绍.因为我们大家都知道NUnit是在.NET进行TDD的利器.
如果你已经知道很多关于NUnit的应用,请指出我的不对之处和提出一些建议,使本文更加完善.如果你对NUnit还不是很了解的话,我建议你还是阅读一下.
1. TDD的简介
2.NUnit的介绍
2.1 NUnit的介绍
图2 NUnit运行的另外一个效果
- 绿色 描述目前所执行的测试都通过
- 黄色 意味某些测试忽略,但是这里没有失败
- 红色 表示有失败
- 状态.说明了现在运行测试的状态。当所有测试完成时,状态变为Completed.运行测试中,状态是Running: <test-name> (<test-name>是正在运行的测试名称)。
- Test Cases说明加载的程序集中测试案例的总个数。这也是测试树里叶子节点的个数。
- Tests Run 已经完成的测试个数。
- Failures 到目前为止,所有测试中失败的个数.
- Time 显示运行测试时间(以秒计)
- New Project允许你创建一个新工程。工程是一个测试程序集的集合。这种机制让你组织多个测试程序集,并把他们作为一个组对待。
- Open 加载一个新的测试程序集,或一个以前保存的NUnit工程文件。
- Close关闭现在加载的测试程序集或现在加载的NUnit工程。
- Save 保存现在的Nunit工程到一个文件。如果正工作单个程序集,本菜单项允许你创建一个新的NUnit工程,并把它保存在文件里。
- Save As允许你将现有NUnit工程作为一个文件保存。
- Reload 强制重载现有测试程序集或NUnit工程。NUnit-Gui自动监测现加载的测试程序集的变化。
- Recent Files 说明5个最近在NUnit中加载的测试程序集或NUnit工程(这个列表在Windows注册表,由每个用户维护,因此如果你共享你的PC,你仅看到你的测试)。最近程序集的数量可以使用Options菜单项修改,可以访问Tool主菜单。
- Exit退出。
- View菜单有以下内容:
- Expand一层层扩展现在树中所选节点
- Collapse 折叠现在树中选择的节点
- Expand All递归扩展树中所选节点后的所有节点
- Collapse All递归折叠树中所选节点后的所有节点
- Expand Fixtures扩展树中所有代表测试fixture的节点。
- Collapse Fixtures 折叠树中所有代表测试fixture的节点。
- Properties 显示树中现所选节点的属性。
- Tools 菜单由这些项:
- Save Results as XML作为一XML文件保存运行测试的结果。
- Options让你定制NUnit的行为。
- Errors and Failures 窗口显示失败的测试。在我们的例子里,这个窗口是空。
- Tests Not Run 窗口显示没有得到执行的测试。
- Console.Error 窗口显示运行测试产生的错误消息。这些此消息是应用程序代码使用Console.Error输出流可以输出的。
- Console.Out窗口显示运行测试打印到Console.Error输出流的文本消息。
2.2 一些常用属性
- Test Fixture
- Test
TestFixtureAttribute
- 必须是Public,否则NUnit看不到它的存在.
- 它必须有一个缺省的构造函数,否则是NUnit不会构造它.
- 构造函数应该没有任何副作用,因为NUnit在运行时经常会构造这个类多次,如果要是构造函数要什么副作用的话,那不是乱了.
1 using System;
2 using NUnit.Framework;
3 namespace MyTest.Tests
4{
5
6 [TestFixture]
7 public class PriceFixture
8 {
9 //
10 }
11}
12
TestAttribute
public void MethodName()
1using System;
2using NUnit.Framework;
3
4namespace MyTest.Tests
5{
6 [TestFixture]
7 public class SuccessTests
8 {
9 [Test] public void Test1()
10 { /* */ }
11 }
12}
13
14
一般来说,有了上面两个属性,你可以做基本的事情了.
另外,我们再对如何进行比较做一个描述。
在NUnit中,用Assert(断言)进行比较,Assert是一个类,它包括以下方法:AreEqual,AreSame,Equals, Fail,Ignore,IsFalse,IsNotNull,具体请参看NUnit的文档。
3.如何在.NET中应用NUnit
第1步.为测试代码创建一个Visual Studio工程。
图 4-1: 创建第一个NUnit工程
第2步.增加一个NUnit框架引用
图 4-2: 增加一个 NUnit.framework.dll 引用到工程
第3步.为工程加一个类.
2using NUnit.Framework;
3
4namespace NUnitQuickStart
5{
6 [TestFixture]
7 public class NumersFixture
8 {
9 [Test]
10 public void AddTwoNumbers()
11 {
12 int a=1;
13 int b=2;
14 int sum=a+b;
15 Assert.AreEqual(sum,3);
16 }
17 }
18}
19
第4步.建立你的Visual Studio 工程,使用NUnit-Gui测试
第5步.编译运行测试.
4.其他的一些核心概念
SetUp/TearDown 属性
2using NUnit.Framework;
3
4namespace NUnitQuickStart
5{
6 [TestFixture]
7 public class NumersFixture
8 {
9 [Test]
10 public void AddTwoNumbers()
11 {
12 int a=1;
13 int b=2;
14 int sum=a+b;
15 Assert.AreEqual(sum,3);
16 }
17 [Test]
18 public void MultiplyTwoNumbers()
19 {
20 int a = 1;
21 int b = 2;
22 int product = a * b;
23 Assert.AreEqual(2, product);
24 }
25
26 }
27}
28
我们仔细一看,不对,有重复的代码,如何去除重复的代码呢?我们可以提取这些代码到一个独立的方法,然后标志这个方法为SetUp 属性,这样2个测试方法可以共享对操作数的初始化了,这里是改动后的代码:
2using NUnit.Framework;
3
4namespace NUnitQuickStart
5{
6 [TestFixture]
7 public class NumersFixture
8 {
9 private int a;
10 private int b;
11 [SetUp]
12 public void InitializeOperands()
13 {
14 a = 1;
15 b = 2;
16 }
17
18 [Test]
19 public void AddTwoNumbers()
20 {