使用void函数检查gtest中的错误

时间:2018-12-21 11:12:00

标签: c++ googletest

在gtest中使用使用ASSERT_或EXPECT_宏的辅助函数时,该辅助函数必须为空。但是,我也想在调用测试代码中检查那些错误。

有一个ASSERT_NO_FATAL_FAILURE宏,它有助于在触发ASSERT_的情况下停止调用代码,但是我也想通过对EXPECT_故障的正确处理(请参阅:NonFatalFailures)进行扩展。这是到目前为止我得到的:

#include <gtest/gtest.h>

// A void test-function using  ASSERT_ or EXPECT_ calls should be encapsulated by this macro.
// Example: CHECK_FOR_FAILURES(MyCheckForEquality(lhs, rhs))
#define CHECK_FOR_FAILURES(statement)                                                              \
  ASSERT_NO_FATAL_FAILURE((statement));                                                            \
  EXPECT_FALSE(HasNonfatalFailure())

void TestHelperFunction(bool givenAssert, int givenExpect)
{
    ASSERT_TRUE(givenAssert);  // note: this is line 11 in my code
    EXPECT_EQ(givenExpect, 0); // note: this is line 12 in my code
}

TEST(FailureInFunctionTestNoChecks, noChecks)
{
    // note: this is line 17 in my code
    TestHelperFunction(true, 0);
    TestHelperFunction(true, 1);
    for (int i = 0; i < 3; ++i)
    {
        TestHelperFunction(true, i);
    }
    TestHelperFunction(false, 1);
    TestHelperFunction(true, 2);
}

TEST(FailureInFunctionTestWithChecks, withChecks)
{
    // note: this is line 30 in my code
    CHECK_FOR_FAILURES(TestHelperFunction(true, 0)) << "\n All good - will NOT be seen! \n";
    CHECK_FOR_FAILURES(TestHelperFunction(true, 1)) << "\n optional msg: First Expect failed \n";
    for (int i = 0; i < 3; ++i)
    {
        CHECK_FOR_FAILURES(TestHelperFunction(true, i)) << "\n optional msg: Expect failed for i=" << i << "\n";
    }
    CHECK_FOR_FAILURES(TestHelperFunction(false, 1)) << "this message will NOT be seen due to the assert";
    CHECK_FOR_FAILURES(TestHelperFunction(true, 2)) << "\n will not be seen because assert stops the test \n";
}

// This test creates the following output:

// Note: Google Test filter = *FailureInFunctionTest*
// [==========] Running 2 tests from 2 test cases.
// [----------] Global test environment set-up.
// [----------] 1 test from FailureInFunctionTestNoChecks
// [ RUN      ] FailureInFunctionTestNoChecks.noChecks
// ./checked_test_failure.cpp:12: Failure
// Expected equality of these values:
//   givenExpect
//     Which is: 1
//   0
// ./checked_test_failure.cpp:12: Failure
// Expected equality of these values:
//   givenExpect
//     Which is: 1
//   0
// ./checked_test_failure.cpp:12: Failure
// Expected equality of these values:
//   givenExpect
//     Which is: 2
//   0
// ./checked_test_failure.cpp:11: Failure
// Value of: givenAssert
//   Actual: false
// Expected: true
// ./checked_test_failure.cpp:12: Failure
// Expected equality of these values:
//   givenExpect
//     Which is: 2
//   0
// [  FAILED  ] FailureInFunctionTestNoChecks.noChecks (0 ms)
// [----------] 1 test from FailureInFunctionTestNoChecks (0 ms total)
// 
// [----------] 1 test from FailureInFunctionTestWithChecks
// [ RUN      ] FailureInFunctionTestWithChecks.withChecks
// ./checked_test_failure.cpp:12: Failure
// Expected equality of these values:
//   givenExpect
//     Which is: 1
//   0
// ./checked_test_failure.cpp:32: Failure
// Value of: HasNonfatalFailure()
//   Actual: true
// Expected: false
// 
//  optional msg: First Expect failed 
// 
// ./checked_test_failure.cpp:35: Failure
// Value of: HasNonfatalFailure()
//   Actual: true
// Expected: false
// 
//  optional msg: Expect failed for i=0
// 
// ./checked_test_failure.cpp:12: Failure
// Expected equality of these values:
//   givenExpect
//     Which is: 1
//   0
// ./checked_test_failure.cpp:35: Failure
// Value of: HasNonfatalFailure()
//   Actual: true
// Expected: false
// 
//  optional msg: Expect failed for i=1
// 
// ./checked_test_failure.cpp:12: Failure
// Expected equality of these values:
//   givenExpect
//     Which is: 2
//   0
// ./checked_test_failure.cpp:35: Failure
// Value of: HasNonfatalFailure()
//   Actual: true
// Expected: false
// 
//  optional msg: Expect failed for i=2
// 
// ./checked_test_failure.cpp:11: Failure
// Value of: givenAssert
//   Actual: false
// Expected: true
// ./checked_test_failure.cpp:37: Failure
// Expected: (TestHelperFunction(false, 1)) doesn't generate new fatal failures in the current thread.
//   Actual: it does.
// [  FAILED  ] FailureInFunctionTestWithChecks.withChecks (1 ms)
// [----------] 1 test from FailureInFunctionTestWithChecks (1 ms total)
// 
// [----------] Global test environment tear-down
// [==========] 2 tests from 2 test cases ran. (1 ms total)
// [  PASSED  ] 0 tests.
// [  FAILED  ] 2 tests, listed below:
// [  FAILED  ] FailureInFunctionTestNoChecks.noChecks
// [  FAILED  ] FailureInFunctionTestWithChecks.withChecks
// 
//  2 FAILED TESTS
// 

从输出中可以看到:使用新的'CHECK_FOR_FAILURES'宏可以改善测试输出:它告诉您导致失败的那一行,并且在命中断言后阻止执行测试。

但是,使用“ HasNonfatalFailure()”还不够好,因为您在i = 0的输出中可以看到。原因是已经存在一个非致命错误,并且对于i = 0,没有新的非致命错误,但是HasNonfatalFailure()由于旧错误而返回true ..:-(

有什么想法可以消除错误的i = 0输出吗?

1 个答案:

答案 0 :(得分:0)

以下是使用suggestion of gtest docs的一种明显方法,但我宁愿不使用自定义消息或SCOPED_TRACE()宏

#include <gtest/gtest.h>

// A void test-function using  ASSERT_ or EXPECT_ calls with a custom message should be encapsulated
// by this macro. Example: CHECK_FOR_FAILURES_MSG(MyCheckForEquality(counter, 42), "for counter=42")
#define CHECK_FOR_FAILURES_MSG(statement, message)                                                 \
{                                                                                                  \
    SCOPED_TRACE(message);                                                                         \
    ASSERT_NO_FATAL_FAILURE((statement));                                                          \
}

// A void test-function using  ASSERT_ or EXPECT_ calls should be encapsulated by this macro.
// Example: CHECK_FOR_FAILURES(MyCheckForEquality(lhs, rhs))
#define CHECK_FOR_FAILURES(statement) CHECK_FOR_FAILURES_MSG(statement, " <--  line of failure\n")

void TestHelperFunction(bool givenAssert, int givenExpect)
{
    ASSERT_TRUE(givenAssert);  // note: this is line 17 in my code
    EXPECT_EQ(givenExpect, 0); // note: this is line 18 in my code
}

TEST(FailureInFunctionTestNoChecks, noChecks)
{
    // note: this is line 23 in my code
    TestHelperFunction(true, 0);
    TestHelperFunction(true, 1);
    for (int i = 0; i < 3; ++i)
    {
        TestHelperFunction(true, i);
    }
    TestHelperFunction(false, 1);
    TestHelperFunction(true, 2);
}

TEST(FailureInFunctionTestWithChecks, withChecks)
{
    // note: this is line 36 in my code
    CHECK_FOR_FAILURES(TestHelperFunction(true, 0));
    CHECK_FOR_FAILURES(TestHelperFunction(true, 1));
    for (int i = 0; i < 3; ++i)
    {
        CHECK_FOR_FAILURES_MSG(TestHelperFunction(true, i), "for i=" + std::to_string(i) + "\n");
    }
    CHECK_FOR_FAILURES(TestHelperFunction(false, 1));
    CHECK_FOR_FAILURES(TestHelperFunction(true, 2));
}

// Note: Google Test filter = *FailureInFunction*
//[==========] Running 2 tests from 2 test cases.
//[----------] Global test environment set-up.
//[----------] 1 test from FailureInFunctionTestNoChecks
//[ RUN      ] FailureInFunctionTestNoChecks.noChecks
//./checked_test_failure.cpp:18: Failure
//Expected equality of these values:
//  givenExpect
//    Which is: 1
//  0
//./checked_test_failure.cpp:18: Failure
//Expected equality of these values:
//  givenExpect
//    Which is: 1
//  0
//./checked_test_failure.cpp:18: Failure
//Expected equality of these values:
//  givenExpect
//    Which is: 2
//  0
//./checked_test_failure.cpp:17: Failure
//Value of: givenAssert
//  Actual: false
//Expected: true
//./checked_test_failure.cpp:18: Failure
//Expected equality of these values:
//  givenExpect
//    Which is: 2
//  0
//[  FAILED  ] FailureInFunctionTestNoChecks.noChecks (0 ms)
//[----------] 1 test from FailureInFunctionTestNoChecks (0 ms total)
//
//[----------] 1 test from FailureInFunctionTestWithChecks
//[ RUN      ] FailureInFunctionTestWithChecks.withChecks
//./checked_test_failure.cpp:18: Failure
//Expected equality of these values:
//  givenExpect
//    Which is: 1
//  0
//Google Test trace:
//./checked_test_failure.cpp:38:  <--  line of failure
//
//./checked_test_failure.cpp:18: Failure
//Expected equality of these values:
//  givenExpect
//    Which is: 1
//  0
//Google Test trace:
//./checked_test_failure.cpp:41: for i=1
//
//./checked_test_failure.cpp:18: Failure
//Expected equality of these values:
//  givenExpect
//    Which is: 2
//  0
//Google Test trace:
//./checked_test_failure.cpp:41: for i=2
//
//./checked_test_failure.cpp:17: Failure
//Value of: givenAssert
//  Actual: false
//Expected: true
//Google Test trace:
//./checked_test_failure.cpp:43:  <--  line of failure
//
//./checked_test_failure.cpp:43: Failure
//Expected: (TestHelperFunction(false, 1)) doesn't generate new fatal failures in the current thread.
//  Actual: it does.
//Google Test trace:
//./checked_test_failure.cpp:43:  <--  line of failure
//
//[  FAILED  ] FailureInFunctionTestWithChecks.withChecks (0 ms)
//[----------] 1 test from FailureInFunctionTestWithChecks (0 ms total)
//
//[----------] Global test environment tear-down
//[==========] 2 tests from 2 test cases ran. (0 ms total)
//[  PASSED  ] 0 tests.
//[  FAILED  ] 2 tests, listed below:
//[  FAILED  ] FailureInFunctionTestNoChecks.noChecks
//[  FAILED  ] FailureInFunctionTestWithChecks.withChecks
//
// 2 FAILED TESTS
//