【学习笔记】C#中的单元测试

  

  周一老师讲完单元测试以后,感觉挺好玩,通过查资料和相关书籍学到了几种C#在VS2010的测试方法,跟大家分享下,图文并茂啊,有木有~~

 

 1.从被测试的代码中生成单元测试

  1.1创建C#控制台程序,命名为AddUnitText

    

  1.2然后先用一小段很简单的代码练习一下

 1  class Program
 2     {
 3         public int Add(int a, int b)
 4         {
 5             return a + b;
 6         }
 7         static void Main(string[] args)
 8         {
 9         }
10     }

1.3然后用下面的步骤创建单元测试

  (1)在Add方法体中,在右击菜单中选择创建单元测试,并为这个方法创建单元测试代码的基本框架

(2)点击确定后,系统自动生成单元测试代码,如下所示

 1 namespace AddText
 2 { 
 3     /// <summary>
 4     ///这是 ProgramTest 的测试类,旨在
 5     ///包含所有 ProgramTest 单元测试
 6     ///</summary>
 7     [TestClass()]
 8     public class ProgramTest
 9     {
10 
11 
12         private TestContext testContextInstance;
13 
14         /// <summary>
15         ///获取或设置测试上下文,上下文提供
16         ///有关当前测试运行及其功能的信息。
17         ///</summary>
18         public TestContext TestContext
19         {
20             get
21             {
22                 return testContextInstance;
23             }
24             set
25             {
26                 testContextInstance = value;
27             }
28         }
29 
30         #region 附加测试特性
31         // 
32         //编写测试时,还可使用以下特性:
33         //
34         //使用 ClassInitialize 在运行类中的第一个测试前先运行代码
35         //[ClassInitialize()]
36         //public static void MyClassInitialize(TestContext testContext)
37         //{
38         //}
39         //
40         //使用 ClassCleanup 在运行完类中的所有测试后再运行代码
41         //[ClassCleanup()]
42         //public static void MyClassCleanup()
43         //{
44         //}
45         //
46         //使用 TestInitialize 在运行每个测试前先运行代码
47         //[TestInitialize()]
48         //public void MyTestInitialize()
49         //{
50         //}
51         //
52         //使用 TestCleanup 在运行完每个测试后运行代码
53         //[TestCleanup()]
54         //public void MyTestCleanup()
55         //{
56         //}
57         //
58         #endregion
59 
60 
61         /// <summary>
62         ///Add 的测试
63         ///</summary>
64         [TestMethod()]
65         public void AddTest()
66         {
67             Program target = new Program(); // TODO: 初始化为适当的值
68             int a = 0; // TODO: 初始化为适当的值
69             int b = 0; // TODO: 初始化为适当的值
70             int expected = 0; // TODO: 初始化为适当的值
71             int actual;
72             actual = target.Add(a, b);
73             Assert.AreEqual(expected, actual);
74             Assert.Inconclusive("验证此测试方法的正确性。");
75         }
76     }
77 }

(3)ProgramTest.cs代码文件详讲

[TestMethod()]:说明了以下代码是一个测试用例

Int a = o; // TODO: 初始化为适当的值

int b = 0; // TODO: 初始化为适当的值

这两句是被测函数的输入参数,需要我们去修改它的值,也就是我们输入测试用例的地方。

double expected = 0; // TODO: 初始化为适当的值

double actual;

这两句话浅显易懂,前一句话是定义了期望值和对它进行初始化,后一句话是定义了实际值。默认

Assert.AreEqual(expected, actual);

Assert在这里可以理解成断言:在VSTS里做单元测试是基于断言的测试。

默认代码中Assert.Inconclusive 表明这是一个未经验证的单元测试。在实际的程序中可以注释掉。

(4)还可以在C#项目中自行创建单元测试项目,然后编写测试方法

单元测试的基本方法是调用被测代码的函数,输入函数的参数值,获取返回结果,然后与预期测试结果进行比较,如果相等则认为测试通过,否则认为测试不通过。

1、Assert类的使用

Assert.Inconclusive()    表示一个未验证的测试;

Assert.AreEqual()         测试指定的值是否相等,如果相等,则测试通过;

AreSame()            用于验证指定的两个对象变量是指向相同的对象,否则认为是错误

AreNotSame()        用于验证指定的两个对象变量是指向不同的对象,否则认为是错误

Assert.IsTrue()              测试指定的条件是否为True,如果为True,则测试通过;

Assert.IsFalse()             测试指定的条件是否为False,如果为False,则测试通过;

Assert.IsNull()               测试指定的对象是否为空引用,如果为空,则测试通过;

Assert.IsNotNull()          测试指定的对象是否为非空,如果不为空,则测试通过;

2、CollectionAssert类的使用

用于验证对象集合是否满足条件

StringAssert类的使用

用于比较字符串。

StringAssert.Contains

StringAssert.Matches

StringAssert.tartWith

3、附加测试属性的使用

默认都是被注释掉的,只要我们取消注释就可以使用了。这个功能的加入,很大程度上是为了增加测试的灵活性。具体的属性有:

[ClassInitialize()]在运行类的第一个测试前先运行代码

[ClassCleanup()]在运行完类中的所有测试后再运行代码

[TestInitialize()]在运行每个测试前先运行代码

[TestCleanup()]在运行完每个测试后运行代码

4、测试单元NUnit 声明

  1.AreEqual

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

    //判断结果与预期是否相等

     报告的结果如下:

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

   2.IsNull

    Assert.IsNull(object [, string message])
    Assert.IsNotNull(object [, string message])

    声明给的对象是否属于空

   3.AreSame

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

     声明是否同类型

   4.IsTrue

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

    判断返回条件是否为真

   5.Fail

    Assert.Fail([string message])

     测试立即失败。

 

2.下面是老师课上编写的程序

2.1这是测试代码:

   查找list[]中的最大值:int Largest(int list[], int length);

  首份实现代码如下:

int Largest(int list[], int length)

{

  int i,max;

   for(i = 0; i < (length – 1); i ++ )

  {  

     if(list[i] > max)

       { max=list[i]; }

  }

return max;

}

 

2.2编写程序:

 1 static void Main(string[] args)
 2         {
 3             int[] List = new int[3];//申明一个长度为3的数组保存录入的3个数
 4             int Max = 0;//保存最大值
 5             for (int i = 0; i < List.Length; i++)//循环数组
 6             {
 7                 Console.WriteLine("请输入第" + (i + 1) + "个数:");
 8                 List[i] = int.Parse(Console.ReadLine());//循环将录入的数字保存到数组
 9                 if (List[i] > Max)//判断当前数字是否大于最大值
10                 {
11                     Max = List[i];//将最大值赋值给Max
12                 }
13             }
14             Console.WriteLine("最大的数是:{0}",Max);//输出最大值
15             Console.ReadLine();
16         }

2.3在此测试的过程中发现无法对程序进行有效的测试,所以重新写了方法

 1 namespace MUnitText
 2 {
 3     public class LIU
 4     {
 5         /// <summary>
 6         /// 把返回的最大值放在list中
 7         /// </summary>
 8         /// <param name="list">一列整数</param>
 9         /// <returns>最大值返回给出的list中</returns>
10         public static int Largest(int[] list)
11         {
12             int i, max = Int32.MaxValue;
13             for (i = 0; i < list.Length - 1; i++)
14             {
15                 if (list[i] > max)
16                 {
17                     max = list[i];
18                 }
19             }
20             return max;
21         }
22     }
23 }

 

2.4创建单元测试

测试了多组数据以后,验证了老师上课提到的那些错误。

给一列数字[7,8,9].这个方法返回9.这是很符合常理的一个测试用例。但是,另外的测试用例如何想?

要写多少测试用例?

下面给出测试思想。

[7,8,9]—>9

  [8,9,7]—>9

  [9,7,8]—>9

  当有重复的最大的数字时候将会发生什么?

  [7,9,8,9]—>9

  因为只存在int类型,没有objects类型,所以你可能不会关系9返回的是什么类型。

  那么当只有1个数字的时候,它将会是什么?

  [1]—>1

  并且当出现负数时候又会发生什么情况:

  [-9,-8,-7]—>-7

  可以很很简单的看出来-7比-9大。

 

2.5编写测试方法

首先:通过Globally assembly cath调用using NUnit.Framework;

    NUnit框架提供我们需要的单元测试的功能。

    下一步,我们要定义一个类:每一个类包含着测试用例状态属性的注释。必须被声明为共有的,它必须有一个共有的,没有参数和构造器的。

    最终,这个测试类包含单个带有测试属性的测试方法。

 1  using NUnit.Framework;
 2 
 3     [TestFixture]
 4 
 5     public class TestSimple{
 6 
 7         [Test]
 8 
 9         public void LargestOf3(){
10 
11             Assert.AreEqual(9,Cmp.Largest(new int[]{8,9,7}));
12 
13             Assert.AreEqual(100,Cmp.Largest(new int[]{100,4,25}));
14 
15             Assert.AreEqual(64,Cmp.Largest(new int[]{1,64,38}));
16 
17         }
18 
19     }

 

测试了一上午,太不容易了,抓紧搞电梯了。。

posted @ 2014-03-08 11:59  摆摊的程序猿  阅读(10890)  评论(2编辑  收藏  举报