当前位置: 首页 > Linux

CICD实战—服务自动化测试

时间:2023-04-06 02:44:15 Linux

简介近年来随着微服务、容器、云计算的发展,DevOps、CI/CD等概念越来越多地进入人们的视野。许多开发团队希望应用这些概念来提高软件质量和开发效率。工欲善其事,必先利其器。什么样的工具可以满足开发者的需求?TARS作为优秀的开源微服务开发和运行集成平台,具有多语言、高性能、敏捷研发、高可用等特点。那么TARS能否完美支持DevOps理念呢?在上一篇文章中,我们学习了如何将开源CI工具Jenkins与TARS集成,实现TARS服务的自动化构建和部署。软件测试是软件开发过程中必不可少的一步。在上一篇文章的基础上,本文将通过一个完整的实践来展示如何通过Jenkins与TARS的集成实现TARS服务的自动化单元测试。目录什么是单元测试环境准备修改项目创建测试项目修改Jenkins项目配置自动化测试什么是单元测试随着微服务、容器、云计算的发展,近年来DevOps、CI/CD等概念越来越多地体现在大家的视野中。DevOps是一种流行的软件开发方法,将持续开发、持续测试、持续集成、持续部署、持续监控融入到软件开发的生命周期中,以提高软件开发质量。几乎所有顶级公司都在使用它。TARS作为优秀的开源微服务开发和运行集成平台,具有多语言、高性能、敏捷研发、高可用等特点。通过将开源CI工具Jenkins与TARS集成,可以实现TARS服务开发的自动化测试,减少开发和测试人员的工作量。限于篇幅,本文只关注自动化单元测试。软件测试是软件开发过程中必不可少的一步,单元测试是软件测试的最基本形式。在单元测试中,单元可以指代代码中的模块、函数或类;单元测试就是为每个单元编写测试用例,检查单元的正确性,测试逻辑是否正确,确保每个单元的行为符合预期。因此,单元测试的加入可以大大降低软件或服务上线后出现问题的概率。环境准备本文基于上一篇文章使用的TarsCppCIDemo项目,使用GoogleTest作为单元测试框架。在实际项目中,请根据自己的需要选择测试框架。安装GoogleTestGoogleTest是Google开源的一套C++测试框架,可以很方便的进行单元测试。接下来,我们在部署了Jenkins的机器上安装框架。GoogleTest的GitHub仓库地址为:https://github.com/google/googletest,可以直接克隆然后构建安装。这里我们安装的是稳定版,点击GitHub页面右侧的Release可以查看历史发布的版本。本文截稿前最新版本为1.10.0,下载安装命令如下wgethttps://github.com/google/googletest/archive/release-1.10.0.tar.gztar-zxvfrelease-1.10.0.tar.gzcdgoogletest-release-1.10.0mkdirbuildcdbuildcmake..makemakeinstall至此,GoogleTest安装完成。安装xUnit插件xUnit是Jenkins平台的一个插件,可以用来读取单元测试结果,支持包括GoogleTest在内的多种测试框架。打开Jenkins的管理页面,进入SystemManagement->PluginManagement->OptionalPlugins,在搜索框中搜索xUnit,在出现的结果中选择xUnitplugin,直接点击Install,等待Jenkins安装完成并重启。修改项目现在回到我们之前创建的Demo项目,我们在项目的HelloServer中添加几个接口和一个计数类,实现一个简单的计数服务。通过tars文件的定义修改Hello.tars服务的接口。我们编辑Hello.tars,在其中添加三个接口,分别是增加计数、减少计数和获取当前计数值。修改后的Hello.tars如下可以看到除了自动生成的测试接口外,我们还增加了increment,decrement,getCount三个接口,这三个接口都返回count,也就是计数的结果。在项目根目录TarsCppCIDemo,进入HelloServer/src目录,我们运行脚本tars2cpp将Hello.tars转换成对应的头文件Hello.h。cdHelloServer/src/usr/local/tars/cpp/tools/tars2cppHello.tars修改HelloImp.h然后我们编辑接口实现文件的头文件HelloImp.h,在类HelloImp中添加三个接口声明:/***@paramcountout返回计数值*@return服务状态码*/virtualintincrement(int&count,tars::TarsCurrentPtrcurrent);/***@paramcountout返回计数值*@return服务状态码*/virtualintdecrement(int&count,tars::TarsCurrentPtrcurrent);/***@paramcountout返回计数值*@return服务状态码*/virtualintgetCount(int&count,tars::TarsCurrentPtrcurrent);createnewCounterclassconnection接下来,我们通过新建一个Counter类来实现计数器的功能。TarsCpp的公共组件中提供了单件模板组件TC_Singleton。我们直接继承这个类,Counter.h如下:#ifndef__COUNTER_H_#define__COUNTER_H_#include"util/tc_singleton.h"#include"util/tc_thread.h"#include"util/tc_thread_rwlock.h"//A简单单调counter.classCounter:publictars::TC_Singleton{private:intcounter_;tars::TC_ThreadRWLockerrwlocker_;public://创建一个从0开始的计数器。Counter():counter_(0){}//返回计数值,对计数执行+1intIncrement();//返回计数值,对计数执行-1intDecrement();//返回当前计数值intGetCount();};#endif//__COUNTER_H_其中TC_ThreadRWLocker是TarsCpp工具组件提供的读写锁类。更多TarsCpp公共组件可以在TarsCpp/util/include/util查看其定义和使用。接下来是Counter.cpp#include"Counter.h"intCounter::Increment(){tars::TC_ThreadWLockwlock(rwlocker_);returncounter_++;}intCounter::Decrement(){if(counter_==0){//为0时直接返回tars::TC_ThreadRLockrlock(rwlocker_);returncounter_;}else{tars::TC_ThreadWLockwlock(rwlocker_);returncounter_--;}}intCounter::GetCount(){tars::TC_ThreadRLockrlock(rwlocker_);returncounter_;}这样就完成了Counter类的创建。修改HelloImp.cpp接下来我们添加三个接口的实现#include"HelloImp.h"#include"servant/Application.h"#include"Counter.h"usingnamespacestd;voidHelloImp::initialize(){}voidHelloImp::destroy(){}intHelloImp::increment(int&count,tars::TarsCurrentPtrcurrent){count=Counter::getInstance()->Increment();return0;}intHelloImp::decrement(int&count,tars::TarsCurrentPtrcurrent){count=Counter::getInstance()->Decrement();return0;}intHelloImp::getCount(int&count,tars::TarsCurrentPtrcurrent){count=Counter::getInstance()->获取计数();return0;}至此,我们就完成了三个接口逻辑的添加。创建测试项目接下来我们创建一个测试项目,在HelloServer目录下新建test目录,并在test中创建app_ut.cpp和CMakeLists.txt,目录结构如下HelloServer├──build├──CMakeLists。txt├──src│├──CMakeLists.txt│├──Counter.cpp│├──Counter.h│├──Hello.h│├──HelloImp.cpp│├──HelloImp.h│├──HelloServer.cpp│├─HelloServer.h│└──Hello.tars└──test├──app_ut.cpp└──CMakeLists.txt添加测试用例GoogleTest包含丰富的断言,可以方便单元测试,关于GoogleTest的使用你可以阅读它的使用文档。我们在app_ut.cpp中添加测试流程和测试用例,如下,为Counter类添加三个测试用例,测试的执行顺序按照定义的顺序执行。其中EXPECT_EQ是用来判断两个值是否相等的断言。如果不相等,则会触发错误,并在测试结果中输出。#defineprivatepublic#include"gtest/gtest.h"#include"Counter.h"namespace{//测试Increment()方法。TEST(Counter,Increment){Counter*c=Counter::getInstance();EXPECT_EQ(0,c->Increment());EXPECT_EQ(1,c->Increment());EXPECT_EQ(2,c->Increment());EXPECT_EQ(3,c->Increment());c->counter_=0;}//测试Decrement()方法。TEST(Counter,Decrement){Counter*c=Counter::getInstance();EXPECT_EQ(0,c->Decrement());EXPECT_EQ(0,c->Increment());EXPECT_EQ(1,c->Increment());EXPECT_EQ(2,c->Decrement());EXPECT_EQ(1,c->Decrement());c->counter_=0;}//测试GetCount()方法。TEST(Counter,GetCount){Counter*c=Counter::getInstance();EXPECT_EQ(0,c->GetCount());EXPECT_EQ(0,c->Increment());EXPECT_EQ(1,c->GetCount());EXPECT_EQ(1,c->Increment());EXPECT_EQ(2,c->GetCount());EXPECT_EQ(2,c->Decrement());EXPECT_EQ(1,c->GetCount());c->counter_=0;}}//namespace其中的#defineprivatepublic是单元测试中常用的宏替换,方便修改私有对象进行测试。Counter类是一个单例类。为了不影响其他测试用例,每个测试用例最后都将counter_设置为零。将CMakeLists.txt添加到测试用例中就完成了测试用例的创建,我们需要编译测试工程,生成可执行文件进行测试。编译框架可以根据自己的喜好选择。在这个例子中,我们使用cmake来管理代码编译。cmake的使用请参考官方文档。首先我们在test目录下添加CMakeLists.txt文件,内容如下。cmake_minimum_required(VERSION3.10)find_package(GTestREQUIRED)set(TARS_INC“/usr/local/tars/cpp/include”)set(TARS_LIB“/usr/local/tars/cpp/lib”)set(TARS_LIB_UTIL“${TARS_LIB}/libtarsutil.a")set(COUNTER_SRC"${PROJECT_SOURCE_DIR}/src/Counter.cpp")include_directories(${GTEST_INCLUDE_DIRS}${TARS_INC}${PROJECT_SOURCE_DIR}/src)link_directories(${TARS_LIB})add_executable(app_ut${COUNTER_SRC}app_ut.cpp)target_link_libraries(app_ut/usr/local/tars/cpp/lib/libtarsutil.a${GTEST_BOTH_LIBRARIES}pthread)gtest_discover_tests(app_utXML_OUTPUT_DIR"${PROJECT_SOURCE_DIR}/build/test_result")cmake0后3.支持版本中增加了gtest,增加了gtest_discover_tests,可以直接添加测试,但是在实际使用中发现该方法的XML_OUTPUT_DIR参数只在3.18版本有效,低于3.18的版本无法生成测试结果文件指定的路径。因此,建议在cmake版本低于3.18的设备上执行构建的测试可执行文件来运行测试用例,后续章节会详细介绍。修改项目mainCMakeLists.txt使用TarsCpp项目生成工具生成项目时,默认生成项目编译的CMakeLists.txt。接下来,我们将修改此文件以在构建项目时编译测试用例。在上一节中,我们已经完成了测试用例CMakeLists.txt的编写。在项目的主CMakeLists.txt文件中,添加一个子目录即可,如下,添加enable_testing()和add_subdirectory(test)。cmake_minimum_required(版本2.8.8)项目(Demo-DemoServer)选项(TARS_MYSQL“mysql选项”ON)选项(TARS_SSL“ssl选项”OFF)选项(TARS_HTTP2“http2选项”OFF)if(WIN32)包括(c:tarscppmakefiletars-tools.cmake)else()include(/usr/local/tars/cpp/makefile/tars-tools.cmake)endif()####你可以:cdbuild;cmake..-DTARS_WEB_HOST={你的虚拟主机}set(TARS_WEB_HOST""CACHESTRING"setwebhost")IF(TARS_WEB_HOSTSTREQUAL"")set(TARS_WEB_HOST"http://tars.test.com")ENDIF()include_directories(/usr/local/tars/cpp/thirdparty/include)link_directories(/usr/local/tars/cpp/thirdparty/lib)#include_directories(/home/tarsprotol/App/OtherServer)enable_testing()#启用测试add_subdirectory(src)add_subdirectory(test)#addtest#target_link_libraries(mysqlclientsslcryptonghttp2-static)接下来按照TarsCpp项目的编译方式编译构建项目。有两种运行测试用例的方法。大家可以根据自己的需求选择一个,直接使用cmake集成的测试功能即可。构建完成后,直接在构建目录下执行maketest即可。要求cmake版本为3.18。运行测试用例以编译和构建可执行文件。执行项目构建命令后,会在build/bin中生成测试用例可执行文件。在这个项目中,就是app_ut,可以直接执行。适用于cmake2.8.8及以上版本。通常添加参数--gtest_output="xml:test*.xml"输出测试结果,如下/bin/app_ut--gtest_output="xml:testresults.xml"修改Jenkins项目配置本节将介绍如何配置Jenkins任务,可以自动执行项目中的单元测试,并获取测试结果。在修改构建shell命令构建过程的脚本中,我们只需要添加运行测试用例的命令即可。按照上一节运行测试用例的部分,根据cmake版本选择任意命令。以测试用例的可执行文件为例,修改后的构建脚本如下#!/bin/shmkdir-pHelloServer/buildcdHelloServer/buildcmake..make-j4makeHelloServer-tar./bin/app_ut--gtest_output="xml:test_results.xml"Addpost-buildoperation点击??Addpost-buildoperationsteps选择PublishxUnittestresultreport,添加post-buildsteps,如下,然后在ReportType中点击Add,选择GoogleTest,填写匹配模式在Pattern中匹配之前build过程中生成的xml文件,可以直接使用pattern**/*.xml匹配所有的xml文件,也可以根据命名方式自定义模式匹配,如下,最后点击Save完成Jenkins任务的配置。自动化测试我们已经完成了自动化测试所需的配置,就像自动化构建和部署一样,接下来我们只需要将项目推送到GitHub仓库,就可以触发自动化构建和测试过程。构建完成后,我们可以查看本次构建的测试结果。如下,我们就完成了基于Jenkins的TarsCpp项目的自动化单元测试。其他语言大致相同。选择自己熟悉的测试框架和Jenkins上对应的插件。能。总结本文在上一篇文章的基础上,介绍如何将Jenkins与TARS集成,实现TARS服务的自动化单元测试,在软件开发过程中帮助提升软件质量。TARS能够在兼顾易用性和高性能的同时,快速构建系统并自动生成代码,帮助开发者和企业以微服务的形式快速构建属于自己的稳定可靠的分布式应用,让开发者只关注业务逻辑,提高运维能力效率。多语言、敏捷研发、高可用、高效运行等特点使TARS成为企业级产品。TARS微服务助你数字化转型,欢迎访问:TARS官网:https://TarsCloud.orgTARS源码:https://github.com/TarsCloudLinux基金会官方微服务免费课程:https://www.edx.org/course/bu...获取《TARS官方培训电子书》:https://wj.qq.com/s2/6570357/...或扫码获取: