前面的章节我们完成了任务管理主要功能的开发及单元测试编写,可如何知道单元测试效果怎么样呢?测试充分吗?还有没有没有测到的地方呢?

  本章节我们介绍一个统计测试代码覆盖率的利器Coverage,Coverage.py (以下简称 Coverage)是 Python 测试界最为流行的一个库之一,用来统计测试覆盖率。测试覆盖率可以从一个角度衡量代码的质量,覆盖率越高,说明测试越充分,代码出现 bug 的几率相对也就越小。当然需要明确的是,测试覆盖率仅仅只是衡量代码质量的一个角度,即是否有代码未经过单元测试验证,不能说100% 的覆盖率的代码就没有 bug 了。

1.1. 安装coverage

  IDE Python环境管理里或进入命令行安装coverage,如下图:

1.2. 运行coverage

1.2.1. 工程目录下运行coverage run manage.py test

D:\my tfs\IndDemo>coverage run manage.py test

Creating test database for alias 'default'...

System check identified no issues (0 silenced).

.............

----------------------------------------------------------------------

Ran 13 tests in 0.146s

OK

Destroying test database for alias 'default'...

D:\my tfs\IndDemo>

1.2.2. 查看统计结果coverage report

D:\my tfs\IndDemo>coverage report

Name                                                               Stmts   Miss  Cover

--------------------------------------------------------------------------------------

C:\Users\FQ\AppData\Roaming\Python\Python36\site-packages\six.py     490    242    51%

Collector\__init__.py                                                  0      0   100%

Collector\admin.py                                                     1      0   100%

Collector\migrations\__init__.py                                       0      0   100%

Collector\models.py                                                    1      0   100%

Collector\tests.py                                                     8      0   100%

Collector\views.py                                                    93     72    23%

IndDemo\__init__.py                                                    0      0   100%

IndDemo\settings.py                                                   21      0   100%

IndDemo\urls.py                                                        9      0   100%

Task\TaskBiz.py                                                       27      5    81%

Task\__init__.py                                                       1      0   100%

Task\admin.py                                                         82     36    56%

Task\apps.py                                                           4      0   100%

Task\migrations\0001_initial.py                                        7      0   100%

Task\migrations\0002_auto_20210314_0840.py                             6      0   100%

Task\migrations\__init__.py                                            0      0   100%

Task\models.py                                                        81     12    85%

Task\tests.py                                                         78      0   100%

Task\urls.py                                                           3      0   100%

Task\views.py                                                         33      2    94%

TestStringMethods.py                                                   9      1    89%

app\__init__.py                                                        0      0   100%

app\forms.py                                                           6      0   100%

app\migrations\__init__.py                                             0      0   100%

app\models.py                                                          1      0   100%

app\tests.py                                                          16      0   100%

app\views.py                                                          12      0   100%

manage.py                                                             10      2    80%

--------------------------------------------------------------------------------------

TOTAL                                                                999    372    63%

D:\my tfs\IndDemo>

1.2.3. coverage html命令获得更加详细的信息

  此命令在同级目录下生成包含html文件的文件夹,默认名称为htmlcov,点击打开index.html即可。

  通过覆盖率统计,我们可以看到Task\views.py文件的代码覆盖率94%,有两行代码未被测试覆盖到,就可以通过点击相关链接查看详情,如下图:

  有两行代码未被单元测试覆盖到,红色标注出来了非常方便查看未被覆盖额代码。

1.3. 修改单元测试代码

  接下来我们增加单元测试代码,增加 self.client.get('/task/1/change/')测试get请求才能进入到上图标红的代码分支。

...

    def test_task_change(self):
data={'source':'111','target':'05-01-11'}
#更新第一个task的源和目标值
response=self.client.post('/task/1/change/',data) model = Task.objects.get(pk=1)
self.assertEqual(model.Source,'111')
self.assertEqual(model.Target,'05-01-11') response=self.client.get('/task/')
self.assertIn('111',response.content.decode())
self.assertTemplateUsed(response,'Task/tasks.html') response=self.client.get('/task/1/change/')
self.assertIn('111',response.content.decode())
self.assertTemplateUsed(response,'Task/taskChange.html') 

  重新运行代码覆盖命令:

D:\my tfs\IndDemo>coverage run manage.py test

Creating test database for alias 'default'...

System check identified no issues (0 silenced).

.............

----------------------------------------------------------------------

Ran 13 tests in 0.212s

OK

Destroying test database for alias 'default'...

D:\my tfs\IndDemo>coverage html

  刷新网页/htmlcov/index.html,我们得到如下图:

  文件Task\views.py单元测试代码覆盖率达到了100%

1.4. 配置coverage

windows平台生成.coveragerc配置文件:

D:\my tfs\IndDemo>echo >.coveragerc

1.4.1. 基本配置

[run]

branch = True

source = .

[report]

show_missing = True

  • branch = True。是否统计条件语句的分支覆盖情况。if 条件语句中的判断通常有 True 和 False 两种情况,设置 branch = True 后,Coverage 会测量这两种情况是否都被测试到。
  • source = .。指定需统计的源代码目录,这里设置为当前目录(即项目根目录)。
  • show_missing = True。在生成的统计报告中显示未被测试覆盖到的代码行号。

  有一些文件其实并不需要测试,或者并非项目的核心文件(例如部署脚本 fabfile.py,django 的 migrations 文件等),这些文件应该从统计中排除。

  Coverage 默认显示全部文件的覆盖率统计结果,如果文件比较多的话就不好查找非 100% 覆盖率的文件。毕竟我们的目标是提高代码覆盖率,因此已达 100% 覆盖的代码文件我们不再关心。我们要做的是找到非 100% 覆盖率的文件,为其添加缺失的测试。

1.4.2. 完善配置

在 [run] 配置块中增加 omit 配置项可以指定排除统计的文件。

在 [report] 配置块中增加 skip_covered 配置项可以指定统计报告中不显示 100% 覆盖的文件。

[run]

branch = True

source = .

omit =

*/__init__.py

manage.py

IndDemo/*

*/migrations/*

IndDemo/wsgi.py

[report]

show_missing = True

skip_covered = True

重新运行覆盖率

D:\my tfs\IndDemo>coverage run manage.py test

Creating test database for alias 'default'...

System check identified no issues (0 silenced).

.............

----------------------------------------------------------------------

Ran 13 tests in 0.157s

OK

Destroying test database for alias 'default'...

D:\my tfs\IndDemo>coverage html

1.5. 小结

  通过单元测试的代码覆盖率coverage工具,我们能够快速的定位到那些代码未经过单元测试覆盖到,从而实现单元测试精准的定位,确保覆盖到所有代码。虽然说经过单元测试的代码就没有bug,没有经过单元测试的代码隐藏的可能的bug概率会高得多。所以企业开发过程中引入单元测试和覆盖率肯定会给项目开发质量带来一个飞跃的提升!

  这些都是深陷多个项目泥潭后,发现单元测试带来的好处。如果你和你团队也在做一个企业定制开发项目,组织编写单元测试吧,项目的中后期变更、扩展,你会发现编写单元测试的代价是多么的值得!

python工业互联网应用实战14——单元测试覆盖率的更多相关文章

  1. python工业互联网应用实战2—从需求开始

    前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...

  2. python工业互联网应用实战3—模型层构建

    本章开始我们正式进入到实战项目开发过程,如何从需求分析获得的实体数据转到模型设计中来,变成Django项目中得模型层.当然,第一步还是在VS2019 IDE环境重创建一个工程项目,本文我们把工程名称命 ...

  3. python工业互联网应用实战1—SQL与ORM

    从sql到ORM应该说也是编程体系逐步演化的结果,通过类和对象更好的组织开个过程中遇到的各种业务问题,面向对象的解耦和内聚作为一套有效的方法论,对于复杂的企业应用而言确实能够解决实践过程中很多问题. ...

  4. python工业互联网应用实战7—业务层

    本章我们演示代码是如何"进化"的,实战的企业日常开发过程中,系统功能总伴随着业务的不断增加,早期简单的代码慢慢的越来越复杂,敏捷编程中的"禅"--简单设计.快速 ...

  5. python工业互联网应用实战13—基于selenium的功能测试

    本章节我们再来说说测试,单元测试和功能测试.单元测试我们在数据验证章节简单提过了,本章我们进一步如何用单元测试来测试view的功能代码:同时,也涉及一下基于selenium的功能测试做法.笔者过去的项 ...

  6. python工业互联网应用实战3—Django Admin列表

    Django Admin笔者使用下来可以说是Django框架的开发利器,业务model构建完成后,我们就能快速的构建一个增删查改的后台管理框架.对于大量的企业管理业务开发来说,可以快速的构建一个可发布 ...

  7. python工业互联网应用实战11—客户端UI

    这个章节我们将演示用户端界面的开发,当前演示界面还是采用先实现基本功能再逐步完善的"敏捷"模式.首先聚焦在功能逻辑方面实现普通用户与系统的交互,普通用户通过url能查看到当前任务的 ...

  8. python工业互联网应用实战15-前后端分离模式1

    我们在13章节里通过监控界面讲了如何使用jquery的动态加载数据写法,通过简单案例来说明了如何实现动态的刷新监控界面的数据,本章我们将演示如何从Django模板加载数据逐步演化到前后端分离的异步数据 ...

  9. python工业互联网应用实战18—前后端分离模式之jquery vs vue

    前面我们分三章来说明了使用django template与jquery的差别,通过jquery如何来实现前后端的分离,同时再9章节使用vue.js 我们浅尝辄止的介绍了JQuery到vue的切换,由于 ...

随机推荐

  1. 混合编程:如何用python11调用C++

    摘要:在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对性能要求高的情景下面,还是需要使用c/c++来完成. 那怎样做呢?我们能使用pybind11作 ...

  2. Docker SDK api操作Docker

    下载包 go get "github.com/docker/docker/api/types" go get "github.com/docker/docker/clie ...

  3. 生成元(JAVA语言)

    package 第三章; import java.util.Scanner; public class 生成元 { public static void main(String[] args) { / ...

  4. Docker上安装Redis

    Docker可以很方便的进行服务部署和管理,下面我们通过docker来搭建Redis的单机模式.Redis主从复制.Redis哨兵模式.Redis-Cluster模式 一.在Docker上安装单机版R ...

  5. Java 并发工具类 CountDownLatch、CyclicBarrier、Semaphore、Exchanger

    本文部分摘自<Java 并发编程的艺术> CountDownLatch CountDownLatch 允许一个或多个线程等待其他线程完成操作.假设现有一个需求:我们需要解析一个 Excel ...

  6. .NET Core 环境变量详解

    一.概述 软件从开发到正式上线,在这个过程中我们会分为多个阶段,通常会有开发.测试.以及上线等.每个阶段对应的环境参数配置我们会使用不同的参数.比如数据库的连接字符串,开发环境一般我们都是连接的测试库 ...

  7. TypeError: Can't convert 'int' object to str implicitly Python常见错误

    尝试连接非字符串值与字符串 想要字符串连接非字符串需要先进行强制转化 可以用str()函数 --------------------------------

  8. HTML5和CSS3提高

    一.HTML5的新特性 HTML5 的新增特性主要是针对于以前的不足,增加了一些新的标签.新的表单和新的表单属性等. 这些新特性都有兼容性问题,基本是 IE9+ 以上版本的浏览器才支持,如果不考虑兼容 ...

  9. SQL语句练习(基础版)

    最近在学习SQL基本语句的练习,在此分享一下笔者做过的练习以及个人的解决教程: 首先是基本练习表格的搭建,具体内容如下表所示: Snum Sname Ssex Sage Sphone Dname S0 ...

  10. linux系统调用号查询(pwn)

    做pwn题时遇到程序使用了64位系统调用号:59和15,这里做一下记录 在线查询链接:https://syscalls.w3challs.com/ 分为32位和64位,链接中还有arm.mips等架构 ...