当前位置: 首页 > news >正文

网站建设账务处理属于什么费用一个网站怎么做关键词搜索

网站建设账务处理属于什么费用,一个网站怎么做关键词搜索,石家庄什么时候能解封,青岛北方现货交易平台点击蓝字关注我们来源于网络#xff0c;侵删前言测试是软件开发过程中一个必须的环节#xff0c;测试确保软件的质量符合预期。对于工程师自己来说#xff0c;单元测试也是提升自信心的一种方式。直接交付没有经过测试的代码是不太好的#xff0c;因为这很可能会浪费整个团…点击蓝字关注我们来源于网络侵删前言测试是软件开发过程中一个必须的环节测试确保软件的质量符合预期。对于工程师自己来说单元测试也是提升自信心的一种方式。直接交付没有经过测试的代码是不太好的因为这很可能会浪费整个团队的时间在一些原本早期就可以发现的问题上。而单元测试就是发现问题一个很重要的环节。本文以C语言为基础讲解如何进行单元测试并生成测试报告。在工具上我们会使用下面这些GCCCMakeGoogle Testgcovlcov演示项目为了方便本文的讲解我专门编写了一个演示项目作为代码示例。演示项目的源码可以在我的Github上获取paulQuei/gtest-and-coverage[1]。你可以通过下面几条命令下载和运行这个项目git clone https://github.com/paulQuei/gtest-and-coverage.git cd gtest-and-coverage ./make_all.sh要运行这个项目你的机器上必须先安装好前面提到的工具。如果没有请阅读下文以了解如何安装它们。如果你使用的是Mac系统下文假设你的系统上已经安装了brew[2]包管理器。如果没有请通过下面这条命令安装它/usr/bin/ruby -e $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)项目结构演示项目的目录结构如下. ├── CMakeLists.txt ├── googletest-release-1.8.1.zip ├── include │   └── utility.h ├── make_all.sh ├── src │   └── utility.cpp └── test└── unit_test.cpp这里演示的内容是以测试一个我们要提供的软件库为例讲解如何对其进行单元测试并生成测试报告。为了简单起见这个软件库只有一个头文件和一个实现文件。当然在实际上的项目中一个软件库会通常包含更多的文件不过这并不影响我们要说明的问题。演示项目中的文件说明如下文件名称说明make_all.sh入口文件会执行编译测试和生成报告等所有工作CMakeLists.txt项目的编译文件googletest-release-1.8.1.zipgoogle test源码压缩包utility.h待测试的软件库的头文件utility.cpp待测试的软件库的实现文件unit_test.cpp对软件库进行单元测试的代码测试环境演示项目在如下的环境中测试过。MacBook Pro操作系统macOS Mojave 10.14.1编译器Apple LLVM version 10.0.0 clang-1000.11.45.2CMakecmake version 3.12.1Google Test: 1.8.1lcov: lcov version 1.13Ubuntu操作系统Ubuntu 16.04.5 LTS编译器gcc Ubuntu 5.4.0-6ubuntu1~16.04.10 5.4.0 20160609CMakecmake version 3.5.1Google Test1.8.1lcovlcov version 1.12关于CMake为了简化编译的过程这里使用CMake作为编译工具。关于CMake的更多内容请参见请官网https://cmake.org[3]。关于如何安装CMake请参见这里Installing CMake[4]。另外你也可以通过一条简单的命令来安装CMakeMac系统brew install cmakeUbuntu系统sudo apt install cmake由于篇幅所限这里不打算对CMake做过多讲解读者可以访问其官网或者在网络上搜寻其使用方法。这里仅仅对演示项目中用到的内容做一下说明。演示项目中的CMakeLists.txt内容如下cmake_minimum_required(VERSION 2.8.11) ① project(utility) ②set(CMAKE_CXX_STANDARD 11) ③set(GTEST googletest-release-1.8.1) ④ include_directories(./include ${GTEST}/googletest/include/) link_directories(build/gtest/googlemock/gtest/)SET(CMAKE_CXX_FLAGS  ${CMAKE_CXX_FLAGS} --coverage) ⑤add_library(${CMAKE_PROJECT_NAME}_lib src/utility.cpp) ⑥add_executable(unit_test test/unit_test.cpp) ⑦ target_link_libraries(unit_test ${CMAKE_PROJECT_NAME}_lib gtest gtest_main pthread) ⑧以编号为序这段代码说明如下设置使用的CMake最低版本号为2.8.11。指定项目的名称为”utility”项目名称可以通过${CMAKE_PROJECT_NAME}进行引用。指定使用C11。这里的三行是编译google test并将其头文件路径和编译结果的库文件路径添加到环境中。因为后面在编译单元测试代码的时候需要用到。添加--coverage到编译器flag中这个参数是很重要的因为这是生成代码覆盖率所必须的。关于该编译参数的说明见这里Program Instrumentation Options[5]。编译我们的软件库这里将生成libutility_lib.a库文件。编译单元测试的可执行文件。单元测试的可执行文件需要链接我们开发的软件库以及google test的库。另外google test依赖了pthread所以这个库也需要。关于测试软件测试有很多种分类方式。从测试的级别来说可以大致分为单元测试集成测试系统测试这其中单元测试是最局部和具体的。它通常需要对代码中的每一个类和函数进行测试。单元测试通常由开发者完成需要针对代码逻辑进行测试。所以它是一种白盒测试[6]。关于xUnitxUnit是几种单元测试框架的总称。最早源于Smalltalk的单元测试框架SUnit它是由Kent Beck[7]开发的。除此之外还有针对Java语言的JUnit针对R语言的RUnit。在本文中我们使用Google开发的xUnit框架Google Test。Google Test介绍Google Test的项目主页在Github上Github: Google Test[8]。实际上这个项目中同时包含了GoogleTest和GoogleMock两个工具本文中我们只会讲解第一个。Google Test支持的操作系统包含下面这些LinuxMac OS XWindowsCygwinMinGWWindows MobileSymbian目前有很多的项目都使用了Google Test例如下面这些Chromium projects[9]LLVM[10]Protocol Buffers[11]OpenCV[12]tiny-dnn[13]编译Google Test关于如何编译Google Test请参见这里Generic Build Instructions[14]。为了便于读者使用我们在演示项目中包含了Google Test 1.8.1的源码压缩包。并且在CMake文件中同时包含了Google Test的编译和使用配置工作。如果使用演示项目读者将不需要手动处理Google Test的编译和安装工作。使用Google Test演示项目代码说明为了便于下文说明演示项目中包含了几个简单的函数。可以从这里下载源码以便查看其中的内容paulQuei/gtest-and-coverage[15]。演示项目中的软件库包含一个头文件和一个实现文件。头文件内容如下// utility.h#ifndef INCLUDE_UTILITY_ #define INCLUDE_UTILITY_enum CalcType {ADD,MINUS,MULTIPLE,DIVIDE };class Utility { public:int ArithmeticCalculation(CalcType op, int a, int b);double ArithmeticCalculation(CalcType op, double a, double b);bool IsLeapYear(int year); };#endif这个头文件说明如下头文件包含了三个函数前两个用来做int和double类型的四则运算。最后一个判断输入的年份是否是闰年。当然在实际的工程中前两个函数合并实现为一个泛型函数更为合适。但这里之所以分成两个是为了查看代码覆盖率所用。关于闰年说明如下能被4整除但不能被100整除的年份为普通闰年。能被100整除也同时能被400整除的为世纪闰年。其他都不是闰年。例如1997年不是闰年2000年是闰年2016年是闰年2100不是闰年。这三个函数的实现也不复杂// utility.cpp#include utility.h#include iostream #include limitsusing namespace std;int Utility::ArithmeticCalculation(CalcType op, int a, int b) {if (op  ADD) {return a  b;} else if (op  MINUS) {return a - b;} else if (op  MULTIPLE) {return a * b;} else {if (b  0) {cout  CANNO Divided by 0  endl;return std::numeric_limitsint::max();}return a / b;} }double Utility::ArithmeticCalculation(CalcType op, double a, double b) {if (op  ADD) {return a  b;} else if (op  MINUS) {return a - b;} else if (op  MULTIPLE) {return a * b;} else {if (b  0) {cout  CANNO Divided by 0  endl;return std::numeric_limitsdouble::max();}return a / b;} }bool Utility::IsLeapYear(int year) {if (year % 100  0  year % 400  0) {return true;}if (year % 100 ! 0  year % 4  0) {return true;}return false; }开始测试接下来我们就要对上面这些代码进行测试了。要使用Google Test进行测试整个过程也非常的简单。只要进行下面三部创建一个测试用的cpp文件为上面这个测试用的cpp文件编写Makefile或者CMake文件。同时链接待测试的软件库gtest库gtest_main库pthread库Google Test使用了这个库所以需要编写测试代码编译并运行测试的可执行程序。并且测试代码写起来也非常的简单像下面这样#include utility.h#include gtest/gtest.hTEST(TestCalculationInt, ArithmeticCalculationInt) {Utility util;EXPECT_EQ(util.ArithmeticCalculation(ADD, 1, 1), 2);EXPECT_EQ(util.ArithmeticCalculation(MINUS, 2, 1), 1);EXPECT_EQ(util.ArithmeticCalculation(MULTIPLE, 3, 3), 9);EXPECT_EQ(util.ArithmeticCalculation(DIVIDE, 10, 2), 5);EXPECT_GT(util.ArithmeticCalculation(DIVIDE, 10, 0), 999999999); }是的就是这么简单的几行代码就对整数四则运算的函数进行了测试。TEST后面所包含的内容称之为一条case通常我们会为每个函数创建一个独立的case来进行测试。一个测试文件中可以包含很多条case。同时一条case中会包含很多的判断例如EXPECT_EQ...。注意在做单元测试的时候保证每条case是独立的case之间没有前后依赖关系是非常重要的。当然测试代码中包含的判断的多少将影响测试结果的覆盖率。所以在编写每条case的时候我们需要仔细思考待测试函数的可能性有针对性的进行测试代码的编写。这段代码应该很好理解它分别进行了下面这些测试1 1 22 - 1 13 x 3 910 / 2 510 / 0 999999999你可能会发现这段代码里面甚至没有main函数。它也依然可以生成一个可执行文件。这就是我们链接gtest_main所起的作用。在实际的测试过程中你想判断的情况可能不止上面这么简单。下面我们来看看Google Test还能做哪些测试。测试判断Google Test对于结果的判断有两种形式ASSERT_*这类判断是Fatal的。一旦这个判断出错则直接从测试函数中返回不会再继续后面的测试。EXPECT_*这类判断是Nonfatal的。它的效果是如果某个判断出错则输出一个错误信息但是接下来仍然会继续执行后面的测试。可以进行的判断方法主要有下面这些布尔判断FatalNonfatal说明ASSERT_TRUE(condition)EXPECT_TRUE(condition)判断 condition 为 trueASSERT_FALSE(condition)EXPECT_FALSE(condition)判断 condition 为 false二进制判断FatalNonfatal说明ASSERT_EQ(expected, actual)EXPECT_EQ(expected, actual)判断两个数值相等ASSERT_NE(val1, val2)EXPECT_NE(val1, val2)val1 ! val2ASSERT_LT(val1, val2)EXPECT_LT(val1, val2)val1 val2ASSERT_LE(val1, val2)EXPECT_LE(val1, val2)val1 val2ASSERT_GT(val1, val2)EXPECT_GT(val1, val2)val1 val2ASSERT_GE(val1, val2)EXPECT_GE(val1, val2)val1 val2说明EQEQualNENot EqualLTLess ThanLELess EqualGTGreater ThanGEGreater Equal字符串判断FatalNonfatal说明ASSERT_STREQ(expected, actual)EXPECT_STREQ(expected, actual)两个C string相同ASSERT_STRNE(str1, str2)EXPECT_STRNE(str1, str2)两个C string不相同ASSERT_STRCASEEQ(exp, act)EXPECT_STRCASEEQ(exp, act)忽略大小写两个C string相同ASSERT_STRCASENE(str1, str2)EXPECT_STRCASENE(str1, str2)忽略大小写两个C string不相同浮点数判断FatalNonfatal说明ASSERT_FLOAT_EQ(exp, act)EXPECT_FLOAT_EQ(exp, act)两个float数值相等ASSERT_DOUBLE_EQ(exp, act)EXPECT_DOUBLE_EQ(exp, act)两个double数值相等ASSERT_NEAR(val1, val2, abs_err)EXPECT_NEAR(val1, val2, abs_err)val1和val2的差距不超过abs_err异常判断FatalNonfatal说明ASSERT_THROW(stmt, exc_type)EXPECT_THROW(stmt, exc_type)stmt抛出了exc_type类型的异常ASSERT_ANY_THROW(stmt)EXPECT_ANY_THROW(stmt)stmt抛出了任意类型的异常ASSERT_NO_THROW(stmt)EXPECT_NO_THROW(stmt)stmt没有抛出异常Test Fixture在某些情况下我们可能希望多条测试case使用相同的测试数据。例如我们的演示项目中每条case都会需要创建Utility对象。有些时候我们要测试的对象可能很大或者创建的过程非常的慢。这时如果每条case反复创建这个对象就显得浪费资源和时间了。此时我们可以使用Test Fixture来共享测试的对象。要使用Test Fixture我们需要创建一个类继承自Google Test中的::testing::Test。还记得我们前面说过我们要尽可能的保证每条测试case是互相独立的。但是当我们在多条case之间共享有状态的对象时就可能出现问题。例如我们要测试的是一个队列数据结构。有的case会向队列中添加数据有的case会从队列中删除数据。case执行的顺序不同则会导致Queue中的数据不一样这就可能会影响case的结果。为了保证每条case是独立的我们可以在每条case的执行前后分别完成准备工作和清理工作例如准备工作是向队列中添加三个数据而清理工作是将队列置空。这两项重复性的工作可以由::testing::Test类中的Setup和TearDown两个函数来完成。我们演示用的Utility类是无状态的所以不存在这个问题。因此这里我们仅仅在Setup和TearDown两个函数中打印了一句日志。使用Test Fixture后我们的代码如下所示class UtilityTest : public ::testing::Test {protected:void SetUp() override {cout  SetUp runs before each case.  endl; }void TearDown() override {cout  TearDown runs after each case.  endl; }Utility util;};这段代码说明如下Setup和TearDown两个函数标记了override以确认是重写父类中的方法这是C11新增的语法。我们的Utility类是无状态的因此Setup和TearDown两个函数中我们仅仅打印日志以便确认。将Utility util设置为protected以便测试代码中可以访问。从实现上来说测试case的代码是从这个类继承的子类当然这个关系是由Google Test工具完成的。要使用这里定义的Test Fixture测试case的代码需要将开头的TEST变更为TEST_F。这里_F就是Fixture的意思。使用TEST_F的case的代码结构如下TEST_F(TestCaseName, TestName) {... test body ... }这里的TestCaseName必须是Test Fixture的类名。所以我们的测试代码写起来是这样TEST_F(UtilityTest, ArithmeticCalculationDouble) {EXPECT_EQ(util.ArithmeticCalculation(ADD, 1.1, 1.1), 2.2); }TEST_F(UtilityTest, ArithmeticCalculationIsLeapYear) {EXPECT_FALSE(util.IsLeapYear(1997));EXPECT_TRUE(util.IsLeapYear(2000));EXPECT_TRUE(util.IsLeapYear(2016));EXPECT_FALSE(util.IsLeapYear(2100)); }我们针对ArithmeticCalculation方法故意只进行了一种情况的测试。这是为了最终生成代码覆盖率所用。运行测试编写完单元测试之后再执行编译工作便可以运行测试程序以查看测试结果了。测试的结果像下面这样如果测试中包含了失败的case则会以红色的形式输出。同时会看到失败的case所处的源码行数这样可以很方便的知道哪一个测试失败了像下面这样如果只想有选择性的跑部分case可以通过--gtest_filter参数进行过滤这个参数支持*通配符。像下面这样$ ./build/unit_test --gtest_filter*ArithmeticCalculationInt Running main() from googletest/src/gtest_main.cc Note: Google Test filter  *ArithmeticCalculationInt [] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from TestCalculationInt [ RUN      ] TestCalculationInt.ArithmeticCalculationInt CANNO Divided by 0 [       OK ] TestCalculationInt.ArithmeticCalculationInt (0 ms) [----------] 1 test from TestCalculationInt (0 ms total)[----------] Global test environment tear-down [] 1 test from 1 test case ran. (0 ms total) [  PASSED  ] 1 test.如果想要更好的理解这些内容。请读者下载演示项目之后完成下面这些操作在utility.h和utility.cpp中添加一些新的函数。在新添加的函数中故意包含一个bug。为新添加的函数编写测试代码并测试出函数中包含的bug。代码覆盖率在进行单元测试之后我们当然希望能够直观的看到我们的测试都覆盖了哪些代码。理论上如果我们能做到100%的覆盖我们的所有代码则可以说我们的代码是没有Bug的。但实际上100%的覆盖率要比想象得困难。对于大型项目来说能够达到80% ~ 90%的语句覆盖率就已经很不错了。覆盖率的类型先来看一下当我们在说“覆盖率”的时候我们到底是指的什么。实际上代码覆盖率有下面几种类型函数覆盖率描述有多少比例的函数经过了测试。语句覆盖率描述有多少比例的语句经过了测试。分支覆盖率描述有多少比例的分支例如if-elsecase语句经过了测试。条件覆盖率描述有多少比例的可能性经过了测试。这其中函数覆盖率最为简单就不做说明了。语句覆盖率是我们最常用的。因为它很直观的对应到我们写的每一行代码。而分支覆盖率和条件覆盖率可能不太好理解需要做一下说明。以下面这个C语言函数为例int foo (int x, int y) {int z  0;if ((x  0)  (y  0)) {z  x;}return z; }这个函数中包含了一个if语句因此if语句成立或者不成立构成了两个分支。所以如果只测试了if成立或者不成立的其中之一其分支覆盖率只有 1/2 50%。而条件覆盖率需要考虑每种可能性的情况。对于if (a b)这样的语句其一共有四种可能的情况a true, b truea true, b falsea false, b truea false, b false请读者思考一下对于三层if嵌套每个if语句包含三个布尔变量的代码如果要做到100%的条件覆盖率一共要测试多少种情况。很显示在编写代码的时候尽可能的减少代码嵌套并且简化逻辑运算是一项很好的习惯。便于测试的代码也是便于理解和维护的反之则反。有了这些概念之后我们就可以看懂测试报告中的覆盖率了。gcovgcov[16]是由GCC工具链提供的代码覆盖率生成工具。它可以很方便的和GCC编译器配合使用。通常情况下安装好GCC工具链也就同时包含了gcov命令行工具。对于代码覆盖率工具所做的工作可以简单的理解为标记一次运行过程中哪些代码被执行过哪些没有执行。因此即便没有测试代码直接运行编译产物也可以得到代码的覆盖率。只不过通常情况下这样得到的覆盖率较低罢了。使用这里我们以另外一个简单的代码示例来说明gcov的使用。这段代码如下// test.c#include stdio.hint main (void) {for (int i  1; i  10; i) {if (i % 3  0)printf (%d is divisible by 3\n, i);if (i % 11  0)printf (%d is divisible by 11\n, i);}return 0; }这是一个仅仅包含了main函数的c语言代码main函数的逻辑也很简单。我们将这段代码保存到文件test.c。要通过gcov生成代码覆盖率。需要在编译时增加参数--coveragegcc --coverage test.c--coverage等同于编译参数-fprofile-arcs -ftest-coverage以及在链接时增加-lgcov。此处的编译结果除了得到可执行文件a.out还会得到一个test.gcno文件。该文件包含了代码与行号的信息在生成覆盖率时会需要这个文件。很显然带--coverage编译参数得到的编译产物会比不带这个参数要包含更多的信息因此编译产物会更大。所以这个参数只适合在需要生成代码覆盖率的时候才加上。对于正式发布的编译产物不应该添加这个编译参数。当我们执行上面编译出来的可执行文件a.out时我们还会得到每个源码文件对应的gcda后缀的文件。由test.gcno和test.gcda这两个文件便可以得到代码的覆盖率结果了。关于这两个文件的说明请参见这里Brief description of gcov data files[17]只需要通过gcov指定源文件的名称不需要带后缀gcov test便可以得到包含覆盖率的结果文件 test.c.gcov了。回顾一下我们刚刚的操作内容$ gcc --coverage test.c $ ll total 72 -rwxr-xr-x  1 Paul  staff    26K 11 10 14:41 a.out -rw-r--r--  1 Paul  staff   240B 11 10 14:41 test.c -rw-r--r--  1 Paul  staff   720B 11 10 14:41 test.gcno $ ./a.out  3 is divisible by 3 6 is divisible by 3 9 is divisible by 3 $ ll total 80 -rwxr-xr-x  1 Paul  staff    26K 11 10 14:41 a.out -rw-r--r--  1 Paul  staff   240B 11 10 14:41 test.c -rw-r--r--  1 Paul  staff   212B 11 10 14:42 test.gcda -rw-r--r--  1 Paul  staff   720B 11 10 14:41 test.gcno $ gcov test File test.c Lines executed:85.71% of 7 test.c:creating test.c.gcov$ ll total 88 -rwxr-xr-x  1 Paul  staff    26K 11 10 14:41 a.out -rw-r--r--  1 Paul  staff   240B 11 10 14:41 test.c -rw-r--r--  1 Paul  staff   623B 11 10 14:42 test.c.gcov -rw-r--r--  1 Paul  staff   212B 11 10 14:42 test.gcda -rw-r--r--  1 Paul  staff   720B 11 10 14:41 test.gcno我们可以cat test.c.gcov一下查看覆盖率的结果-:    0:Source:test.c-:    0:Graph:test.gcno-:    0:Data:test.gcda-:    0:Runs:1-:    0:Programs:1-:    1:// test.c-:    2:-:    3:#include stdio.h-:    4:-:    5:int main (void) {-:    6:20:    7:  for (int i  1; i  10; i) {9:    8:      if (i % 3  0)3:    9:        printf (%d is divisible by 3\n, i);9:   10:      if (i % 11  0)#####:   11:        printf (%d is divisible by 11\n, i);9:   12:  }-:   13:1:   14:  return 0;-:   15:}这个结果应该还是很容易理解的最左边一列描述了代码的覆盖情况-表示该行代码被覆盖了整数表示被执行的次数#####表示该行没有被覆盖lcovgcov[18]得到的结果是本文形式的。但很多时候我们可能希望得到更加美观和便于浏览的结果。此时就可以使用lcov[19]了。lcov是gcov工具的图形前端。它收集多个源文件的gcov数据并生成描述覆盖率的HTML页面。生成的结果中会包含概述页面以方便浏览。lcov支持我们前面提到的所有四种覆盖率。这个链接是lcov生成的报告样例lcov - code coverage report[20]。安装lcov并非包含在GCC中因此需要单独安装。Mac系统brew install lcovUbuntu系统sudo apt install lcov使用对于lcov的使用方法可以通过下面这条命令查询lcov --help通过输出我们可以看到这个命令的参数有简短例如-c和完整例如--capture)两种形式其作用是一样的。这里主要关注的下面这几个参数-c 或者 --capture 指定从编译产物中收集覆盖率信息。-d DIR 或者 --directory DIR 指定编译产物的路径。-e FILE PATTERN 或者 --extract FILE PATTERN 从指定的文件中根据PATTERN过滤结果。-o FILENAME 或者 --output-file FILENAME 指定覆盖率输出的文件名称。另外还有需要说明的是lcov默认不会打开分支覆盖率因此我们还需要增加这个参数来打开分支覆盖率的计算--rc lcov_branch_coverage1lcov输出的仍然是一个中间产物我们还需要通过lcov软件包提供的另外一个命令genhtml来生成最终需要的html格式的覆盖率报告文件。同样的为了打开分支覆盖率的计算我们也要为这个命令增加--rc lcov_branch_coverage1参数最后make_all.sh脚本中包含的相关内容如下COVERAGE_FILEcoverage.info REPORT_FOLDERcoverage_report lcov --rc lcov_branch_coverage1 -c -d build -o ${COVERAGE_FILE}_tmp lcov --rc lcov_branch_coverage1  -e ${COVERAGE_FILE}_tmp *src* -o ${COVERAGE_FILE} genhtml --rc genhtml_branch_coverage1 ${COVERAGE_FILE} -o ${REPORT_FOLDER}这段代码从我们前面编译的结果中收集覆盖率结果并将结果输出到coverage.info_tmp文件中。但是这里面会包含非项目源码的覆盖率例如google test所以我们又通过另外一条命令来指定”src”文件夹进行过滤。最后通过genhtml得到html格式的报告。可以通过浏览器查看覆盖率报告的结果像下面这样从这个报告的首页我们已经可以看到代码的语句覆盖率Lines函数覆盖率Functions以及分支覆盖率Branches。而对于条件覆盖率可以从详细页面中看到。如下图所示在上面这张图中我们可以看到哪些代码被覆盖了哪些没有。而对于对于if-else之类的语句也能很清楚的看到条件覆盖率的覆盖情况。例如对于代码的27行只覆盖了if成立时的情况没有覆盖if不成立时的情况。更进一步本文中我们已经完整的完成了从编写单元测试到覆盖率生成的整个过程。但实际上对于这项工作我们还可以做得更多一些。例如下面这两项工作使用Google MockGoogle Mock是Google Test的扩展用于编写和使用C Mock类。在面向对象的编程中Mock对象[21]是模拟对象它们以预先设定的方式模仿真实对象的行为。程序员通常会创建一个Mock对象来测试某个其他对象的行为这与汽车设计师使用碰撞测试假人来模拟人类在车辆碰撞中的动态行为的方式非常相似。关于Google Mock的更多内容请参见Google Mock的文档[22]。持续集成对于演示项目的覆盖率报告是通过手动执行脚本文件生成的。而在实际的项目中可能同时有很多人在开发同一个项目每一天项目中都会有很多次的代码提交。我们不可能每次手动的执行编译和生成覆盖率报告结果。这时就可以借助一些持续集成[23]的工具定时自动地完成项目的编译测试和覆盖率报告结果的生成工作。可以在持续集成工具中包含我们编写的脚本然后将覆盖率报告的html结果发布到某个Web服务器上最后再以邮件的形式将链接地址发送给大家。这样就可以很方便的让整个团队看到所有模块的测试结果和覆盖率情况了。完成了一整套这样的工作可以非常好的提升整个项目的质量。参考文献与推荐读物CMake CookbookGoogle Testgoogletest Generic Build InstructionsGoogletest PrimerA quick introduction to the Google C Testing FrameworkGoogle Test Quick ReferenceCoverage testing with gcovGenerating Code Coverage with Qt 5 and GCOV on Mac OSWikipedia: xUnitWikipedia: Code Coveragelcov - the LTP GCOV extensiongcov—a Test Coverage Program参考资料[1]paulQuei/gtest-and-coverage: https://github.com/paulQuei/gtest-and-coverage[2]brew: https://brew.sh/[3]https://cmake.org: https://cmake.org/[4]Installing CMake: https://cmake.org/install/[5]Program Instrumentation Options: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#Instrumentation-Options[6]白盒测试: https://en.wikipedia.org/wiki/White-box_testing[7]Kent Beck: https://en.wikipedia.org/wiki/Kent_Beck[8]Github: Google Test: https://github.com/google/googletest[9]Chromium projects: http://www.chromium.org/[10]LLVM: http://llvm.org/[11]Protocol Buffers: https://github.com/google/protobuf[12]OpenCV: http://opencv.org/[13]tiny-dnn: https://github.com/tiny-dnn/tiny-dnn[14]Generic Build Instructions: https://github.com/google/googletest/tree/master/googletest[15]paulQuei/gtest-and-coverage: https://github.com/paulQuei/gtest-and-coverage[16]gcov: https://gcc.gnu.org/onlinedocs/gcc/gcov.html[17]Brief description of gcov data files: https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/gcov-Data-Files.html[18]gcov: https://gcc.gnu.org/onlinedocs/gcc/gcov.html[19]lcov: http://ltp.sourceforge.net/coverage/lcov.php[20]lcov - code coverage report: http://ltp.sourceforge.net/coverage/lcov/output/index.html[21]Mock对象: https://en.wikipedia.org/wiki/Mock_object[22]Google Mock的文档: https://github.com/google/googletest/blob/master/googlemock/README.md[23]持续集成: https://en.wikipedia.org/wiki/Continuous_integration[24]《C语言的单元测试与代码覆盖率》: https://paul.pub/gtest-and-coverage/如果你年满18周岁以上又觉得学【C语言】太难想尝试其他编程语言那么我推荐你学Python现有价值499元Python零基础课程限时免费领取限10个名额▲扫描二维码-免费领取戳“阅读原文”我们一起进步
http://www.sadfv.cn/news/260002/

相关文章:

  • 网站建设能赚很多钱不动产登记网站建设
  • 广西灵山县建设局网站wordpress应用市场主体
  • 乐清手机网站设计互联网推广员是做什么
  • 厦门集团网站建设wordpress首页文章只显示标题
  • 赣州火车站找服务铜陵县住房和城乡建设局网站
  • 建企业网站销售营销网站
  • 天津开发区网站中小学生做试卷的网站
  • 网站的网络营销方案华为手机开发者模式怎么关闭
  • 网站尺寸大小东阳市网站建设制作
  • 毕业设计做网站做什么好影视作品网站开发与设计
  • 东莞四网合一网站建设长宁网站建设
  • 现在的网站设计深圳网站建设加q5299丶14602推广
  • 做go kegg的在线网站怎样注册网站卖东西
  • 凡科建站有哪些弊端资源交易网站代码
  • 设计网站推广方案网络营销渠道
  • 什么网站收录快it运维之道
  • 网站备案注销原因做智能家居网站需要的参考文献
  • 网站导航一定要一样吗物联网系统开发
  • 淮安网站优化网站建设存在问题整改报告
  • 崇信县门户网站首页在服务器上运行wordpress
  • 建设网站的软件下载河源市地震
  • 网站设计宽屏价格低的手机
  • 深圳最大的招聘网站是什么上海贸易公司注册条件
  • 网站开发费怎么做账网站seo工具
  • 广西学校论坛网站建设成都网站建设推来客熊掌号
  • 群艺馆网站建设方案阿里巴巴网站是怎么做的
  • 中国建设银行网站余额查询比较有名的设计网站
  • 浙江方远建设集团网站seo研究协会
  • 南阳网站运营昆明网站建设制作
  • 做个门户网站多少钱怎么登陆公司网站的后台