GTest源码剖析(七)——断言

来源:互联网 发布:网络直播怎么兴起的 编辑:程序博客网 时间:2024/06/16 04:50

GTest源码剖析——断言

  • GTest源码剖析断言
    • ASSERT_TRUE宏
      • 1 ASSERT_TRUE宏 和 EXPECT_TRUE宏 的区别
      • 11 GTEST_MESSAGE_宏
        • 12 AssertHelper类
      • 2 ASSERT_TRUE宏的实现
        • 21 AssertionResult类

1 ASSERT_TRUE宏

ASSERT_TRUE宏和ASSERT_FALSE宏几乎认为无区别,仅仅是参数取反而已。

ASSERT_*宏定义如下:

#define ASSERT_TRUE(condition)   GTEST_TEST_BOOLEAN_((condition), #condition, false, true, GTEST_FATAL_FAILURE_)#define ASSERT_FALSE(condition)   GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, GTEST_FATAL_FAILURE_)

1.1 ASSERT_TRUE宏 和 EXPECT_TRUE宏 的区别

  1. EXPECT_TRUE宏和ASSERT_FALSE宏 几乎认为无区别,仅仅是参数取反而已;

  2. EXPECT_TRUE宏和ASSERT_FALSE宏 均使用GTEST_TEST_BOOLEAN_宏;
    两者的区别仅仅是第五个参数不同
    EXPECT_TRUE的参数是GTEST_NONFATAL_FAILURE_,而ASSERT_TRUE的参数是GTEST_FATAL_FAILURE_

EXPECT_*宏定义如下:

#define EXPECT_TRUE(condition)   GTEST_TEST_BOOLEAN_((condition), #condition, false, true,GTEST_NONFATAL_FAILURE_)#define EXPECT_FALSE(condition)   GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, GTEST_NONFATAL_FAILURE_)

3.对比一下 GTEST_FATAL_FAILURE_宏 和 GTEST_NONFATAL_FAILURE_宏 的区别可以发现,两者均使用GTEST_MESSAGE_宏,
区别在于使用了不同的TestPartResult的枚举值。

宏定义如下:

#define GTEST_FATAL_FAILURE_(message)   return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)#define GTEST_NONFATAL_FAILURE_(message)   GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)

TestPartResult类定义如下,仅仅是定义了三个枚举值而已。

class GTEST_API_ TestPartResult {public:  enum Type   {    kSuccess,          // Succeeded.    kNonFatalFailure,  // Failed but the test can continue.    kFatalFailure      // Failed and the test should be terminated.  };

1.1.1 GTEST_MESSAGE_宏

  1. GTEST_MESSAGE_宏定义如下:
#define GTEST_MESSAGE_(message, result_type)   GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
  1. GTEST_MESSAGE_AT_宏定义如下:
#define GTEST_MESSAGE_AT_(file, line, message, result_type)   ::testing::internal::AssertHelper(result_type, file, line, message)     = ::testing::Message()

1.1.2 AssertHelper类

重载了void operator=(const Message& message) const;利用它把断言的结果信息添加到TestResult中。

class GTEST_API_ AssertHelper {public:  AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message);  ~AssertHelper();  void operator=(const Message& message) const;private:  struct AssertHelperData   {    AssertHelperData(TestPartResult::Type t,                     const char* srcfile,                     int line_num,                     const char* msg)        : type(t), file(srcfile), line(line_num), message(msg) { }    TestPartResult::Type const type;    const char* const file;    int const line;    std::string const message;   private:    GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);  };  AssertHelperData* const data_;  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);};// AssertHelper constructor.AssertHelper::AssertHelper(TestPartResult::Type type,                           const char* file,                           int line,                           const char* message)    : data_(new AssertHelperData(type, file, line, message)) {}AssertHelper::~AssertHelper() {  delete data_;}// Message assignment, for assertion streaming support.void AssertHelper::operator=(const Message& message) const {  UnitTest::GetInstance()->    AddTestPartResult(data_->type, data_->file, data_->line,                      AppendUserMessage(data_->message, message),                      UnitTest::GetInstance()->impl()                      ->CurrentOsStackTraceExceptTop(1)                      // Skips the stack frame for this function itself.                      );  // NOLINT}

UnitTest::AddTestPartResult

void UnitTest::AddTestPartResult(    TestPartResult::Type result_type,    const char* file_name,    int line_number,    const std::string& message,    const std::string& os_stack_trace) {  Message msg;  msg << message;  internal::MutexLock lock(&mutex_);  if (impl_->gtest_trace_stack().size() > 0)   {    msg << "\n" << GTEST_NAME_ << " trace:";    for (int i = static_cast<int>(impl_->gtest_trace_stack().size()); i > 0; --i)     {      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];      msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)          << " " << trace.message;    }  }}

1.2 ASSERT_TRUE宏的实现

#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail)   GTEST_AMBIGUOUS_ELSE_BLOCKER_   if (const ::testing::AssertionResult gtest_ar_ =       ::testing::AssertionResult(expression))     ;   else     fail(::testing::internal::GetBoolAssertionFailureMessage(        gtest_ar_, text, #actual, #expected).c_str())

1.2.1 AssertionResult类

class GTEST_API_ AssertionResult {public:  AssertionResult(const AssertionResult& other);  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)  template <typename T>  explicit AssertionResult(      const T& success,      typename internal::EnableIf<          !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type*          /*enabler*/ = NULL)      : success_(success) {}  GTEST_DISABLE_MSC_WARNINGS_POP_()  // Assignment operator.  AssertionResult& operator=(AssertionResult other)   {    swap(other);    return *this;  }  operator bool() const { return success_; }   AssertionResult operator!() const;  const char* message() const   {    return message_.get() != NULL ?  message_->c_str() : "";  }  template <typename T> AssertionResult& operator<<(const T& value)   {    AppendMessage(Message() << value);    return *this;  }  AssertionResult& operator<<(std::ostream& (*basic_manipulator)(::std::ostream& stream))   {    AppendMessage(Message() << basic_manipulator);    return *this;  }private:  void AppendMessage(const Message& a_message)   {    if (message_.get() == NULL)      message_.reset(new ::std::string);    message_->append(a_message.GetString().c_str());  }  void swap(AssertionResult& other);  internal::scoped_ptr< ::std::string> message_;};AssertionResult::AssertionResult(const AssertionResult& other)    : success_(other.success_),      message_(other.message_.get() != NULL ?               new ::std::string(*other.message_) :               static_cast< ::std::string*>(NULL)) {}void AssertionResult::swap(AssertionResult& other) {  using std::swap;  swap(success_, other.success_);  swap(message_, other.message_);}AssertionResult AssertionResult::operator!() const {  AssertionResult negation(!success_);  if (message_.get() != NULL)    negation << *message_;  return negation;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 身份证丢了被别人网贷了怎么办 户口身份证被注销了网贷怎么办 首付交了贷款办不下来怎么办 付首付后贷款没有批下来怎么办 交了首付贷款没有办下来怎么办 买房交了首付贷款没批下来怎么办 交完首付办不下来贷款怎么办 房子交了首付贷款办不下来怎么办 浦发银行办理房贷流水不够怎么办 房贷审批过程中突然换工作怎么办 建行快贷结清后无额度怎么办 建设银行快贷逾期2个月怎么办 全职速卖通一个月没订单要怎么办 买家点的好评写的差评怎么办 手机流量把话费扣没了怎么办 街电忘记还怎么办3天了 街电1个星期没还怎么办 苹果手机设置密码忘记问题了怎么办 买房付了首付后无法办按揭怎么办 苹果x导入通讯录不显示名字怎么办 苹果切换了id通讯录没有了怎么办 换了id通讯录记录没有了怎么办 4s升级系统通讯录没了怎么办 手机接听声音小怎么办但插耳机正常 苹果6p手机听筒声音小怎么办 苹果6s接电话对方声音小怎么办 iphone死机了怎么办关机也关不了 苹果7p卡死sos了怎么办 苹果x死机且屏幕失灵怎怎么办 幸果手机开机数字便按不动了怎么办 苹果6s黑屏但没关机怎么办 苹果6p突然黑屏怎么办单冷接电话 华硕86u的5g掉线找不到怎么办 信而富额度被清0怎么办 贷款回访电话回答错两个问题怎么办 天天中彩票获取期号失败怎么办 借贷宝电话打到家里了怎么办 私人借款付了利息不下款怎么办 别人借钱不还打电话不接怎么办 有信电话给别人打电话不接怎么办 别人欠我材料钱不接电话怎么办