51Testing软件测试论坛

标题: 浅谈google开源单元测试框架Google Test(2) [打印本页]

作者: lsekfe    时间: 2023-3-14 13:06
标题: 浅谈google开源单元测试框架Google Test(2)
断言
  除了上面示例里的EXPECT_EQ,在gTest里有很多断言相关的宏。断言可以检查出某些条件的真假,因此,我们可以通过它来判断被测试的函数的成功与否。这里断言我们主要可以分为两类:
  ·以"ASSERT_"开头的断言,致命性断言(Fatal assertion)
  · 以"EXPECT_"开头的断言 ,非致命性断言(Nonfatal assertion)
  上面的两种断言会在断言条件不满足时会有区别,即当不满足条件时, "ASSERT_"断言会在当前函数终止,而不会继续执行下去;而"EXPECT_"则会继续执行。我们可以通过下面一个例子来理解下他们的区别。
  #include <iostream>
  #include <gtest/gtest.h>
  int add(int a, int b)
  {
      return a + b;
  }
  int sub(int a, int b)
  {
      return a - b;
  }
  TEST(testcase, test_expect)
  {
      std::cout << "------ test_expect start-----" << std::endl;
      std::cout << "add function start" << std::endl;
      EXPECT_EQ(add(1,2), 2);
      std::cout << "add function end" << std::endl;
      std::cout << "sub function start" << std::endl;
      EXPECT_EQ(sub(1,2), -1);
      std::cout << "sub function end" << std::endl;
      std::cout << "------ test_expect end-----" << std::endl;
  }
  TEST(testcase, test_assert)
  {
      std::cout << "------ test_assert start-----" << std::endl;
      std::cout << "add function start" << std::endl;
      ASSERT_EQ(add(1,2), 2);
      std::cout << "add function end" << std::endl;
      std::cout << "sub function start" << std::endl;
      ASSERT_EQ(sub(1,2), -1);
      std::cout << "sub function end" << std::endl;
      std::cout << "------ test_assert end-----" << std::endl;
  }
  int main(int argc, char **argv)
  {  
      testing::InitGoogleTest(&argc, argv);  
      return RUN_ALL_TESTS();
  }


  从下面的运行结果上看,assert断言检查出被测函数add不满足条件,所以程序就没有继续执行下去;而expect虽然检查出被测试函数add不满足条件,但是程序还是继续去测试sub函数。

  上面的示例用到的都是判断相等条件的断言,还有其他条件检查的断言。主要可以分为布尔检查,数值比较检查,字符串检查,浮点数检查,异常检查等等。下面我们逐一认识这些断言。
  布尔检查
  布尔检查主要用来检查布尔类型数据,检查其条件是真还是假。

  数值比较检查
  数值比较检查主要用来比较两个数值之间的大小关系,这里有两个参数。

  字符串检查
  字符串检查主要用来比较字符串的内容。

  浮点数检查
  对于浮点数来说,因为其精度原因,我们无法确定其是否完全相等,实际上对于浮点数我比较两个浮点数近似相等。

  异常检查
  异常检查可以将异常转换成断言的形式。

  除了上面的一些类型的断言,还有一切其他的常用断言。
  显示成功或失败
  这一类断言会在测试运行中标记成功或失败。它主要有三个宏:
  ·SUCCED():标记成功。
  · FAIL() : 标记失败,类似ASSERT断言标记致命错误;
  · ADD_FAILURE():标记,类似EXPECT断言标记非致命错误。
  #include <iostream>
  #include <gtest/gtest.h>
  int divison(int a, int b)
  {
      return a / b;
  }
  TEST(testCaseTest, test0)
  {
      std::cout << "start test 0" << std::endl;
      SUCCEED();
      std::cout << "test pass" << std::endl;
  }
  TEST(testCaseTest, test1)
  {
      std::cout << "start test 1" << std::endl;
      FAIL();
      std::cout << "test fail" << std::endl;
  }
  TEST(testCaseTest, test2)
  {
      std::cout << "start test 2" << std::endl;
      ADD_FAILURE();
      std::cout << "test fail" << std::endl;
  }
  int main(int argc, char **argv)
  {  
      testing::InitGoogleTest(&argc, argv);  
      return RUN_ALL_TESTS();
  }



  执行结果如下:

  死亡测试
  死亡测试是用来检测测试程序是否按照预期的方式崩溃。

  #include <iostream>
  #include <gtest/gtest.h>
  int divison(int a, int b)
  {
      return a / b;
  }
  TEST(testCaseDeathTest, test_div)
  {
      EXPECT_DEATH(divison(1, 0), "");
  }
  int main(int argc, char **argv)
  {  
      testing::InitGoogleTest(&argc, argv);  
      return RUN_ALL_TESTS();
  }


  上面这个例子就是死亡测试,其运行结果如下,这里需要注意的是test_case_name如果使用DeathTest为后缀,gTest会优先运行。

  测试事件
  在学习测试事件之前,我们先来了解下三个概念,它们分别是测试程序,测试套件,测试用例
  ·测试程序是一个可执行程序,它有一个测试程序的入口main函数。
  · 测试用例是用来定义需要验证的内容。
  · 测试套件是测试用例的集合,运行测试。
  我们回过来看测试事件,在GTest中有了测试事件的这个机制,就能能够在测试之前或之后能够做一些准备/清理的操作。根据事件执行的位置不同,我们可将测试事件分为三种:
  · TestCase级别测试事件:这个级别的事件会在TestCase之前与之后执行;
  · TestSuite级别测试事件:这个级别的事件会在TestSuite中第一个TestCase之前与最后一个TestCase之后执行;
  · 全局测试事件:这是级别的事件会在所有TestCase中第一个执行前,与最后一个之后执行。
  这些测试事件都是基于类的,所以需要在类上实现。下面我们依次来学习这三种测试事件。
  TestCase测试事件
  TestCase测试事件,需要实现两个函数SetUp()和TearDown()。
  · SetUp()函数是在TestCase之前执行。
  · TearDown()函数是在TestCase之后执行。
  这两个函数是不是有点像类的构造函数和析构函数,但是切记他们并不是构造函数和析构函数,只是打个比方才这么说而已。我们可以借助下面的代码示例来加深对它的理解。这两个函数是testing::Test的成员函数,我们在编写测试类时需要继承testing::Test。
  #include <iostream>
  #include <gtest/gtest.h>
  class calcFunction
  {
  public:
      int add(int a, int b)
      {
          return a + b;
      }
      int sub(int a, int b)
      {
          return a - b;
      }
  };
  class calcFunctionTest : public testing::Test
  {
  protected:
      virtual void SetUp()
      {
          std::cout << "--> " << __func__ << " <--" <<std::endl;
      }
      virtual void TearDown()
      {
          std::cout << "--> " << __func__ << " <--" <<std::endl;
      }
      calcFunction calc;
  };
  TEST_F(calcFunctionTest, test_add)
  {
      std::cout << "--> test_add start <--" << std::endl;
      EXPECT_EQ(calc.add(1,2), 3);
      std::cout << "--> test_add end <--" << std::endl;
  }
  TEST_F(calcFunctionTest, test_sub)
  {
      std::cout << "--> test_sub start <--" << std::endl;
      EXPECT_EQ(calc.sub(1,2), -1);
      std::cout << "--> test_sub end <--" << std::endl;
  }
  int main(int argc, char **argv)
  {  
      testing::InitGoogleTest(&argc, argv);  
      return RUN_ALL_TESTS();
  }


  测试结果如下,两个函数都是是在每个TestCase(test_add和test_sub)之前和之后执行。







欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2