[英]A multi-thread implementation of CppUnit?
有人能指出我允許在單獨的線程中啟動測試的CppUnit版本嗎?
我們的想法是,因為我們的許多測試都非常重CPU(但不是多線程的,當然,它們是獨立的),它可以讓我們在今天的多核上更快地運行測試機器。 目前,運行所有測試大約需要5分鍾。 能夠將其減少到1或2分鍾會很棒......
您認為五分鍾是等待測試完成的很長時間! 試幾個小時。 我有以下動機。
使用Boost線程,CppUnit線程非常簡單。 CppUnit已經有一些用於同步的鈎子,所以下面應該使它的線程安全:
class Mutex : public CPPUNIT_NS::SynchronizedObject::SynchronizationObject
{
public:
void lock() { this->mutex->lock(); }
void unlock() { this->mutex->unlock(); }
private:
boost::mutex mutex;
};
有了這個,您可以修改測試運行器以使TestResult
線程安全。 只需寫一些像CPPUNIT_NS::TestResult testResult(new Mutex);
。 現在這是一個線程測試套件:
class TestSuiteThreaded : public CPPUNIT_NS::TestSuite
{
public:
TestSuiteThreaded(std::string name = "", int nThreads = 0)
: TestSuite(name)
, nThreads(nThreads ? nThreads : boost::thread::hardware_concurrency())
{
}
void doRunChildTests(CPPUNIT_NS::TestResult *controller)
{
ThreadPool pool(this->nThreads);
for (int i=0; i < getChildTestCount(); ++i)
{
pool.add(
boost::bind(threadFunction, getChildTestAt(i)
, controller));
}
}
private:
static void threadFunction(
CPPUNIT_NS::Test *test,
CPPUNIT_NS::TestResult *controller)
{
test->run(controller);
}
const int nThreads;
};
您可能需要一個宏來輕松使用線程測試套件。 您應該能夠將TestSuiteThreaded
套件用作頂級套件或包含相同文本夾具的多個方法的套件。 以下是您如何操作后者 - 將其替換為CPPUNIT_TEST_SUITE_END
。 其中一些是從CppUnit粘貼的,所以請尊重許可證 :
#define CPPUNIT_TEST_SUITE_END_THREADED(n) \
} \
static CPPUNIT_NS::TestSuite *suite() \
{ \
const CPPUNIT_NS::TestNamer &namer = getTestNamer__(); \
std::auto_ptr<CPPUNIT_NS::TestSuite> suite( \
new CPPUNIT_NS::TestSuiteThreaded( namer.getFixtureName(), n)); \
CPPUNIT_NS::ConcretTestFixtureFactory<TestFixtureType> factory; \
CPPUNIT_NS::TestSuiteBuilderContextBase context( *suite.get(), \
namer, \
factory ); \
TestFixtureType::addTestsToSuite( context ); \
return suite.release(); \
} \
private: /* dummy typedef so that the macro can still end with ';'*/ \
typedef int CppUnitDummyTypedefForSemiColonEnding__
現在有一個ThreadPool
的小問題。 我嘗試使用各種公開的,但沒有成功。 我的公司有一個,但我無法在這里發布。 所以滾動你自己 - 在Boost的幫助下,線程池非常簡單有趣。 這是TestSuiteThreaded
預期的接口:
class ThreadPool
{
public:
// Create thread pool, launching n worker threads
ThreadPool(unsigned n);
// Join all worker threads and clean up
~ThreadPool();
// You can have add() do one of two things. Both will work:
// Either: push a new task to the back of the threadpool's work queue
// Or: block until a worker is free then assign task to that thread
void add(boost::function0<void> task);
};
我將此作為練習留給讀者。 玩得開心!
鑒於你已經得到了這個問題的答案,特別是與upvotes的數量相比,我懷疑是否有人制作了一個好的多線程單元測試框架,無論它是多么偉大的想法。 這似乎是一個很好的機會讓某人為自己創造一個非常有用的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.