zoukankan      html  css  js  c++  java
  • 【学习笔记】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     }

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

  • 相关阅读:
    关于网络安全攻防演化博弈的研究小议
    入侵检测技术框架总论【课题笔记】
    态势提取的前置基础技术:数据集成、数据规约、数据融合
    网络安全态势感知框架小议
    入侵检测基本准则(Basic principles of intrusion detection)【v1.0】
    Research on collection technology and countermeasure technology of system behavior log for HIDS,面向HIDS的日志采集技术与对抗技术研究
    Tomcat(二):Tomcat处理一个Http请求
    Tomcat(一):Tomcat启动时加载web.xml
    SpringMVC(十七):Web.xml初始化流程源码分析
    设计模式(九)责任链(Chain of Responsibility)
  • 原文地址:https://www.cnblogs.com/huiyuan/p/ceshi.html
Copyright © 2011-2022 走看看