36

Python接口覆盖率集成 GITLAB CI/CD - konakona

 4 years ago
source link: https://blog.crazyphper.com/2019/10/26/python%E6%8E%A5%E5%8F%A3%E8%A6%86%E7%9B%96%E7%8E%87%E9%9B%86%E6%88%90gitlab-ci%E8%A1%8C%E5%8A%A8%E6%8C%87%E5%8D%97/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

为了做冒烟测试, 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。

README.md是一个Peer review的标准

写Dockerfile

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

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

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

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

写Gitlab-ci.yml

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

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

(基础知识,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

与之前最大的区别就是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个勾,说明运行成功。

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

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

后端git的gitlab-ci.yml

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

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

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

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

单元测试通过后,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里增加以下内容:

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

显示覆盖率徽章

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK