【问题标题】:Recovering from exceptions using CPPUnit使用 CPPUnit 从异常中恢复
【发布时间】:2008-10-15 05:01:12
【问题描述】:

我一直使用 CPPUnit 作为单元测试框架,现在正尝试在自动化构建和打包系统中使用它。然而,一个阻碍我的问题是,如果在运行单元测试期间发生崩溃,例如一个空指针取消引用,它会停止自动化的其余部分。

CPPUnit 有没有办法从异常中恢复,记录测试失败,然后优雅地存在而不是终止单元测试过程?即使是针对空指针取消引用的特定方法也会很有用,因为它构成了我遇到的大约 90% 的问题。

为了具体技术,我在 Windows 系统上使用 makefile。

【问题讨论】:

    标签: unit-testing exception testing cppunit


    【解决方案1】:

    您在构建过程中自动执行基于 cppunit 的单元测试,对吗?

    如果您尝试使用 CppUnit 执行构建过程,我会很想说不要那样做!

    你能告诉我们当单元测试崩溃时是什么停止了构建过程吗?你的单元测试是从什么开始的,一个 Makefile,一个你自己的脚本,还是一个 continuous integration framework


    为了尝试回答您的问题,CppUnit 无法从违规或分段错误中恢复。在类 Unix 系统上,您应该能够捕获 SIGSEGV 并继续,但是 处于哪个状态

    如果您的崩溃发生在您的单元测试中而不是您的产品中,那么我建议您依靠 assertion guards 来防止取消引用 NULL 指针:

    class TestObject : public CPPUNIT_NS::TestCase
    {
      CPPUNIT_TEST_SUITE(Test);
      CPPUNIT_TEST(testObjectIsReady);
      CPPUNIT_TEST_SUITE_END();
    
    public:
      void setUp(void) {}
      void tearDown(void) {} 
    
    protected:
      void testObjectIsReady(void)
      { 
         Object *theObject = GetObject();
    
         CPPUNIT_ASSERT_MESSAGE("check pointer is not null", theObject != NULL);
    
         //--- now you can play with your object without dereferencing a NULL pointer
         CPPUNIT_ASSERT_MESSAGE("check objet is ready", theObject->isReady());
      }
    };
    

    【讨论】:

      【解决方案2】:

      很抱歉这么说,但您之前收到的答案很荒谬。 cppunit 在这方面确实欠缺。 cppunit 应该实现一个 EXIT_ON_FAIL 宏,它允许您捕获 Windows 中的访问冲突(使用 SetUnhandledExceptionFilter),然后您可以进行任何清理并允许 cpp-unit 通过 EXIT_ON_FAIL 报告故障。然后在报告后,退出应用程序。

      【讨论】:

        【解决方案3】:

        在 C/C++ 中,从此类错误中恢复的最佳方法是在单独的进程中运行每个测试,然后从父进程监视它们。这在 UNIX 中非常简单——只需在测试开始前进行 fork() 即可。 check 支持这一点,您可能会修补 CPPUnit 使其具有此行为而无需大惊小怪。

        【讨论】:

        • 不幸的是,如果您正在运行一个非常大的测试套件,这将是令人望而却步的,因为可能会引入大量开销。每次测试都需要更多的时间来执行。
        • 不是我的经验;分叉非常便宜,因为只需要复制修改过的内存页面。除非您运行数十万次测试,否则不太可能注意到 fork() 的开销。
        【解决方案4】:

        作为对稍后阅读此问题的任何人的补充说明,我发现 UnitTest++ 可以在测试中捕获异常,并且只是通过适当的信息使测试失败,而不是导致进程退出。

        【讨论】:

          【解决方案5】:

          我没有尝试过,但如果在 Windows 中,我想使用 SEH 会有所帮助:

          __try
          {
          // running your case
          }
          
          __except
          {
          }
          

          将其集成到CppUnit框架中,每次收到未知异常,将case标记为失败。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-19
            • 1970-01-01
            • 2017-12-26
            • 1970-01-01
            • 2011-12-28
            相关资源
            最近更新 更多