簡體   English   中英

CppUnit的多線程實現?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM