c++ - CoInitializeEx 用于 boost::test::unit_test

标签 c++ windows visual-studio com boost-test

前几天,我决定需要了解 Windows 平台上 C++ 的测试驱动开发(使用 Visual Studio 2010 Premium)。

在决定试用 boost 的单元测试框架之前,我环顾四周。我应该说我选择了 boostpro.com 的版本(如果我没记错的话,当前版本是 1.44)。这有一个静态库的构建,所以我不在我的测试中使用 DLL。

Boost 的单元测试文档谈到将代码与测试套件分开,这似乎很合理。但随后您必须处理从现在独立的测试套件项目中引用代码的问题。

所以我有一个要测试的库项目(但我仍然不确定如何编写可以引用 .exe 项目的测试...)

所以我在我的解决方案中创建了一个单独的项目,称为单元测试。我添加了以下代码:

#include "stdafx.h"

#define BOOST_TEST_MODULE Crash
#include <boost/test/unit_test.hpp> 
#include "LameEncoder.h"

BOOST_AUTO_TEST_SUITE(CrashTestSuite)

BOOST_AUTO_TEST_CASE(EncoderAvailable)
{
    using namespace Crash::SystemDevices::Audio::Compressors::LameEncoder;

    HRESULT hr = S_OK;
    CComPtr <IBaseFilter> spEncoder;

    hr = spEncoder.CoCreateInstance( CLSID_LAMEDShowFilter );
    if( spEncoder.p )
        spEncoder.Release();

    BOOST_CHECK_EQUAL( hr, S_OK );
}

BOOST_AUTO_TEST_CASE(ProfilesGenerated)
{
    using namespace Crash::SystemDevices::Audio::Compressors::LameEncoder;  
    BOOST_CHECK_EQUAL ( EncoderProfiles.size(), 6 );
}

BOOST_AUTO_TEST_SUITE_END()

我静态链接到我的“崩溃”库项目输出,然后我添加了以下构建后事件以获取构建后报告:

"$(TargetDir)\$(TargetName).exe" --result_code=no --report_level=short

构建后的输出如下所示:

1>------ Build started: Project: UnitTests, Configuration: Debug Win32 ------
1>  UnitTests.cpp
1>  UnitTests.vcxproj -> F:\Projects\Crash\trunk\Debug\UnitTests.exe
1>  Running 2 test cases...
1>  f:/projects/crash/trunk/unittests/unittests.cpp(19): error in "EncoderAvailable": check hr == ((HRESULT)0L) failed [-2147221008 != 0]
1>  
1>  Test suite "Crash" failed with:
1>    1 assertion out of 2 passed
1>    1 assertion out of 2 failed
1>    1 test case out of 2 passed
1>    1 test case out of 2 failed

我预计 EncoderAvailable 测试会失败,因为我还没有为线程初始化 COM 单元。我假设我不能使用自动测试,而是需要用我在主函数中手动定义自己的测试替换自动测试,并在主函数中调用 CoInitializeEx()。

我读过 here您可以定义入口点并注册您自己的函数,所以我试了一下:

#include "stdafx.h"

#include <boost/test/unit_test.hpp>
using namespace boost::unit_test;

#include "LameEncoderTests.h"


test_suite*
init_unit_test_suite( int argc, char* argv[] ) 
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    framework::master_test_suite().
        add( BOOST_TEST_CASE( &LameEncoderAvailable ) );

    framework::master_test_suite().
        add( BOOST_TEST_CASE( &LameEncoderProfilesGenerated ) );

    CoUninitialize();

    return 0;
}

这是构建输出:

    1>------ Build started: Project: UnitTests, Configuration: Debug Win32 ------
1>  UnitTests.cpp
1>  UnitTests.vcxproj -> F:\Projects\Crash\trunk\Debug\UnitTests.exe
1>  Running 2 test cases...
1>  f:/projects/crash/trunk/unittests/lameencodertests.h(17): error in "LameEncoderAvailable": check hr == ((HRESULT)0L) failed [-2147221008 != 0]
1>  
1>  Test suite "Master Test Suite" failed with:
1>    1 assertion out of 2 passed
1>    1 assertion out of 2 failed
1>    1 test case out of 2 passed
1>    1 test case out of 2 failed
1>  
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

该测试失败在第一个测试 LameEncoderAvailable 上失败,这是以下简单函数:

void LameEncoderAvailable()
{
    using namespace Crash::SystemDevices::Audio::Compressors::LameEncoder;

    HRESULT                 hr              = S_OK;
    CComPtr<IBaseFilter>    spEncoder;

    hr = spEncoder.CoCreateInstance( CLSID_LAMEDShowFilter );
    if( spEncoder.p )
        spEncoder.Release();

    BOOST_CHECK_EQUAL( hr, S_OK );
}

谁能告诉我在何处进行 CoInitializeEx() 调用的正确位置 - 我认为我不应该在每个测试中这样做一次 - 它应该只在每个线程中完成一次......

至于测试 exe 项目,我猜你可以指定一个单独的 main.cpp(testmain.cpp 或其他东西)并从构建中排除你真正的 main.cpp 以访问你的代码。如果有人知道更优雅的解决方案,我很想听听...

最佳答案

使用 Global Fixture .夹具是为每个测试设置初始化/关闭代码的好方法。全局夹具让您可以为整个测试套件定义初始化/关闭代码。

关于c++ - CoInitializeEx 用于 boost::test::unit_test,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5219993/

相关文章:

c++ - 为什么虚函数会破坏我的转换?

java - 与命令行进程交互

windows - 在Windows中从vim调用外部脚本时如何引用主目录

android - 在 android studio 上使用 NDK 构建原生 openCV

c++ - 通过命名管道从 C++ exe 向 vb.net dll 发送一个空指针

c++ - C++ 中的 "template <typename From, typename Tag> struct Alias;"是什么?

java - 使用静默安装将 Java 安装到带空格的目录中

android - visual studio 2015,android 命令 'run-as' 失败

visual-studio - VS 中的奇怪 "go to sources"行为

c++ - 给定一个指向 C++ 对象的指针,调用 operator[] 函数的所有正确方法是什么?