[googletest] --- 简易使用教程

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: [googletest] --- 简易使用教程

1 googletest下载/官方sample分析

1.1 googletest源码下载编译

源码下载编译

// 下载
git clone https://github.com/google/googletest
// 现在官方已经把 gtest 和 gmock 一起维护,所以这个 git 仓库还包含了 gmock。
// 编译、安装
cd googletest-main
mkdir build install
cd build
cmake -DCMAKE_INSTALL_PREFIX=../install
make -j
make install

编译设置

如果需要生成.so库,生成官方sample的二进制文件,需要对源码最外层的CMakeLists.txt进行修改

生成动态库或者静态库,需要修改BUILD_SHARED_LIBS

生成samples测试bin文件,需要修改gtest_build_samples

将L20修改为ON之后,可以在build目录下看到googletest自带的sample都编译为了可执行文件。

1.2 googletest语法

TEST宏

TEST(test_case_name, test_name) 宏用于定义一个测试用例,其中test_case_name是测试用例的名称,test_name是测试的名称。例如:

TEST(MyTestSuite, MyTest) {
  // 测试代码
}

ASSERT宏

ASSERT_() 宏用于断言结果是否符合预期,其中可以是以下几种:

ASSERT_TRUE(condition):条件为真

ASSERT_FALSE(condition):条件为假

ASSERT_EQ(val1, val2):两个值相等

ASSERT_NE(val1, val2):两个值不相等

ASSERT_LT(val1, val2):第一个值小于第二个值

ASSERT_LE(val1, val2):第一个值小于等于第二个值

ASSERT_GT(val1, val2):第一个值大于第二个值

ASSERT_GE(val1, val2):第一个值大于等于第二个值

例如:

TEST(MyTestSuite, MyTest) {
  int a = 1;
  int b = 2;
  ASSERT_TRUE(a < b);
  ASSERT_EQ(a + b, 3);
}

如果断言失败,测试用例将会失败。

EXPECT宏

EXPECT_() 宏与ASSERT_()宏的作用相同,但是如果检查失败,不会终止测试用例的执行。例如:

TEST(MyTestSuite, MyTest) {
  int a = 1;
  int b = 2;
  EXPECT_TRUE(a < b);
  EXPECT_EQ(a + b, 3);
}

ASSERT宏和EXCEPT宏的区别:
ASSERT 不通过的时候会认为是一个 fatal 的错误,退出当前函数(只是函数)。而 EXPECT 失败的话会继续运行当前函数,所以对于函数内几个失败可以同时报告出来。通常我们用 EXPECT 级别的断言就好,除非你认为当前检查点失败后函数的后续检查没有意义。

SetUp和TearDown

SetUp() 和 TearDown() 函数可以在每个测试用例执行前和执行后分别调用,用于初始化和清理测试环境。例如:

class MyTestSuite : public ::testing::Test {
 protected:
  void SetUp() override {
    // 初始化代码
  }
  void TearDown() override {
    // 清理代码
  }
};
TEST_F(MyTestSuite, MyTest) {
  // 测试代码
}

参数化测试

参数化测试可以用于测试一组输入的不同情况下,程序的输出是否符合预期。例如:

class MyTestSuite : public ::testing::TestWithParam<int> {
};
TEST_P(MyTestSuite, MyTest) {
  int input = GetParam();
  // 测试代码
}
INSTANTIATE_TEST_SUITE_P(MyTestSuiteInstantiationName, MyTestSuite, ::testing::Values(1, 2, 3));

在这个例子中,MyTestSuite 继承自 TestWithParam,表示这是一个参数化测试。GetParam() 函数可以获取当前测试用例的参数值。INSTANTIATE_TEST_SUITE_P 宏用于实例化测试用例,其中第一个参数是实例化的名称,第二个参数是测试用例的名称,第三个参数是参数值列表。

预期异常

有时候需要测试程序在出现异常时的行为,可以使用 EXPECT_THROW() 和 ASSERT_THROW() 宏。例如:

TEST(MyTestSuite, MyTest) {
  std::vector<int> v;
  EXPECT_THROW(v.at(0), std::out_of_range);
}

在这个例子中,EXPECT_THROW() 宏表示期望在执行 v.at(0) 时抛出 std::out_of_range 异常。如果没有抛出异常,测试用例将失败。

1.3 官方sample分析

我们安装时下载的代码就包含了 10 个例子,可以直接在根目录下执行 make 并运行。进入 samples 文件夹,阅读每份功能代码和对应的测试文件,可以帮助我们较快入门。我们下面看一下简单的例子。

sample1

#include <limits.h>
#include "sample1.h"
#include "gtest/gtest.h"
// Tests factorial of negative numbers.
TEST(FactorialTest, Negative) {
  // This test is named "Negative", and belongs to the "FactorialTest"
  // test case.
  EXPECT_EQ(1, Factorial(-5));
  EXPECT_EQ(1, Factorial(-1));
  EXPECT_GT(Factorial(-10), 0);
}
...
TEST(IsPrimeTest, Positive) {
  EXPECT_FALSE(IsPrime(4));
  EXPECT_TRUE(IsPrime(5));
  EXPECT_FALSE(IsPrime(6));
  EXPECT_TRUE(IsPrime(23));
}

sample1 演示了简单测试用例的编写,主要使用了 TEST() 宏。

一个 test_case_name 对应一个函数的测试用例,test_name 可以对应这个测试用例下的某个场景的测试集。这两个名字可以任意取,但应该是有意义的.

sample1运行结果如下:

2 在自己的代码中使用gtest

上面已经说了如何将gtest编译成库,在自己项目中使用gtest时需要将install的头文件和库文件包含在记录的项目目录中。

项目目录如下:

// CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(GTEST_USAGE)
set(CMAKE_CXX_COMPILE_FLAGS "std=c++11")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/install/include)
file(GLOB CPP_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c*)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/install/lib)
add_executable(GTEST_USAGE ${CPP_FILES})
target_link_libraries(GTEST_USAGE 
gtest
)
// main.cpp
#include <gtest/gtest.h>
#include<numeric>
int main(int argc, char **argv)
{
  testing::InitGoogleTest(&argc, argv)
  return 0;
}

这里我不写自己的代码,直接用官方的sample4充当测试代码

sample4.cc

// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
#include "sample4.h"
#include <stdio.h>
// Returns the current counter value, and increments it.
int Counter::Increment() { return counter_++; }
// Returns the current counter value, and decrements it.
// counter can not be less than 0, return 0 in this case
int Counter::Decrement() {
  if (counter_ == 0) {
    return counter_;
  } else {
    return counter_--;
  }
}
// Prints the current counter value to STDOUT.
void Counter::Print() const { printf("%d", counter_); }

sample4.h

// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
#ifndef GOOGLETEST_SAMPLES_SAMPLE4_H_
#define GOOGLETEST_SAMPLES_SAMPLE4_H_
// A simple monotonic counter.
class Counter {
 private:
  int counter_;
 public:
  // Creates a counter that starts at 0.
  Counter() : counter_(0) {}
  // Returns the current counter value, and increments it.
  int Increment();
  // Returns the current counter value, and decrements it.
  int Decrement();
  // Prints the current counter value to STDOUT.
  void Print() const;
};
#endif  // GOOGLETEST_SAMPLES_SAMPLE4_H_

sample4_unittest.cc

// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "sample4.h"
#include "gtest/gtest.h"
namespace {
// Tests the Increment() method.
TEST(Counter, Increment) {
  Counter c;
  // Test that counter 0 returns 0
  EXPECT_EQ(0, c.Decrement());
  // EXPECT_EQ() evaluates its arguments exactly once, so they
  // can have side effects.
  EXPECT_EQ(0, c.Increment());
  EXPECT_EQ(1, c.Increment());
  EXPECT_EQ(2, c.Increment());
  EXPECT_EQ(3, c.Decrement());
}
}  // namespace

运行结果如下:



相关文章
|
测试技术 程序员 C++
C++单元测试GoogleTest和GoogleMock十分钟快速上手(gtest&gmock)
gtest是Google开源的一个跨平台的(Liunx、Mac OS X、Windows等)的 C++ 单元测试框架,可以帮助程序员测试 C++ 程序的结果预期。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。另一方面,gmock并不是一个独立的测试框架,而是gtest的辅助框架,主要用于模拟没有实现的类的操作,以便在没有完整类的情况下进行测试。通过配合使用gtest和gmock,开发者可以编写出更为复杂且健壮的C++单元测试。
1513 0
|
存储 安全 编译器
【C++ 17 新功能 std::visit 】深入解析 C++17 中的 std::visit:从原理到实践
【C++ 17 新功能 std::visit 】深入解析 C++17 中的 std::visit:从原理到实践
1120 1
|
6月前
|
安全 Unix Linux
VMware Workstation 17.6.3 发布下载,现在完全免费无论个人还是商业用途
VMware Workstation 17.6.3 发布下载,现在完全免费无论个人还是商业用途
48030 65
|
10月前
|
机器学习/深度学习 编解码 Java
YOLO11创新改进系列:卷积,主干 注意力,C3k2融合,检测头等创新机制(已更新100+)
《YOLO11目标检测创新改进与实战案例》专栏已更新100+篇文章,涵盖注意力机制、卷积优化、检测头创新、损失与IOU优化、轻量级网络设计等多方面内容。每周更新3-10篇,提供详细代码和实战案例,帮助您掌握最新研究和实用技巧。[专栏链接](https://blog.csdn.net/shangyanaf/category_12810477.html)
YOLO11创新改进系列:卷积,主干 注意力,C3k2融合,检测头等创新机制(已更新100+)
|
存储 前端开发 IDE
YAML语法记录
YAML语法记录
344 0
|
存储 NoSQL Linux
《探索 Linux 命令:systemd-coredumpctl》
**《systemd-coredumpctl概览》** `systemd-coredumpctl`, Linux中管理&分析core dump的利器。集中管控systemd生成的转储,详述crash细节。用`--list`查看所有转储,`--info &lt;ID&gt;`深入单一转储。需注意权限、存储管理,配gdb深化分析。精通此命令,加速问题诊断。#LinuxTips #CoreDumpAnalysis
|
存储 C++
【C++】Visual Studio C++ 配置并使用gtest(不好用你捶我)
【C++】Visual Studio C++ 配置并使用gtest(不好用你捶我)
|
自然语言处理
什么是大模型的局限性?
【7月更文挑战第25天】什么是大模型的局限性?
1845 3
|
编译器 C语言 C++
列举gcc 常见和有用的编译警告选项
列举gcc 常见和有用的编译警告选项
485 0
|
存储 缓存 Unix
Cmake 链接外部库:如何在项目中使用外部库和头文件
Cmake 链接外部库:如何在项目中使用外部库和头文件
1316 0