使用Visual Studio 2012进行原生单元测试






4.45/5 (8投票s)
使用 Visual Studio 2012 中的原生单元测试项目。
引言
原生 C++ 测试单元框架有很多,但在 Visual Studio 2012 中有一个很棒的项目模板,名为 原生单元测试,它完全支持在测试资源管理器中运行测试。
背景
我搜索了原生 C++ 的测试框架,正如许多有经验的程序员所说,Google Test Framework,也称为 GTest 是最好的。我用过它,它更高级,但它在 DOS 窗口中显示结果,并用颜色突出显示警报……但在这个 Visual Studio 测试项目中,情况不同,我们将使用 Visual Studio 来编写和运行我们的测试。
使用代码
我们将创建一个包含三个项目解决方案。
- 第一个是一个名为 DemoBusiness 的 Win32 库,它将包含我们的业务类。在这个库中,我将使用 Visual Studio 为我生成的类
CDemoBusiness
。 - 第二个项目是用于测试先前业务项目的原生单元测试项目。从文件 -> 新建 -> 项目 -> c++ -> 测试 -> 原生单元测试创建它。
- 可选的主应用程序,它将使用业务类// 在我们的例子中是可选的,因为我们正在发现 VS2012 中的原生测试功能。
- *在向 DemoBusiness 项目添加任何新逻辑后,转到测试并添加你的测试方法
- *在 DemoBusiness 中进行任何更改后,构建它,然后构建测试模块,并从测试资源管理器运行所有测试
- *所有
Logger::WriteMessage(L"")
注释将出现在输出窗口中,但选择 测试 在显示输出中。
// DemoBusiness.h
#ifdef DEMOBUSINESS_EXPORTS
#define DEMOBUSINESS_API __declspec(dllexport)
#else
#define DEMOBUSINESS_API __declspec(dllimport)
#endif
class CDemoBusinessTest;
// This class is exported from the DemoBusiness.dll
class DEMOBUSINESS_API CDemoBusiness
{
private://private members
int data;
public:
CDemoBusiness(void);
// TODO: add your methods here.
template<class T> T Max(T item1, T item2) const
{
if (item2 > item1)
{
return item2;
}
return item1;
}
void SetData(int data);
int GetData() const;
int BadAdd(int num1, int num2) const;
int ThrowingException() const;
const int* ReturnNullData() const;
const int* ReturnData() const;
friend class CDemoBusinessTest;
};
// DemoBusiness.cpp
#include "stdafx.h"
#include "DemoBusiness.h"
CDemoBusiness::CDemoBusiness() : data(0)
{
return;
}
void CDemoBusiness::SetData( int data )
{
this->data = data;
}
int CDemoBusiness::GetData() const
{
return this->data;
}
int CDemoBusiness::BadAdd( int num1, int num2 ) const
{
return num1 + num2 + 10;
}
int CDemoBusiness::ThrowingException() const
{
throw exception("Problem");
return 0;
}
const int* CDemoBusiness::ReturnNullData() const
{
return nullptr;
}
const int* CDemoBusiness::ReturnData() const
{
return &data;
}
添加对 DemoBusiness 项目的依赖项。将输出 DemoBusiness.lib 添加到链接器输入,并将输出目录添加到 C++ 目录中的库目录,确保它们具有相同的输出目录,如果是共享链接而不是静态链接,建议使用静态链接。
删除默认的 unittest1.cpp 文件,并添加一个新的 cpp 文件进行测试。我为我们的类创建了以下测试
#include "stdafx.h"
#include "../DemoBusiness/DemoBusiness.h"//this is the file containing the code to test
#include <CppUnitTest.h>
#include <exception>
using namespace std;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
// the following attributes are optional just attributes for more details about the test module
// mention this attributes once per any test module(test project)
BEGIN_TEST_MODULE_ATTRIBUTE()
TEST_MODULE_ATTRIBUTE(L"Project", L"DemoBusiness")
TEST_MODULE_ATTRIBUTE(L"Owner", L"Ahmed")
TEST_MODULE_ATTRIBUTE(L"Date", L"22/10/2013")
END_TEST_MODULE_ATTRIBUTE()
// the following method is optional also just in case of need
TEST_MODULE_INITIALIZE(ModuleStartup)
{
Logger::WriteMessage(L"The test is starting....");
///////////////////////////////////////////////
// Initialize some important data //
/////////////////////////////////////////////
}
// the following method is optional also just in case of need
TEST_MODULE_CLEANUP(ModuleFinalize)
{
Logger::WriteMessage(L"Finalizing the test.");
///////////////////////////////////////////////////////////
// Finalize any previously initialized data //
/////////////////////////////////////////////////////////
}
TEST_CLASS(CDemoBusinessTest)
{
public:
CDemoBusinessTest()
{
Logger::WriteMessage(L"Inside the CDemoBusinessTest");
}
//optional info about the test class
BEGIN_TEST_CLASS_ATTRIBUTE()
TEST_CLASS_ATTRIBUTE(L"Owner", L"Ahmed")
TEST_CLASS_ATTRIBUTE(L"Descrioption", L"CDemoBusiness")
TEST_CLASS_ATTRIBUTE(L"Priority", L"Critical")
END_TEST_CLASS_ATTRIBUTE()
// optional initialization method if needed
TEST_CLASS_INITIALIZE(ClassInitialize)
{
Logger::WriteMessage(L"Initializing the class");
}
//optional finalization method if needed
TEST_CLASS_CLEANUP(ClassFinalize)
{
Logger::WriteMessage(L"Finalizing the class");
}
BEGIN_TEST_METHOD_ATTRIBUTE(TestInitialData)
TEST_OWNER(L"Ahmed")
TEST_DESCRIPTION(L"Make sure that data is initialized to zero,
as data is private this testclass must be friend to our class")
END_TEST_METHOD_ATTRIBUTE()
TEST_METHOD(TestInitialData)
{
CDemoBusiness demo;
Assert::AreEqual(demo.data, 1);
//make sure that they are equal if not the test fails
}
TEST_METHOD(TestMax)
{
CDemoBusiness demo;
double d1 = 192.123;
double d2 = 192.122;
Assert::AreEqual(demo.Max(d1, d2), d1);
}
TEST_METHOD(TestDataTransfer)
{
CDemoBusiness demo;
int data = 100;
demo.SetData(data);
Assert::AreEqual(demo.GetData(), data);
}
TEST_METHOD(TestBadAdd)
{
CDemoBusiness demo;
int num1 = 10;
int num2 = 20;
int addition = num1 + num2;
Assert::AreNotEqual(demo.BadAdd(num1, num2), addition);
}
TEST_METHOD(TestThrowingException)
{
CDemoBusiness demo;
Assert::ExpectException<exception>([&]
{
demo.ThrowingException();
});
}
TEST_METHOD(TestReturnNullData)
{
CDemoBusiness demo;
Assert::IsNull(demo.ReturnNullData());
}
TEST_METHOD(TestReturnData)
{
CDemoBusiness demo;
Assert::IsNotNull(demo.ReturnData());
}
TEST_METHOD(AreSameTest)
{
int x = 100;
int& y = x;
Assert::AreSame(x, y);
}
};
关注点
有关原生单元测试的更多信息
- 使用 Microsoft.VisualStudio.TestTools.CppUnitTestFramework: http://msdn.microsoft.com/en-us/library/hh694604.aspx
- 在 VS11 中使用 Assert::ExpectException 进行原生单元测试: http://blogs.msdn.com/b/dgartner/archive/2012/04/22/using-assert-expectexception-with-native-unit-testing-in-vs11.aspx
- 使用测试资源管理器运行单元测试: http://msdn.microsoft.com/en-us/library/hh270865.aspx
这是测试的输出