繁体   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