|
为项目添加单元测试覆盖率检查(coveralls)对项目添加持续集成构建检查以后,就能完全保证我们提交的代码运行没问题么?
答案是并不能。试想,假如我们整个项目中就只有一条单元测试用例,甚至这一条单元测试用例还是个假用例,即没有调用任何代码,那么可想而知,我们的持续集成构建检查总是成功的,并没有起到检查的作用。
因此,这里还涉及到一个单元测试覆盖率的问题。
怎么理解单元测试覆盖率呢?简单地说,就是我们在执行单元测试时运行代码的行数,与项目总代码数的比值。
对于主流的编程语言,都存在大量的覆盖率检查工具,可以帮助我们快速统计单元测试覆盖率。在Python中,用的最多的覆盖率检查工具是coverage。
要使用coverage,需要先进行安装,采用pip的安装方式如下:
$ pip install coverage然后,我们就可以采用如下命令执行单元测试。
$ coverage run --source=ate -m unittest discover这里需要说明的是,--source参数的作用是指定统计的目录,如果不指定该参数,则会将所有依赖库也计算进去,但由于很多依赖库在安装时是没有包含测试代码的,因此会造成统计得到的单元测试覆盖率远低于实际的情况。在上面的命令中,就只统计了ate目录下的单元测试覆盖率;如果要统计当前项目的覆盖率,那么可以指定--source=.(即当前目录下的所有子文夹)。
采用上述命令执行完单元测试后,会在当前目录下生成一个统计结果文件,.coverage,里面包含了详细的统计结果。
- cat .coverage
- !coverage.py: This is a private format, don't read it directly!{"lines":{"/Users/Leo/MyProjects/ApiTestEngine/ate/__init__.py":[1],"/Users/Leo/MyProjects/
- ApiTestEngine/ate/testcase.py":[1,2,4,6,9,15,42,7,12,40,46,64,67,68,69,70,48,49,62,72,74,13,65,51,52,53,56,60,58,54,55],"/Users/Leo/MyProjects/ApiTestEngi
- ne/ate/exception.py":[2,4,5,9,12,15,16,6,7],"/Users/Leo/MyProjects/ApiTestEngine/ate/utils.py":[1,2,3,4,5,7,9,11,12,14,15,18,22,25,47,51,55,65,77,90,129,1
- 41,27,31,32,19,20,23,34,41,43,45,56,57,59,60,48,49,154,163,166,170,172,173,174,176,177,181,182,183,186,187,189,91,92,66,67,72,73,74,94,95,97,98,101,102,78
- ,80,81,82,84,85,88,103,104,106,108,110,115,121,122,124,125,127,58,52,53,184,185,109,116,118,119,112,113,132,134,135,136,137,139,63,164,155,157,158,159,161
- ,167,168,192,68,69],"/Users/Leo/MyProjects/ApiTestEngine/ate/context.py":[1,3,5,6,10,16,30,45,7,8,25,26,28,41,42,43,49,55,58,59,63,64,56,74,65,68,69,72,66
- ,27,13,14,50,53,52,70],"/Users/Leo/MyProjects/ApiTestEngine/ate/main.py":[1,2,4,7,9,10,15,21,38,51,25,27,28,29,30,32,33,11,12,13,34,36,42,43,45,46,47,49],
- "/Users/Leo/MyProjects/ApiTestEngine/ate/runner.py":[1,3,4,5,8,10,15,46,68,97,135,11,12,13,35,36,38,39,41,42,44,82,63,65,66,84,86,87,88,92,93,94,95,124,12
- 6,127,128,129,130,131,133,154]}}%
复制代码 但是,这个结果就不是给人看的。要想直观地看到统计报告,需要再执行命令coverage report -m,执行完后,就可以看到详细的统计数据了。
- ➜ ApiTestEngine git:(master) ✗ coverage report -m
- Name Stmts Miss Cover Missing
- ------------------------------------------------
- ate/__init__.py 0 0 100%
- ate/context.py 35 0 100%
- ate/exception.py 11 2 82% 10, 13
- ate/main.py 34 7 79% 18-19, 54-62
- ate/runner.py 44 2 95% 89-90
- ate/testcase.py 30 0 100%
- ate/utils.py 112 8 93% 13, 29, 36-39, 178-179
- ------------------------------------------------
- TOTAL 266 19 93%<code></code>
复制代码 通过这个报告,可以看到项目整体的单元测试覆盖率为93%,并清晰地展示了每个源代码文件的具体覆盖率数据,以及没有覆盖到的代码行数。
那要怎么将覆盖率检查添加到我们的持续集成(Travis CI)中呢?
事实上,当前存在多个可选服务,可以与Travis CI配合使用。当前,使用得比较广泛的是coveralls,针对Public类型的GitHub仓库,这也是一个免费服务。
coveralls的使用方式与Travis CI类似,也需要先在coveralls网站上采用GitHub账号授权登录,然后开启需要进行检查的GitHub仓库。而要执行的命令,也可以在.travis.yml配置文件中指定。
增加覆盖率检查后的.travis.yml配置文件内容如下。
- <pre class="highlight yaml"><code><span class="na">sudo</span><span class="pi">:</span> <span class="s">false</span>
- <span class="na">language</span><span class="pi">:</span> <span class="s">python</span>
- <span class="na">python</span><span class="pi">:</span>
- <span class="pi">-</span> <span class="s">2.7</span>
- <span class="pi">-</span> <span class="s">3.3</span>
- <span class="pi">-</span> <span class="s">3.4</span>
- <span class="pi">-</span> <span class="s">3.5</span>
- <span class="pi">-</span> <span class="s">3.6</span>
- <span class="na">install</span><span class="pi">:</span>
- <span class="pi">-</span> <span class="s">pip install -r requirements.txt</span>
- <span class="pi">-</span> <span class="s">pip install coverage</span>
- <span class="pi">-</span> <span class="s">pip install coveralls</span>
- <span class="na">script</span><span class="pi">:</span>
- <span class="pi">-</span> <span class="s">coverage run --source=. -m unittest discover</span>
- <span class="na">after_success</span><span class="pi">:</span>
- <span class="pi">-</span> <span class="s">coveralls</span></code></pre>
- <span class="s"></span>
复制代码 如上配置应该也很好理解,要使用coveralls的服务,需要先安装coveralls。在采用coverage执行完单元测试后,要将结果上报到coveralls网站,需要再执行coveralls命令。由于coveralls命令只有在测试覆盖率检查成功以后运行才有意义,因此可将其放在after_success部分。
配置完毕后,后续每次提交代码时,GitHub就会调用Travis CI实现构建检查,并同时统计得到单元测试覆盖率。
下图是某次提交代码时的覆盖率检查。
另外,我们在GitHub项目的README.md中也同样可以添加一个Status Image,实时显示项目的单元测试覆盖率。
配置方式也跟之前类似,在coveralls中获取到项目Status Image的URL地址,然后添加到README.md即可。
最后需要说明的是,项目的单元测试覆盖率只能起到参考作用,没有被单元测试覆盖到的代码我们不能说它肯定有问题,100%覆盖率的代码也并不能保证它肯定没有问题。归根结底,这还是要依赖于单元测试的策略实现,因此我们在写单元测试的时候也要尽可能多地覆盖到各种逻辑路径,以及兼顾到各种异常情况。
|
|