带你玩转Visual Studio——单元测试

原创 2016年06月02日 00:21:16

上一篇文章带你玩转Visual Studio——性能分析与优化讲了找出性能瓶颈和性能优化相关的技能,在大型企业项目的开发中,性能是固然重要的,而另一个过程——测试也是必不可少的。测试有很多的各类:功能测试、系统测试、白盒测试、黑盒测试、单元测试,在这些测试中单元测试是程序员最经过遇到的。


什么是单元测试

所谓单元测试(unit testing),就是对软件中的最小单元进行检查和验证,其一般验证对象是一个函数或者一个类。

对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里或C++里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。

单元测试的作用:

  • 确定自己的代码功能和逻辑的正确性;
  • 发现问题并及早地改进一些不当的设计;
  • 对于一些被依赖信很强的代码作修改时,确保逻辑的正确才能不影响其它模块的功能;
  • 更好地管理和保存测试代码,以便下次代码修改后可方便地进行Debugging;


VC++的单元测试

我们继续使用上一章带你玩转Visual Studio——性能分析与优化的案例和代码。经过上一文的优化,我们的代码性能是提高了,但每个函数是否正确无误并没有经过验证。现在就用单元测试进行椎一下。

使用UnitText工程

1、 在Solution中添加一个UnitTest的项目


添加UnitTest工程
图1: 添加UnitTest工程

,关于多工程的开发,请参考《带你玩转Visual Studio——带你多工程开发

2、这时会自动帮我们创建一个unittest1.cpp并生成部分初始代码。(如果没有自动生成也可自己手动添加.cpp文件并编写测试代码)

工程目录
图2: 工程目录

3、根据给定的初始代码框架,编写测试代码

#include "stdafx.h"
#include "CppUnitTest.h"
#include "Prime.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest
{
    TEST_CLASS(UnitTest1)
    {
    public:

        // 测试100以内的质数
        TEST_METHOD(TestPrime)
        {
            int primes[] = 
            {
                2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
                31, 37, 41, 43, 47, 53, 59, 61, 67,
                71, 73, 79, 83, 89, 97/*,   101, 103, 107*/ 
            };

            int n = sizeof(primes) / sizeof(primes[0]);
            for (int  i = 0; i < n; i++)
            {
                Assert::AreEqual(IsPrime(primes[i]), true);
            }
        }

        TEST_METHOD(TestCalculateSum)
        {
            // 测试1到n的整数之和
            Assert::AreEqual((int)CalculateSum(4), 10);
            Assert::AreEqual((int)CalculateSum(6), 21);
            Assert::AreEqual((int)CalculateSum(10), 55);
            Assert::AreEqual((int)CalculateSum(100), 5050);
        }

    };
}

说明:
TEST_METHOD是一个测试宏,每一个宏对应一个测试单元。大括号({})内的内容是这个测试单元的测试代码。

4、进行单元测试
选择Test->Windows->Test Explorer菜单,打开单元测试的工具窗口

测试资源管理器
图3: 测试资源管理器窗口

测试方法:
(1).选择其中的一个或多个单元,右键鼠标->Run Selected Tests,
(2).点击”Run All”,测试所有单元。

如果测试成功,Output窗口会有类似如下的提示:

========== Run test finished: 2 run (0:00:00.7490429) ==========

测试项的标记色会变成绿色:

测试成功标记色
图4: 测试成功标记色


ManagedTest工程

我们在图1中可以看到有两个跟测试相关的工程,一个是Native Unit Test Project(上面已经讲了),一个是Managed Test Project。其实这两个工程都可用来进行单元测试,Managed Test Project提供了更全面的功能,如对类的开始初始化和结束销毁的处理,每个测试方法前后进行初始化和销毁处理等。而Unit Test Project相当于是对Managed Test Project的一种封装,只提供最简单、最常用的测试功能,而帮我们默认处理很多繁琐的工作。在VS2013及之前版本的VisualStudio只有Managed Test Project类型的工程(之前的版本名称好像为Test Project)。

1、添加Managed Test Project工程,完成之后会自动帮我们创建UnitTest.cpp文件和初始代码框架。
2、修改UnitTest.cpp,添加自己的测试代码:

#include "stdafx.h"
#include "Prime.h"

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;

namespace ManagedTest
{
    [TestClass]
    public ref class UnitTest
    {
    private:
        TestContext^ testContextInstance;

    public: 
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        property Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ TestContext
        {
            Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ get()
            {
                return testContextInstance;
            }
            System::Void set(Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ value)
            {
                testContextInstance = value;
            }
        };

        #pragma region Additional test attributes
        //
        //You can use the following additional attributes as you write your tests:

        // ClassInitialize为 在执行(类中)第一个测试单元之前要执行的代码
        // 如全局变量(或静态变量)的初始化
        //[ClassInitialize()]
        //static void MyClassInitialize(TestContext^ testContext) {};

        //ClassCleanup为 在(类中)所有的测试单元执行完之后要执行的代码
        // 如全局变量(或静态变量)的销毁
        //[ClassCleanup()]
        //static void MyClassCleanup() {};

        // TestInitialize为 在执行每一个测试单元之前要执行的代码
        // 如对象中文件流的打开
        //[TestInitialize()]
        //void MyTestInitialize() {};

        // TestCleanup 为 在执行完每一个测试单元之后要执行的代码
        // 如对象中文件流的关闭
        //[TestCleanup()]
        //void MyTestCleanup() {};
        //
        #pragma endregion 

        [TestMethod]
        void TestMethod()
        {
            // TODO: 在此添加测试逻辑
        };


        [TestMethod]
        void TestPrime2()
        {
            // 测试100以内的质数
            int primes[] =
            {
                2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
                31, 37, 41, 43, 47, 53, 59, 61, 67,
                71, 73, 79, 83, 89, 97/*,   101, 103, 107*/
            };

            int n = sizeof(primes) / sizeof(primes[0]);
            for (int i = 0; i < n; i++)
            {
                Assert::AreEqual(IsPrime(primes[i]), true);
            }
        };


        [TestMethod]
        void TestCalculateSum2()
        {
            // 测试1到n的整数之和
            Assert::AreEqual((int)CalculateSum(4), 10);
            Assert::AreEqual((int)CalculateSum(6), 21);
            Assert::AreEqual((int)CalculateSum(10), 55);
            Assert::AreEqual((int)CalculateSum(100), 5050);
        };


    };
}

3、编译工程。
编译时,如果出现类似如下的错误:

1>VisualStudioProject.lib(Prime.obj) : warning LNK4075: ignoring ‘/EDITANDCONTINUE’ due to ‘/OPT:LBR’ specification
1>VisualStudioProject.lib(Prime.obj) : error LNK2019: unresolved external symbol __imp___invalid_parameter referenced in function “public: char const & __thiscall
1>VisualStudioProject.lib(Prime.obj) : error LNK2019: unresolved external symbol __imp___CrtDbgReportW referenced in function “public: char const & __thiscall
1>msvcprtd.lib(locale0_implib.obj) : error LNK2019: unresolved external symbol __imp___free_dbg referenced in function “public: static void __cdecl std::_Fac_node::operator delete(void *)” (??3_Fac_node@std@@SAXPAX@Z)
1>msvcprtd.lib(locale0_implib.obj) : error LNK2019: unresolved external symbol __imp___malloc_dbg referenced in function “public: static void * __cdecl std::_Fac_node::operator new(unsigned int)” (??2_Fac_node@std@@SAPAXI@Z)
1>D:\CppWorkspace\VS2015\ConsoleApplication1\Debug\DefaultTest.dll : fatal error LNK1120: 4 unresolved externals

右键工程属性(Properties) Configuration Properties -> C/C++ -> Code Generation -> Runtime Library, 将运行库的方式改为 “Multi-Threaded Debug DLL (/MDd)”

4、运行测试代码


测试结果
测试结果



上一篇回顾:
带你玩转Visual Studio——性能分析与优化

下一篇要讲述的内容:
带你玩转Visual Studio——绑定进程调试


版权声明:本文为博主原创文章,未经博主允许不得用于任何商业用途,转载请注明出处。

使用 Visual Studio 2015 对 C++ 代码运行单元测试

代码写多了,往往规模会越来越大,这时候就有必要保证代码的稳定性了;不过我从网上看到的单元测试貌似大多都是用的 JUnit, 难道 C++ 就没有了吗?我从网上找了一些方法试了下其实挺简单的。下面我以一...
  • lxf200000
  • lxf200000
  • 2016年04月08日 21:49
  • 5213

Visual Studio 2010 单元测试之一---普通单元测试

本文以Visual Studio 2010为例,来介绍如何在Visual Studio里面进行单元测试.Visual Studio 2010 单元测试共分七个部分:普通单元测试、顺序单元测试、压力测试...
  • tjvictor
  • tjvictor
  • 2011年02月09日 11:50
  • 54032

Visual Studio 单元测试之六---UI界面测试

UI界面测试其实就是录制操作路径(Mapping),然后按照路径还原操作顺序的一个过程。这个方法对于Winform和Webform都同样适用。下面以winform为例,来介绍如何进行录制。...
  • tjvictor
  • tjvictor
  • 2011年02月09日 14:20
  • 33478

VS2015中进行单元测试

VS2015中进行单元测试 前沿 本机环境: VS2015 创建项目使用.net版本为 .net framework 4.0 1.1创建项目 新建一个项目,项目类型不定。我在这里选择创建了...
  • chr23899
  • chr23899
  • 2016年11月04日 14:58
  • 5549

vs2015单元测试总结——3种方法可用

VS中有个非常有用的功能,单元测试。通过单元测试,开发人员和测试人员可以快速的检查C#,.net和c++项目中各个类的方法中是否有逻辑错误。单元测试仅仅需要创建一次,那么在每次更改源代码时候运行,以确...
  • u013299585
  • u013299585
  • 2017年06月24日 11:58
  • 2048

NUnit.Framework在VS2015中如何进行单元测试

微软在VS2015中加入了自动化生成测试功能, 在需要测试的源文件的公共方法中右键既可以创建单元测试。 不过需要注意的是,要在公共方法中创建,否则会提示这个错误 如下是自动化单元测试界面,可以...
  • loongsking
  • loongsking
  • 2017年01月16日 11:55
  • 3017

教你在Android Studio 中进行单元测试(源码)

  • 2015年07月18日 15:14
  • 5.61MB
  • 下载

VS-单元测试-详细配置步骤

前段时间在调代码的时候,客户端总是报错,说找不到XXX方法。而服务端明明存在该方法......调了良久,最终在四姐(又是四姐)帮助下,调通了。而过程中,单元测试起到了很大的作用。它帮助我们找到了问题的...
  • u012654963
  • u012654963
  • 2016年03月27日 21:51
  • 1909

VS单元测试入门

 微软在VSTS(Visual Studio Team System)2005中集成了单元测试框架(Team Test),就是我们平时所说的单元测试(UnitTest)了。今天,就让我们通过一个简单的...
  • aptentity
  • aptentity
  • 2010年06月14日 20:17
  • 5654

对比MS Test与NUnit Test框架

前言: 项目中进行Unit Test时,肯定会用到框架,因为这样能够更快捷、方便的进行测试。 .Net环境下的测试框架非常多,在这里只是对MS Test和NUnit Test进行一下比较,...
  • jiajiayouba
  • jiajiayouba
  • 2013年08月09日 17:23
  • 13252
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:带你玩转Visual Studio——单元测试
举报原因:
原因补充:

(最多只允许输入30个字)