GitHub 研发链 travis-ci 和 codecov 介绍

经常混迹于 GitHub 的话就会发现很多项目都有一些徽章,出现最多的就数这两个了:

这些徽章都是可以点击的,第一个点进去是 https://www.travis-ci.com/,travis-ci 是一个 CI(Continuous integration,持续集成) 平台,主要提供集群编译、单测、集成测试的环境。.org 的服务对公有仓库免费,.com 面向私人、团队、公司的项目提供商业支持(收费)。使用起来非常简单,使用 Github 帐号登录进去,就能看见开始界面:

核心就是.travis.yml的文件配置,一开始可以根据自己的语言选择初始的配置文件:https://docs.travis-ci.com/user/customizing-the-build#Specifying-Runtime-Versions。我这边的项目使用的是 Python,初始配置是:

官方注释可以说非常详细,我就不画蛇添足做说明了,根据自己代码实际情况做调整即可:

配置好之后再 push 代码,就能在 travis-ci 页面上看见项目的构建、测试结果了:

点击图标就能生成我们需要的 MD 语法的代码了,粘贴进 README.MD 中就能显示了。

第二个徽章是 codecov.io(单测覆盖率统计平台),接入过程也很简单,也是不同语言选择不同的配置文件,codecov 可以无缝衔接 travis-ci,只需要在原来的配置文件上稍作修改即可,核心就是生成单测的结果文件。修改后的 .travis.yml

在原来的基础上多了 codecov nose 插件的下载和运行单测时多了--with-coverage等参数。最后还是再次 push 代码就能看见单测覆盖率报告了:

codecov 还有自己的配置文件:codecov.yml。用来实现一些定制化需求,比如说我需要排除一些模块,不进入覆盖率统计:

徽章生成代码的话在setting中可以找到:

除了上面介绍的这两个徽章,还可以通过 shields.io 平台生成一些其它的徽章,甚至可以自定义,比如 https://img.shields.io/badge/Python-2.7-brightgreen.svg 就可以生成一个表示 Python 版本的徽章,别人能看懂就行。

当然徽章不是重点,不是越多的越牛逼,重要的是规范整个研发流程。上面说的两个其实都是属于 CI(持续集成)中最具代表性的两个环节,算是入门了。关于 CI 是一个很大的话题了,这个有机会以后再说一下。

参考资料:

开源项目徽章集锦,https://segmentfault.com/a/1190000004278253

使用 Python nose 组织 HTTP 接口测试

现在前端 Web、移动端 APP 开发基本上是面向接口编程,后端各种 HTTP 接口已经提供好了,大家只要实现逻辑交互和展示就行。那么问题来了,这么多接口如何方便的进行测试呢?根据个人经验,我认为需要解决三个问题:1. HTTP 接口多种多样,测试程序如何统一?2. 测试程序如何规范组织?3. 接口间有上下文依赖,如何解决?

HTTP 接口多种多样,测试程序如何统一?

后端接口可能来自各个系统,GET/POST 协议的、遵循 RESTful 规范的,使用 session 认证、token 认证的,各式各样的接口都存在。但无论怎么变都无法脱离 HTTP 协议。因为组内的技术栈是 Python,这就很容易想到使用 Python 的 requests 库。首先我们使用requests.Session()会话对象,来进行会话保持和 Header、Cookie 等处理。这里我们可以简单封装一个 HttpSession 类,把一些常用操作和设置封装一下:

通过HttpSession()来获取一个requests session对象,后续的 HTTP 请求都通过它发起。requests 提供 get()、post() 等各种方法调用,但这会让测试代码显得不统一,这里我们直接调用底层的 request 方法,该方法几乎提供了发起一个 HTTP 请求需要的所有参数,非常强大。

这样每一个 HTTP 接口的测试都可以通过准备参数发起请求断言结果三板斧来解决。

测试程序如何规范组织?

前面我们已经解决了如何快捷的发起一个 HTTP 请求的问题,这让我们几行代码就可以测试一个接口的返回值。但你会发现新的问题又来了,各种脚本散乱在一堆,返回值解析各种中间变量,各种配置硬编码在代码中,测试结果全靠 print,这时 nose 框架就派上用场了。nose 是 Python 最流行的一个单测框架,提供测试 case 设置标签、测试 case 查找、强大的断言函数,格式化/可视化报告输出等功能。这样就可以像写单测一样写 HTTP 接口测试了。我们可以把一类接口的测试放在一个类里面,甚至可以把基础变量的定义放在基础测试类里面,其它测试类继承这个基类。

HttpTest基类只做了两个工作:1. 创建http会话对象;2. 读取配置文件到类变量config中。配置文件是一个很好的编程实践,这让我们测试程序和数据能够分离,可以通过调用不同的配置文件来测试不同环境的接口,让我们测试程序不光能做线下测试,还能做线上回归和监控,切换成本非常低。

我这里选择 yaml 语法来组织配置信息,yaml 语法风格类似 json,自带基础数据结构,但更加易于书写和阅读,非常适合做配置文件。通过-env=xxx指定配置文件路径(或者 nose.cfg 配置文件中指定),使用 ruamel.yaml 来解析 yaml,转换为 Python 中能直接操作的数据结构。

这一切都放在setUpClass方法中,在具体测试 case 运行之前就已经准备好这些工作了。 Continue Reading...