使用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
这是测试的输出



