konakona
Dream Afar.
konakona
Python接口覆盖率集成 GITLAB CI/CD
Python接口覆盖率集成 GITLAB CI/CD

为什么做这个?这是什么?

为了做冒烟测试, BVT(Build Verification Testing)。

在daily build(构建版本)建立后,对系统的基本功能进行简单的测试或者功能完整性测试,也就是说冒烟测试是随着每一次构建而执行的。

冒烟测试并非研发流程中的测试阶段,而是一个开关。

通过了,你可以继续后面的测试。

不通过,直接返工等待下一次的构建。

这才是冒烟测试应有的态度。

思考:

就像地铁安检,如果你身上携带了违禁物品,你还能继续过去吗?

Rethink:

冒烟测试的最佳实践最好被自动化,在CI中每一个Build都自动的去执行主流程的测试,确保其是一个基本可用的版本。

怎么做?

我们主要做的是接口冒烟测试的python脚本,并结合业务项目里的单元测试一起做集成测试。工程师开发项目可能用的是JAVA、Go、C++等项目经理不熟悉的开发语言,为了让这个事儿简单易学好使,我们用最简单的Python+UnitTest+Requests来实现接口覆盖率测试脚本(以下简称“Python脚本”)的代码编写。

工具介绍

  • Python3:我们使用Python3这个大版本,保持新鲜,持续动力
  • UnitTest:Python官方单元测试框架,我们主要是用各种断言语句足以
  • Requests:一个很有趣的Python HTTP库,用来实现GET/POST/PATCH/DELETE/OPTION等请求行为
  • Nose2:Nose2是UnitTest的扩展插件,用于向CLI/XML输出覆盖率百分比等信息

学习路径

在工具介绍中提及的所有工具都会用到,应当熟悉。

学习顺序及掌握程度

  1. Python3 会声明变量/常量、function、if else,知道Python格式化要求,知道没有括号这些就可以写脚本了。
  2. UnitTest 掌握各种断言语句足以。
  3. Requests 不用懂,太简单,用过一次就掌握了。
  4. Nose2 只是个扩展插件,在CLI下通过一行命令执行一下就可以了,出现问题时问搜索引擎就可以了。

如何写?

准备工作

  • 首先准备一个合适的IDE/编辑器,比如VSCode、Atom或者更专业的PyCharm
  • 安装好Python3,并且可以在命令行下输入 python3 -version,如果不能,请检查环境变量
  • 安装requests和nose2
  • 安装好Docker,MacOS首次安装后需要准备 default env,建议安装Docker-for-mac
  • 安装好git,在你负责的业务项目分组中创建一个新的git project存放python脚本

何时写

在Sprint A(Scrum flow)结束后,基于后端工程师撰写的Swagger文档进行Python脚本的编写,并在首个Scrum周期结束之际,完成以及部署到python所在的 git CI/CD和后端git CI/CD。

你可以只写系统的基本功能进行简单测试的部分(核心业务流程接口),也可以做功能完整性测试(所有接口)。

  • 根据每一个接口的请求方式,使用requests.get(url) 等或requests.patch(url,data=data,headers=headers) 等requests框架的方法来执行接口请求。
  • 执行后,根据服务器端返回的HTTP状态值判断是否执行成功。
  • 如果接口使用到了自定义状态值,则还需要根据状态值近一步判断操作是否成功,并且HTTP状态值的作用转变为判断是否请求成功,而非执行成功。关于这一个认知,可以查看我另一份文档《接口文档协作规范》5.2 返回状态说明

参考代码

python代码可以我整理至github的仓库

文件结构介绍

.

├── Dockerfile

├── README.md 

├── function

│   └── common.py // 常用方法库

├── nose2.cfg // nose2的配置文件,非必须

├── gitlab-ci.yml // CI配置

├── requirements.txt // 初始化Dockerfile时,需要pip3 install的包名称

└── tests

├── __init__.py

└── api_testing

├── __init__.py

├── for_upload.jpg //上传用到的文件

├── test_manager.py // 运营端测试脚本

├── test_web.py // 客户端测试脚本

└── test_mini_program.py // 小程序端测试脚本

文件名必须遵守的约定

测试文件必须以test_开头,nose2才能检测到。

如何执行测试脚本

有两个做法:

  • 使用python3执行测试脚本:python3 脚本名
  • 使用nose2执行全部测试脚本:nose2

最终,我们只会统一使用nose2来执行所有测试脚本的。

写README.md

写README.md只有一个目的:能够让任何同行看了都能明白怎么通过docker build一个容器并run起来,然后可以进去正确的执行nose2。

https://blog.img.crazyphper.com/2019/10/J9fo8rWTojEeWpWy__thumbnail-800x352.png

README.md是一个Peer review的标准

写Dockerfile

https://blog.img.crazyphper.com/2019/10/qdaMVLABv8cPtSj7__thumbnail.png

在这里,我选择创建一个/app做为工作目录,将git中的文件全部拷贝至/app,在requirements.txt中,要求安装nose2和requests,调用pip3去安装。

写完Dockerfile后,执行docker build命令创建容器。

https://blog.img.crazyphper.com/2019/10/bijubiu-800x532.png

接下来,我们需要进入这个运行中的容器里执行一下nose2来确保容器中的脚本工作良好。

https://blog.img.crazyphper.com/2019/10/nvQhln8TppIi7LPl__thumbnail.png

到这里,python脚本的开发和dockerfile工作结束。接下来我们需要配置gitlab-ci.yaml 文件来让Gitlab的 CI/CD自动运行nose2 。

写Gitlab-ci.yml

先来说一下python所在的git的gitlab-ci.yml如何写以及有哪些思考,有些长,建议全部阅读。

如果只需要yml文件,请直接看python git仓库中的gitlab-ci.yml文件,然后跳过本章的阅读。

https://blog.img.crazyphper.com/2019/10/HxSsERXh7YgLLW8J__thumbnail.png

(基础知识,stages是顺序执行的

  • stages :只有一个test job就够了
  • test job : 使用python3.8镜像做为gitlab runner在当前job里所使用的docker容器
  • script :依次告知需要执行的命令,最后执行nose2
  • only :告诉CI,当前job只需要执行develop分支下的代码
  • when :任何使用都执行这个job

到这里,这份gitlab-ci.yml是可以独立运作的,我们可以删掉dockerfile,因为没有用到。

但很遗憾,这无法实现自动化部署测试的目的。我们需要在后端的git仓库里做一个设定(后端git的gitlab-ci.yml中),这个设定可以在每次后端的git有更新时,CI会调用 python git里的容器,然后执行nose2 。

为达到这一目的,需要容器贯通。因此我们需要python git里有dockerfile,让容器部署在hub.dev.domain.com服务器上,就可以让其他容器(每一个git项目都是一个容器)调用了。这么做的是为了实现最小容器化的规范目的。

下一章,我们以实际操作来呈现这一过程。

自动化的gitlab-ci.yml

https://blog.img.crazyphper.com/2019/10/15k0fth7bwc1rT0r__thumbnail-649x600.png

与之前最大的区别就是build阶段,将容器上传至你的Docker Server,可以用Harbor搭建 。

${ HUB_DEV_ADDR } 这些变量是gitlab-shell(linux user)设置的,是在gitlab server上配置的,这里我们无需过多了解,变量全部照抄即可,注意要修改PROEJCT_NAMEREPO_NAME

这里我用的IMAGE_TAG始终是同一个,而没有使用代表commit id的${CI_COMMIT_SHA},如此一来这个容器的地址永远都是: hub.dev.domain.com/**/python:v0.0.1,当我在其他git中要使用这个容器的test job时就很方便。

而在test job里,我们使用的镜像是刚刚build阶段的容器,在dockerfile里我们早早就已经让安装了python3.8、requests、nose2 ,此时就只需要执行nose2即可。

提交代码到gitlab,会在Pipelines中看到刚刚提交的执行结果,这里有2个勾,说明运行成功。

https://blog.img.crazyphper.com/2019/10/QWI6jS1eEx8CmPZ8__thumbnail-800x84.png

我们还需要进入test job,查看执行日志与预期是否一致。

https://blog.img.crazyphper.com/2019/10/1572065855869.jpg

当我们看到nose2的执行结果出来了,就说明一切正常。

后端git的gitlab-ci.yml

接下来我们还需要修改backend的gitlab-ci.yml,以实现daily build后执行测试计划。

https://blog.img.crazyphper.com/2019/10/1572066186136.jpg

只用加入我们自己的job就行,其他无需改动:

python-test:
stage: test
image: hub.dev.domain.com/groupname/python:v0.0.1
script:
- nose2
only:
- develop

这样一来,我们就实现了开发提交代码后,自动触发gitlab-runner拉取executor镜像执行单元测试。

https://blog.img.crazyphper.com/2019/10/SHakImKcKjIlWEtk__thumbnail.png

单元测试通过后,gitlab-runner 执行 python测试脚本,然后执行覆盖率分析(下一章“配置CI/CD”),分析结果可供徽章调用后显示在README.md。

配置CI/CD

访问python git 的Settings -> CI/CD,展开“General pipelines”找到“Test coverage parsing”添加正则:

/TOTAL.+ ([0-9]{1,3}%)/

或者在gitlab-ci.yml文件的test job里增加以下内容:

https://blog.img.crazyphper.com/2019/10/UWfLZORR9MweUQCz__thumbnail-800x337.png

如此,以后任何test job 执行完后,进入jobs页面就可以看到coverage的百分比了。

https://blog.img.crazyphper.com/2019/10/oGJzPRptd2IYdwSi__thumbnail-800x511.png

显示覆盖率徽章

gitlab有一个徽章功能,可以方便的添加到任何markdown文档中。在这里我用到了pipeline status和test coverage这2个徽章。

[![pipeline status](https://git.domain.com/dztech/dzweb-v2/python/badges/develop/pipeline.svg)](https://git.domain.com/dztech/dzweb-v2/python/commits/develop)
[![coverage report](https://git.domain.com/dztech/dzweb-v2/python/badges/develop/coverage.svg)](https://git.domain.com/dztech/dzweb-v2/python/commits/develop)

可以将python的覆盖率放在后端git里展示,效果如下:

https://blog.img.crazyphper.com/2019/10/FOzScP5ExNUqDJcf__thumbnail-800x344.png

赞赏
https://secure.gravatar.com/avatar/3b712b34a0e1b689cfb524c9c6bcdc47?s=256&r=g

团哥

文章作者

继续玩我的CODE,让别人说去。 低调,就是这么自信。

发表评论

textsms
account_circle
email

konakona

Python接口覆盖率集成 GITLAB CI/CD
为什么做这个?这是什么? 为了做冒烟测试, BVT(Build Verification Testing)。 在daily build(构建版本)建立后,对系统的基本功能进行简单的测试或者功能完整性测试,也就是说冒烟…
扫描二维码继续阅读
2019-10-26