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

  本章节我们介绍一个统计测试代码覆盖率的利器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. android分析之Condition

    Condition的含义是条件变量,其实现依赖于系统,一般都要配合Mutex使用,使用步骤为:给mutex上锁(Lock),调用wait等待"条件"发生,如果没有发生则re-wai ...

  2. java实现所有排序算法

    package sort;public class Sort { public static void BubbleSort(int[] arr) { //TODO 冒泡排序 for(int i=ar ...

  3. 2018ICPC南京Problem G. Pyramid

    题意: 询问类似于这样的三角形中:里面正三角形的个数是多少. 思路:打表找了个规律发现就是C4n+3     1 //#include<bits/stdc++.h> 2 #include& ...

  4. python基础之流程控制(2)

    今天将是基础篇的最后一篇,咱们来补上最后一个内容,流程控制for循环 For 循环 一.为什么有for循环? for循环能做的事情,while循环全都可以实现,但是在某些情境下,for循环相对于whi ...

  5. CodeForces CF862E题解

    \(Part\ 1:\) 我们发现每次修改动的是\(a\)串,所以对于这个答案的公式,\(b_{i+j}\)的部分是可以求出来的.所以我们可以把公式改成如下所示: \(f(j)=|\sum_{i=1} ...

  6. Elasticsearch 主节点和暖热节点解析

    Elasticsearch 主节点和暖热节点解析 主节点 控制整个集群,进行一些轻量级操作,列如:跟踪哪些节点是集群中的一部分,决定节点分片分配,负责集群健康, 不包含数据,也不参与搜索和索引操作,对 ...

  7. 201871030118-雷云云 实验二 个人项目—D{0-1}背包问题项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业链接 我的课程学习目标 1.了解并掌握psp2.掌握软件项目个人开发流程3.掌握Github发布软件项目的操作方法 这个作业在哪些方面帮助 ...

  8. BUAAOO第三单元总结

    JML理论基础 JML规定了一些语法,用这些语法可以描述一个方法,一个类的行为,理论基础是离散数学吧 JML常用语法 前置条件: 使用 require + 表达式 ,表达式一般为布尔表达式 副作用: ...

  9. IDEA - 返回上一步,回到下一步 代码 快捷键

    回到上一步 ctrl + alt + < 回到下一步 ctrl + alt + >

  10. fish shell 自动补全子命令

    之前在 「创建 fish shell 自动补全文件」 中介绍了如何创建 fish 的补全文件,实现对命令的友好补全提示.通过形如 complete -c <command> -a [&qu ...