设计网站软件开发,大连比较好的网站公司吗,建设网站还要云服务器吗,做网站的软件是哪个一、简介
1. 引言 在开发过程中#xff0c;如何保证代码的质量以及程序的正确性成为了我们亟需解决的问题#xff0c;其中测试用例成为了不必可少的一部分。测试用例不仅可以帮助我们验证代码的正确性#xff0c;还能帮助我们捕获潜在的错误#xff0c;提高代码的可靠性和…
一、简介
1. 引言 在开发过程中如何保证代码的质量以及程序的正确性成为了我们亟需解决的问题其中测试用例成为了不必可少的一部分。测试用例不仅可以帮助我们验证代码的正确性还能帮助我们捕获潜在的错误提高代码的可靠性和可维护性。然而手动编写和执行测试用例可能会非常繁琐和耗时因此我们引入了 Google Test 框架。 2. Google Test 框架 Google Test (gtest) 是一个由 Google 开发的流行的 C 单元测试框架。它为开发者提供了一套强大的工具和功能用于编写、组织和运行测试用例。gtest 框架支持测试驱动开发Test-Driven DevelopmentTDD和行为驱动开发Behavior-Driven DevelopmentBDD方法。 具有以下主要功能和特点
简单易用 gtest 框架提供了简洁而直观的语法和 API使得编写测试用例变得简单易懂。通过使用宏和断言开发者可以轻松地定义测试用例和验证预期结果
丰富的断言 gtest 框架提供了一组丰富的断言宏用于验证测试结果。这些断言宏包括比较值、检查条件、抛出异常等功能可以满足各种测试需求
灵活的测试组织 gtest 框架允许开发者将测试用例组织成测试套件Test Suite并可以嵌套多个测试套件。这样可以更好地组织和管理测试用例提高测试代码的可读性和可维护性
测试夹具支持 gtest 框架提供了测试夹具Test Fixture 的概念允许开发者在多个测试用例之间共享资源或设置环境。通过派生测试夹具类并重写 SetUp() 和 TearDown() 方法开发者可以方便地进行资源的初始化和清理操作
完善的编译及平台支持 gtest 框架支持 C11 及以上的 C 标准支持 Linux、MacOS、Windows 等众多平台支持 gcc5.0、clang5.0、MSVC2015 编译器支持 Bazel 以及 cmake 构建工具
丰富的测试报告 gtest 框架生成详细的测试报告显示每个测试用例的运行结果包括通过的用例和失败的用例。如果断言失败报告会提供失败的原因和位置方便开发者快速定位问题。
二、Google Test 框架集成
1. 系统安装 gtest 测试框架 Ubuntu
sudo apt install libgtest-devCentos
https://pkgs.org/search/?qgtest # 下载gtest-devel.rpm
rpm -ivh gtest-devel.rpm # 安装rpm包2. CMake 项目集成 Cmakelists.txt 文件中添加以下代码
enable_testing() # 开启测试否则无法执行make test
add_executable(add_test_exe add_test.cpp) # 添加可执行程序
target_link_libraries(add_test_exe PRIVATE gtest pthread) # 链接gtest库
add_test(add_test_exe ${CMAKE_BINARY_DIR}/add_test_exe) # 添加测试保证make test可以执行该测试用例3. 简单 Demo add_test.cpp #include gtest/gtest.hint add(int a, int b) {return a b;
}TEST(TEST_ADD, UNSIGNED_INT_VALUE) { int result add(100, 200); EXPECT_EQ(result, 300); result add(200, 300); EXPECT_NE(result, 400);
}int main() {testing::InitGoogleTest();return RUN_ALLTESTS();
}4. 编译运行
~/Projects/Test master 625 !5592 ?1 ) mkdir build cd build cmake .. make -j4
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler:/usr/bin/cc
-- Check for working CXX compiler:/usr/bin/c
-- Configuring done
-- Generating done
-- Build files have been written to:/home/limstor/Projects/Test/build
Scanning dependencies of target add_test_exe
[50%] Building CXX object CMakeFiles/add_test_exe.dir/aadd_test.cpp.o
[100%] Linking CXX executable add_test_exe
[100%] Built target add_test_exe
~/Projects/Test/build master 625 !5592 ?2)/add_test_exe
[] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from TEST_ADD
[ RUN ]TEST_ADD.UNSIGNED_INT_VALUE
[ OK ]TEST_ADD.UNSIGNED_INT_VALUE (O ms)
[----------] 1 test from TEST_ADD (0 ms total)[----------] Global test environment tear-down
[] 1 test from 1 test suite ran. (0ms total)
[ PASSED ] 1 test.三、Google Test - 测试宏
1. TEST 宏 说明该宏定义用来测试其内部代码其内部断言决定最终的测试结果。 使用方式
TEST(TestSuiteName, TestName) {... statements ...
}用途针对多个用例之间不需要进行数据共用的测试场景。
示例
int add(int a, int b) {return a b;
}TEST(TEST_ADD, UNSIGNED_INT_VALUE) {int result add(100, 200);EXPECT_EQ(result, 300);result add(200, 300);EXPECT_NE(result, 400);
}TEST(TEST_ADD, NEGATIVE_INT_VALUE) {int result add(-100, -200);EXPECT_EQ(result, -300);result add(-200, -300);EXPECT_NE(result, -400);
}2. TEST_F 宏 说明该宏定义用来对 TestFixtureName 类进行多样测试。 使用方法
TEST_F(TestFixtureName, TestName) {... statements ...
}用途针对多个用例之间需要进行数据共用的测试场景用于多样测试也有助于简化测试代码。
使用示例
class Student {
public:Student(int id, std::string name): id_(id), name_(name) {};~Student() default;void SetAge(int age) { age_ age; }int GetAge() const { return this-age_; }void SetScore(int score) { score_ score; }int GetScore() const { return this-score_; }
private:int id_;std::string name_;int age_;int score_;
};
class StudentTest : public testing::Test {
protected:void SetUp() override {student new Student(1234, Tom);}void TearDown() override {delete student;}Student* student;
};
TEST_F(StudentTest, SET_AGE_TEST) {student-SetAge(16);int age student-GetAge();EXPECT_EQ(age, 16);
}
TEST_F(StudentTest, SET_SCORE_TEST) {student-SetScore(99);int score student-GetScore();ASSERT_EQ(score, 99);
}
int main() {testing::InitGoogleTest();return RUN_ALL_TESTS();
}3. TEST_P 宏 说明该宏定义用来参数化测试。 使用方式
TEST_P(TestFixtureName, TestName) {... statements ...
}用途当待测试方法的行为取决于传入的参数时而且这些参数的不同组合有多种 而你又不想为此写多个类似的 test case 时可以用参数化测试。 示例 struct TestData {int a;int b;int result;char type;
};
class CalculateTest : public ::testing::TestWithParamTestData {
protected:void checkData() {int a GetParam().a;int b GetParam().b;int result GetParam().result;switch (GetParam().type) {case :EXPECT_EQ(a b, result);break;case -:EXPECT_EQ(a - b, result);break;case *:EXPECT_EQ(a * b, result);break;case /:EXPECT_EQ(a / b, result);break;default:break;}}
};
TEST_P(CalculateTest, Test) {checkData();
}
INSTANTIATE_TEST_SUITE_P(TestMyClassParams,CalculateTest,::testing::Values(TestData{100, 200, 300, },TestData{20, 5, 15, -},TestData{5, 6, 30, *},TestData{8, 2, 3, /}));
int main() {testing::InitGoogleTest();return RUN_ALL_TESTS();
}四、Google Test - 断言
断言对测试代码中的检查点进行检查。分为以下两种断言类型
ASSERT_*断言当检查点失败时退出当前函数EXPECT_*断言当检查点失败时继续往下执行。 布尔值检查 字符串类型检查 数值类型检查 返回成功或失败 返回成功或失败 谓词断言 浮点数检查 Windows 平台的 HRESULT 检查 类型检查 testing::StaticAssertTypeEq(); 类似模板中的编译检查
除以上 9 种断言使用方法外还可以在断言后增加自定义信息输出
EXPECT_EQ(a, b) Vectors x and y differ at index 五、Google Test - 事件机制
gtest 提供了多种事件机制
全局事件所有用例执行前后TestSuite 级别同一 TestSuite 的第一个用例前最后一个用例执行后TestCase 级别每个测试用例前后。 1. 全局事件 要实现全局事件必须写一个类继承 testing::Environment 类实现里面的 SetUp 和 TearDown 方法 SetUp() 方法在所有用例执行前执行 TearDown() 方法在所有用例执行后执行。
示例
class FooEnvironment : public testing::Environment {
public:virtual void SetUp() { std::cout Foo FooEnvironment SetUP std::endl; } virtual void TearDown() { std::cout Foo FooEnvironment TearDown std::endl; }
};注意在执行用例之前需要在 main 函数中通过 testing::AddGlobalTestEnvironment 方法将事件挂载进来。
示例
int main() { testing::AddGlobalTestEnvironment(new FooEnvironment); testing::InitGoogleTest(); return RUN_ALL_TESTS();}2. TestSuite 事件 要实现 TestSuite 事件必须写一个类继承 testing::Test 类实现 SetUpTestCase 和 TearDownTestCase 方法 SetUpTestCase() 方法在 TestSuite 里的第一个 TestCase 之前执行 TearDownTestCase() 方法在 TestSuite 里的最后一个 TestCase 之后执行。
示例 class FooTest : public testing::Test {protected: static void SetUpTestCase() {shared_resource_ new int(1234); } static void TearDownTestCase() { delete shared_resource_; shared_resource_ NULL; } int* shared_resource_;
};3. TestCase 事件
实现方法和 TestSuite 事件几乎一样只不过它是实现的 SetUp 和 TearDown 方法 (1) SetUp() 方法在每一个 TestCase 之前执行 (2) TearDown() 方法每一个 TestCase 之后执行。
示例 class FooCalcTest:public testing::Test {
protected:virtual void SetUp() {m_foo.Init(); } virtual void TearDown() { m_foo.Finalize(); } FooCalc m_foo;
};六、Google Test - 命令行参数
在测试用例二进制文件后执行以下参数
1. --gtest_list_tests
使用这个参数时将不会执行里面的测试用例而是输出测试用例的列表。
2. --gtest_filter
对执行的测试用例进行过滤支持通配符。 ? 单个字符 * 任意字符 - 排除如-a 表示除了 a : 取或如a:b 表示 a 或 b
比如下面的例子 ./foo_test 没有指定过滤条件运行所有用例
./foo_test --gtest_filter* 使用通配符*表示运行所有用例
./foo_test --gtest_filterFooTest.* 运行所有 TestSuiteName 为 FooTest 的用例
./foo_test --gtest_filter*Null*:*Constructor* 运行所有TestSuiteName或 TestName 包含 Null 或 Constructor 的用例。
./foo_test --gtest_filterFooTest.*-FooTest.Bar 运行所有 TestSuiteName 为 FooTest 的用例但是除了 FooTest.Bar 这个用例。3. --gtest_also_run_disabled_tests
执行用例时同时也执行被置为无效的测试用例(TestSuiteName 或 TestName 以 DISABLED 为前缀)。
4. --gtest_repeat[COUNT]
设置用例重复运行次数例如
–gtest_repeat1000 重复执行1000次即使中途出现错误。 –gtest_repeat-1 无限次数执行 –gtest_repeat1000 --gtest_break_on_failure 重复执行1000次并且在第一个错误发生时立即停止。这个功能对调试非常有用。 –gtest_repeat1000 --gtest_filterFooBar 重复执行1000次测试用例名称为FooBar的用例。
5. --gtest_color(yes|no|auto)
输出命令行时是否使用一些五颜六色的颜色。默认是 auto。
6. --gtest_print_time
输出命令行时是否打印每个测试用例的执行时间。默认是不打印。
7. --gtest_outputxml[:DIRECTORY_PATH|:FILE_PATH]
将测试结果输出到一个 xml 中 –gtest_outputxml: 不指定输出路径时默认为用例当前路径
–gtest_outputxml:/dir 指定输出到某个目录
–gtest_outputxml:~/dir/foo.xml 指定输出到~/dir/foo.xml。
如果不是指定了特定的文件路径gtest 每次输出的报告不会覆盖而会以数字后缀的方式创建。
8. --gtest_break_on_failure
调试模式下当案例失败时停止方便调试。
9. --gtest_throw_on_failure
当用例失败时以 C 异常的方式抛出。
10. --gtest_catch_exceptions
是否捕捉异常。gtest 默认是不捕捉异常的因此假如你的测试用例抛了一个异常很可能会弹出一个对话框这非常的不友好同时也阻碍了测试用例的运行。如果想不弹框可以通过设置这个参数来实现。如将 --gtest_catch_exceptions 设置为一个非零的数。
注意这个参数只在 Windows 平台下有效。