首页 > 其他分享 >google gtest框架入门使用案例

google gtest框架入门使用案例

时间:2023-10-16 13:56:50浏览次数:51  
标签:google 入门 ASSERT gtest EXPECT val2 test leetcode24 val1

通过本文可以收获:google gtest急速入门、google gtest资源网站。

google gtest是什么

google gtest是谷歌开源的c++单元测试框架,非常的好用。

起码个人感觉和spring boot自带的测试框架功能差不太多。

安装

略过,请参考:GitHub - google/googletest: GoogleTest - Google Testing and Mocking Framework或网上资料

使用案例分析

本文重点。

目前版本样例位于:googletest/googletest/samples at main · google/googletest中。

断言

与spring boot的测试框架类似,gtest判断样例是否出错用的也是断言。
断言使用(ASSERTEXPECT)和配合上具体内容,下面案例应该是一看就懂。
ASSERTEXPECT的区别只在于一个函数中,如果有多个断言,ASSERT断言失败后当前函数后续部分不会执行了,EXPECT断言失败后当前函数的后续部分会继续执行。
因此两种具体用哪一个需要看 当前断言失败后函数后续还有无意义。

基础的断言

Fatal assertion Nonfatal assertion Verifies
ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition is true
ASSERT_FALSE(condition); EXPECT_FALSE(condition); condition is false

数值比较

Fatal assertion Nonfatal assertion Verifies
ASSERT_EQ(val1, val2); EXPECT_EQ(val1, val2); val1 == val2
ASSERT_NE(val1, val2); EXPECT_NE(val1, val2); val1 != val2
ASSERT_LT(val1, val2); EXPECT_LT(val1, val2); val1 < val2
ASSERT_LE(val1, val2); EXPECT_LE(val1, val2); val1 <= val2
ASSERT_GT(val1, val2); EXPECT_GT(val1, val2); val1 > val2
ASSERT_GE(val1, val2); EXPECT_GE(val1, val2); val1 >= val2

字符串比较

Fatal assertion Nonfatal assertion Verifies
ASSERT_STREQ(str1, str2); EXPECT_STREQ(str1, _str_2); the two C strings have the same content
ASSERT_STRNE(str1, str2); EXPECT_STRNE(str1, str2); the two C strings have different content
ASSERT_STRCASEEQ(str1, str2); EXPECT_STRCASEEQ(str1, str2); the two C strings have the same content, ignoring case
ASSERT_STRCASENE(str1, str2); EXPECT_STRCASENE(str1, str2); the two C strings have different content, ignoring case

上面内容并不完整,gtest还有些厉害的功能,比如ASSERT_NEAR(ASSERT_NEAR(res, 3.0, 1.0e-11);)用于断言数字的接近程度,当然这种功能已经可以由基础的组合而成了。

个人样例分析

在配置好环境后来一个最简单的入门吧。

公司这边使用的是集成的插件,具体配置vscode + gtest请自行探索。

/*
* Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All rights reserved.
*/
#include "gtest/gtest.h"
#include "leetcode24.h" //要测试的函数的头文件,其中有要测试的函数

int main(int argc, char** argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

TEST(leetcode24, add1)
{
    double res = AddNumbers(1.0, 2.0);
    ASSERT_NEAR(res, 3.0, 1.0e-11);
}

编译后点击测试即可:

可以观察到左边名字和右边TEST宏中有对应,TEST的传入的参数只是名字,没有其他含义。

这里是已经测试成功了,除了图形化也可以在命令行进行测试:

正在执行任务: cd build && cmake --build . --target all && ctest -j14 -C Debug -T test --verbose 

[2/2] Linking CXX executable ..\bin\test_leetcode24.exe
UpdateCTestConfiguration  from :C:/Users/cWX1274913/Desktop/self/leetcode/leetcode24/build/DartConfiguration.tcl
Parse Config file:C:/Users/cWX1274913/Desktop/self/leetcode/leetcode24/build/DartConfiguration.tcl
   Site: P_CDTFC3-N64RRS
   Build name: Win32-ninja
UpdateCTestConfiguration  from :C:/Users/cWX1274913/Desktop/self/leetcode/leetcode24/build/DartConfiguration.tcl
Parse Config file:C:/Users/cWX1274913/Desktop/self/leetcode/leetcode24/build/DartConfiguration.tcl
Test project C:/Users/cWX1274913/Desktop/self/leetcode/leetcode24/build
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 1
    Start 1: test

1: Test command: C:\Users\cWX1274913\Desktop\self\leetcode\leetcode24\bin\test_leetcode24.exe
1: Test timeout computed to be: 1500
1: [==========] Running 1 test from 1 test case.
1: [----------] Global test environment set-up.
1: [----------] 1 test from leetcode24
1: [ RUN      ] leetcode24.add1
1: [       OK ] leetcode24.add1 (0 ms)
1: [----------] 1 test from leetcode24 (0 ms total)
1:
1: [----------] Global test environment tear-down
1: [==========] 1 test from 1 test case ran. (0 ms total)
1: [  PASSED  ] 1 test.
1/1 Test #1: test .............................   Passed    0.10 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.12 sec
 *  终端将被任务重用,按任意键关闭。

可以看到测试已经成功了,来个失败的案例吧。
增加两个test案例,分别是ASSERTEXPECT的失败案例。

TEST(leetcode24, assertFail)
{
    double res = AddNumbers2(1.0, 2.0);
    // EXPECT_NEAR(res, 4.0, 1.0e-11);
    ASSERT_NEAR(res, 4.0, 1.0e-11);
    res = 3;
    EXPECT_NEAR(res, 3.0, 1.0e-11);
}


TEST(leetcode24, expextFail)
{
    double res = AddNumbers2(1.0, 2.0);
    EXPECT_NEAR(res, 4.0, 1.0e-11);
    res = 3;
    EXPECT_NEAR(res, 3.0, 1.0e-11);
}

运行后的命令行:

test 1
    Start 1: test

1: Test command: C:\Users\cWX1274913\Desktop\self\leetcode\leetcode24\bin\test_leetcode24.exe
1: Test timeout computed to be: 1500
1: [==========] Running 3 tests from 1 test case.
1: [----------] Global test environment set-up.
1: [----------] 3 tests from leetcode24
1: [ RUN      ] leetcode24.add1
1: [       OK ] leetcode24.add1 (0 ms)
1: [ RUN      ] leetcode24.assertFail
1: ../test/test_leetcode24.cpp:23: Failure
1: The difference between res and 4.0 is 1, which exceeds 1.0e-11, where
1: res evaluates to 3,
1: 4.0 evaluates to 4, and
1: 1.0e-11 evaluates to 9.9999999999999994e-12.
1: [  FAILED  ] leetcode24.assertFail (0 ms)
1: [ RUN      ] leetcode24.expextFail
1: ../test/test_leetcode24.cpp:32: Failure
1: The difference between res and 4.0 is 1, which exceeds 1.0e-11, where
1: res evaluates to 3,
1: 4.0 evaluates to 4, and
1: 1.0e-11 evaluates to 9.9999999999999994e-12.
1: ../test/test_leetcode24.cpp:34: Failure
1: The difference between res and 4.0 is 1, which exceeds 1.0e-11, where
1: res evaluates to 3,
1: 4.0 evaluates to 4, and
1: 1.0e-11 evaluates to 9.9999999999999994e-12.
1: [  FAILED  ] leetcode24.expextFail (0 ms)
1: [----------] 3 tests from leetcode24 (0 ms total)
1:
1: [----------] Global test environment tear-down
1: [==========] 3 tests from 1 test case ran. (0 ms total)
1: [  PASSED  ] 1 test.
1: [  FAILED  ] 2 tests, listed below:
1: [  FAILED  ] leetcode24.assertFail
1: [  FAILED  ] leetcode24.expextFail
1:
1:  2 FAILED TESTS
1/1 Test #1: test .............................***Failed    0.04 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.06 sec

可以看到leetcode24.assertFail有一处失败,而leetcode24.expextFail有两处失败。这 验证 ASSERT断言失败后续不会再执行,而EXCEPT断言失败后续还会继续执行。

TEST_F宏

TEST_F宏的作用在于帮助很多类似的处理进行批量测试。如果我们使用的测试集需要使用一些相似的数据呢?或者有些相似的检查方法?这时就需要用到测试夹具和TEST_F宏配合了。

测试夹具和TEST_F宏 的最大的作用就在于测试开始之前和测试完成之后可以执行对应的函数,SetUpTearDown 两个虚函数。

#include "sample3-inl.h"
#include "gtest/gtest.h"

// To use a test fixture, derive a class from testing::Test.
class QueueTest : public testing::Test {
 protected:  // You should make the members protected s.t. they can be
             // accessed from sub-classes.

  // virtual void SetUp() will be called before each test is run.  You
  // should define it if you need to initialize the varaibles.
  // Otherwise, this can be skipped.
  virtual void SetUp() {
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // virtual void TearDown() will be called after each test is run.
  // You should define it if there is cleanup work to do.  Otherwise,
  // you don't have to provide it.
  //
  // virtual void TearDown() {
  // }

  // A helper function that some test uses.
  static int Double(int n) {
    return 2*n;
  }

  // A helper function for testing Queue::Map().
  void MapTester(const Queue<int> * q) {
    // Creates a new queue, where each element is twice as big as the
    // corresponding one in q.
    const Queue<int> * const new_q = q->Map(Double);

    // Verifies that the new queue has the same size as q.
    ASSERT_EQ(q->Size(), new_q->Size());

    // Verifies the relationship between the elements of the two queues.
    for ( const QueueNode<int> * n1 = q->Head(), * n2 = new_q->Head();
          n1 != NULL; n1 = n1->next(), n2 = n2->next() ) {
      EXPECT_EQ(2 * n1->element(), n2->element());
    }

    delete new_q;
  }

  // Declares the variables your tests want to use.
  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

// When you have a test fixture, you define a test using TEST_F
// instead of TEST.

// Tests the default c'tor.
TEST_F(QueueTest, DefaultConstructor) {
  // You can access data in the test fixture here.
  EXPECT_EQ(0u, q0_.Size());
}

// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {
  int * n = q0_.Dequeue();
  EXPECT_TRUE(n == NULL);

  n = q1_.Dequeue();
  ASSERT_TRUE(n != NULL);
  EXPECT_EQ(1, *n);
  EXPECT_EQ(0u, q1_.Size());
  delete n;

  n = q2_.Dequeue();
  ASSERT_TRUE(n != NULL);
  EXPECT_EQ(2, *n);
  EXPECT_EQ(1u, q2_.Size());
  delete n;
}

// Tests the Queue::Map() function.
TEST_F(QueueTest, Map) {
  MapTester(&q0_);
  MapTester(&q1_);
  MapTester(&q2_);
}

可以看到我们首先需要从 testing::Test 来派生一个自己的测试类QueueTest,在这个类里你可以定义一些必要的成员变量或者辅助函数,还可以定义 SetUpTearDown 两个虚函数,来指定每个测试集运行前和运行后应该做什么。后面测试用例的每个测试集应该使用 TEST_F 宏,第一个参数是我们定义的类名,第二个是测试集的名称。
这样就可以避免在很多重复的测试的时候需要不断重复初始化相同的内容了,以及可以利用类的函数来写一些复杂的运行逻辑。

参考:
https://github.com/google/googletest/blob/main/googletest/samples/sample6_unittest.cc
https://github.com/AngryHacker/articles/blob/master/src/open_source_components/google_gtest.md

我的博客园:https://www.cnblogs.com/swx123
我的github(代码一般都放在这里):https://github.com/578223592

标签:google,入门,ASSERT,gtest,EXPECT,val2,test,leetcode24,val1
From: https://www.cnblogs.com/swx123/p/17767179.html

相关文章

  • JVM入门笔记
    1.JVM介绍Java虚拟机(JavaVirtualMachine简称JVM)是运行所有Java程序的抽象计算机,是Java编程语言的运行环境,它是Java最具吸引力的特性之一。JVM本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件,这就是Java跨平台的本质原因。由于Java是开放的,有越来越多的编程......
  • 自邮之翼Java Web开发入门学习之旅 阶段一
    这个阶段的任务是“完成开发环境的安装和配置,并基于JSP实现一个“HellotheWorld”页面。主要使用的开发环境为:IntellijJava,进行开发前需要完成的环境配置如下:·配置java环境(JDK17)·配置maven环境(apache-maven-3.9.4)·配置Tomcat环境(apache-tomcat-10.1.13)以上均需要......
  • 为什么Google在JSON响应中添加了`while(1);`?
    内容来自DOChttps://q.houxu6.top/?s=为什么Google在JSON响应中添加了while(1);?为什么Google在(私有)JSON响应前加上while(1);?例如,这是在Google日历中打开和关闭日历时的响应:while(1);[['u',[['smsSentFlag','false'],['hideInvitations','false......
  • OpenGL入门——矩阵变换与坐标系统
    一、OpenGL的数学库GLM向量和矩阵的运算就不作说明了,直接介绍OpenGL中如何使用矩阵变换。GLM(官网:OpenGLMathematics(g-truc.net))是OpenGL Mathematics的缩写,它是一个只有头文件的库,也就是说只需包含对应的头文件就行了,不用链接和编译。把头文件的根目录复制到项目的includes......
  • Spark入门指南:从基础概念到实践应用全解析
    本文已收录至GitHub,推荐阅读......
  • Scala语言入门:初学者的基础语法指南
    本文已收录至GitHub,推荐阅读......
  • HBase入门指南
    本文已收录至GitHub,推荐阅读......
  • Google – Cloud Translation API
    前言通常网站内容翻译,我们都不推荐使用GoogleTranslate。但网站中一些不那么重要的内容确实可以用GoogleTranslate。比如CustomerReviews。这篇是续 GoogleMapsEmbedAPI&JavaScriptAPIGoogle–ReviewsYouTubeDataAPI又一篇关于GoogleCloudAPI的教程。......
  • 每个后端都应该了解的OpenResty入门以及网关安全实战
    简介在官网上对OpenResty是这样介绍的(http://openresty.org):“OpenResty是一个基于Nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。”“......
  • aFlex脚本入门
    aFlex脚本入门对于A10的aFelx脚本,相信很多人都知道,甚至用过,但是实际上很多工程师在各种项目中的使用可能都是按照模板进行修改,虽然能ok,但是却缺乏对aFelx脚本本质上的了解,所以在用户实际场景与脚本应用场景不完全一致的时候,就会碰到问题,不知如何修改。而更多的技术人员或者用户更......