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

发表于:2018-4-12 16:54

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:luoweifu    来源:51Testing软件测试网采编

  什么是单元测试
  所谓单元测试(unit testing),就是对软件中的最小单元进行检查和验证,其一般验证对象是一个函数或者一个类。
  对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里或C++里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。
  单元测试的作用:
  确定自己的代码功能和逻辑的正确性;
  发现问题并及早地改进一些不当的设计;
  对于一些被依赖信很强的代码作修改时,确保逻辑的正确才能不影响其它模块的功能;
  更好地管理和保存测试代码,以便下次代码修改后可方便地进行Debugging;
  VC++的单元测试
  我们继续使用上一章带你玩转Visual Studio——性能分析与优化的案例和代码。经过上一文的优化,我们的代码性能是提高了,但每个函数是否正确无误并没有经过验证。现在就用单元测试进行椎一下。
  使用UnitText工程
  1、 在Solution中添加一个UnitTest的项目 
  图1: 添加UnitTest工程
  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、运行测试代码 
  
  测试结果



上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号