【问题标题】:googletest: How to skip test from an inner methodgoogletest:如何从内部方法中跳过测试
【发布时间】:2018-12-13 16:11:58
【问题描述】:

使用GTEST_SKIPwe can (conditionally) skip 进行测试。其实现方式如下:

#define GTEST_SKIP_(message) \
  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)

如果我们在主测试体中,一切都很好。

如何从我的代码库深处跳过测试?这不起作用:

int skip_this(int x) {
  if (x == 3) GTEST_SKIP();
  return x;
}

TEST(X, Y) {
  skip_this(2);
  skip_this(3);
  throw std::runtime_error("Did not skip");
}

错误:

/Users/markus/Projekte/Opossum/Git/src/test/operators/aggregate_test.cpp:183:15: error: cannot initialize return object of type 'int' with an rvalue of type 'void'
  if (x == 3) GTEST_SKIP();
              ^~~~~~~~~~~~

换句话说:如何修改skip_this 以使测试通过或标记为“已跳过”?

【问题讨论】:

    标签: c++ testing googletest


    【解决方案1】:

    这不是很好,但适用于我的目的。这个想法是展开堆栈,搜索调用测试的 googletest 方法并将指令指针重置为该堆栈帧。

    请注意,堆栈未正确销毁,这意味着,例如,资源可能会泄漏。

    #define UNW_LOCAL_ONLY
    #include <libunwind.h>
    #include <cxxabi.h>
    #include <iostream>
    
    #include <gtest/gtest.h>
    
    void skip() {
      unw_cursor_t cursor;
      unw_context_t context;
    
      unw_getcontext(&context);
      unw_init_local(&cursor, &context);
    
      while (unw_step(&cursor)) {
        unw_word_t off;
    
        char symbol[256] = {"<unknown>"};
        char* name = symbol;
    
        if (!unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off)) {
          int status;
          if ((name = abi::__cxa_demangle(symbol, nullptr, nullptr, &status)) == nullptr) name = symbol;
        }
    
        if (std::string(name) == "testing::Test::Run()") {
          ::testing::internal::AssertHelper(::testing::TestPartResult::kSkip, __FILE__, __LINE__, "skipped") = ::testing::Message();
          unw_resume(&cursor);
        }
    
        if (name != symbol) free(name);
      }
    
      throw std::runtime_error("Did not find test method on the stack, could not skip test");
    }
    

    示例测试(可以粘贴在上面的代码下方):

    int foo(int x) {
      if (x == 3) skip();
      return 11;
    }
    
    TEST(SkipTest, ShouldNotBeSkipped) {
      foo(2);
      EXPECT_TRUE(false);
    }
    
    TEST(SkipTest, ShouldBeSkipped) {
      foo(3);
      EXPECT_TRUE(false);
    }
    
    TEST(SkipTest, TestExecutionContinues) {
      EXPECT_FALSE(false);
    }
    
    int main(int argc, char **argv) {
      ::testing::InitGoogleTest(&argc, argv);
      return RUN_ALL_TESTS();
    }
    

    输出:

    [==========] Running 3 tests from 1 test case.
    [----------] Global test environment set-up.
    [----------] 3 tests from SkipTest
    [ RUN      ] SkipTest.ShouldNotBeSkipped
    skip_test.cpp:44: Failure
    Value of: false
      Actual: false
    Expected: true
    [  FAILED  ] SkipTest.ShouldNotBeSkipped (0 ms)
    [ RUN      ] SkipTest.ShouldBeSkipped
    [  SKIPPED ] SkipTest.ShouldBeSkipped (0 ms)
    [ RUN      ] SkipTest.TestExecutionContinues
    [       OK ] SkipTest.TestExecutionContinues (0 ms)
    [----------] 3 tests from SkipTest (0 ms total)
    
    [----------] Global test environment tear-down
    [==========] 3 tests from 1 test case ran. (0 ms total)
    [  PASSED  ] 1 test.
    [  SKIPPED ] 1 test, listed below:
    [  SKIPPED ] SkipTest.ShouldBeSkipped
    [  FAILED  ] 1 test, listed below:
    [  FAILED  ] SkipTest.ShouldNotBeSkipped
    
     1 FAILED TEST
    

    【讨论】:

      【解决方案2】:

      您不能在内部函数中使用 GTEST_SKIP。它不会生效。我只能提供这个解决方案或类似的东西:

      #define SKIPCODE -1
      
      int skip_this(int x)
      {
         if (x == 3)
            return SKIPCODE;
         else return x;
      }
      
      TEST(Test)
      {
         int n = 3;
      
         if (skip_this(n) == SKIPCODE)
            GTEST_SKIP();
         ASSERT_TRUE(false);
      }
      
      int main(int argc, char** argv)
      {
         ::testing::InitGoogleTest(&argc, argv);
         return RUN_ALL_TESTS();
      }
      

      【讨论】:

      • 你能用普通函数和TEST() 演示它吗?问题中的错误似乎更多是由于嵌入的return 没有值。
      • 是的。您正在演示 GTEST_SKIP 的预期/记录用途。我有兴趣从skip_this 中跳过上面的测试。
      • 你说得对,我对这个问题感到困惑
      猜你喜欢
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多