VS2010中的自动化测试(2)——单元测试

概述

在软件开发过程中,我们可能会有很多的模块,而每个模块有可能又由许多函数组成。当我们的系统发生错误时,我们必须定位发生错误的模块,然后精确到模块中某个具体的函数中,而这工作往往又是非常浪费时间和生产效率的,如果系统越复杂,那么定位错误的成本将越高。所以在每个函数集成进模块时,必须通过严格的单元测试来验证。

在VS2010中我们可以为我们的函数自动生成单元测试,无论它是否是public或者的private的。所有用于单元测试的类和函数都被定义在Microsoft.VisualStudio.TestTools.UnitTesting这个命名空间中。

 

创建Unit Test

我们先创建一个被测试的类库工程,名字叫TestLibrary,然后添加如下代码:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestLibrary
{
    public class Class1
    {
        public double CalculateTotalPrice(double quantity)
        {
            double totalPrice;
            double unitPrice;
            
            unitPrice = 16.0;

            totalPrice = unitPrice * quantity;
            return totalPrice;
        }

        public void GetTotalPrice()
        {
            int qty = 5;
            double totalPrice = CalculateTotalPrice(qty);
            Console.WriteLine("总价: " + totalPrice);
        }

    }
}
复制代码

 

然后我们在需要单元测试的函数上鼠标右键,如图会有个Create Unit Tests选项。

Untitled

 

点击该选项后,就会弹出如下窗口,该窗口会显示出该工程和类中所有的函数,这里我们可以选择我们要进行单元测试的函数。

Capture

 

我们选择CalculateTotalPrice和GetTotalPrice两个函数,点击OK,然后输入测试工程的名字点Create。(我们可以在Output project选项中选择一个以创建的工程或者创建一个新的测试工程)我们的单元测试代码就自动创建好了,当然,这个自动创建的测试代码并没有完成的,而是为我们的单元测试搭好了框架而已。自动生成的代码如下:

复制代码
using TestLibrary;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace TestProject1
{
    
    
    ///<summary>
    ///This is a test class for Class1Test and is intended
    ///to contain all Class1Test Unit Tests
    ///</summary>
    [TestClass()]
    public class Class1Test
    {


        private TestContext testContextInstance;

        ///<summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        ///<summary>
        ///A test for CalculateTotalPrice
        ///</summary>
        [TestMethod()]
        public void CalculateTotalPriceTest()
        {
            Class1 target = new Class1(); // TODO: Initialize to an appropriate value
            double quantity = 0F; // TODO: Initialize to an appropriate value
            double expected = 0F; // TODO: Initialize to an appropriate value
            double actual;
            actual = target.CalculateTotalPrice(quantity);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

        ///<summary>
        ///A test for GetTotalPrice
        ///</summary>
        [TestMethod()]
        public void GetTotalPriceTest()
        {
            Class1 target = new Class1(); // TODO: Initialize to an appropriate value
            target.GetTotalPrice();
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }
    }
}
复制代码

 

其实,我们可以在创建单元测试时适当控制自动生成的测试代码,如图我们点击Setting按钮。

Capture2

 

这时会弹出如下图的窗口

Capture3

 

在该对话框中,我们可以对生成的测试文件、测试类以及测试方法自定义名称。

 

  • Mark all test results Inconclusive by default:选中该复选框可为每个测试方法提供 Assert.Inconclusive() 语句作为占位符 Assert。清除该复选框可消除占位符 Assert。
  • Enable generation warnings:在测试函数创建中如果遇到任何的错误,代码生成器会将这些错误信息以注释的形式写在生成的代码中。
  • Globally qualify all types:这个选项是用来解决多个类可能有相同名字的函数问题,单元测试文件可能包含有多个类的测试函数,所以有可能会有同名的冲突,所以为了区分开同名的函数,会在测试命名中添加namespaces。
  • Enable documentation comments:选中此复选框可为每个测试方法提供占位符注释。清除该复选框可消除占位符注释。
  • Honor InternalsVisibleTo Attribute:选中该复选框可使标为 Friend 或 Internal 的方法被视为公共方法(推荐)。清除该复选框则需要使用专用访问器测试这些方法。

 

此外还可以注意到自动生成的代码中有一些被注释的方法,这些方法我们可以选择使用:

 

  1. [ClassInitialize()]标记的方法可在运行类中的第一个测试前运行代码。
  2. [ClassCleanUp()]标记的方法可在运行完类中的所有测试后运行代码。
  3. [TestInitialize()]标记的方法可在运行每个测试前运行代码。
  4. [TestCleanUp()]标记的方法可在运行完每个测试后运行代码。

 

Assert语句

Assert语句用来比较从方法返回来的值和期望值,然后返回pass或者fail的结果。如果在一个测试方法中有多个Assert的话,那么这个测试方法要通过测试必须让所有的Assert方法通过,不然,其中有一个fail,那么这个Case就会fail。如果我们的单元测试中没有任何的Assert语句,那么它的结果始终是pass的。

Assert类有许多进行比较的方法,此外还有StringAssertsCollectionAssert类也可用于单元测试中,具体的我们可以参加MSDN上的介绍了。

 

下面我们修改一下CalculateTotalPriceTest()这段测试代码,并将最后的Assert.Inconclusive注释:

复制代码
        [TestMethod()]
        public void CalculateTotalPriceTest()
        {
            Class1 target = new Class1(); 
            double quantity = 10F; 
            double expected = 160F; 
            double actual;
            actual = target.CalculateTotalPrice(quantity);
            Assert.AreEqual(expected, actual);
            //Assert.Inconclusive("Verify the correctness of this test method.");
        }
复制代码

 

最后我们可以在该函数中,右键鼠标然后点击Run Tests运行测试一下我们的代码。我们就可以在Test Results窗口中看见我们运行的结果。

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值