HttpRunner 300 行 Python 代码打造实用接口测试框架

debugtalk · 2017年06月28日 · 最后由 debugtalk 回复于 2017年08月20日 · 4571 次阅读

在刚开始实现ApiTestEngine的时候,@kasi 提议做一个 Java 版的。对于这样的建议,我当然是拒绝的,瞬即回复了他,“人生苦短,回头是岸啊”。

当然,我没好意思跟他说的是,我不会 Java 啊。不过最主要的原因嘛,还是因为 Python 的语法简洁,可以采用很少的代码量实现丰富的功能。

有多简洁呢?

刚在coveralls上看了下ApiTestEngine框架的代码统计行数,总行数只有 268 行,还不足 300 行。

当然,这个行数指的是框架本身的Python代码行数,不包括示例注释的行数。从上图可以看出来,LINES列是文件总行数,RELEVANT列是实际的Python代码行数。例如ate/runner.py文件,注释的行数是远多于实际代码行数的。

最极端的一个例子是,ate/testcase.py文件中的parse函数,示例注释行数 35 行,Python代码只有 2 行。

def parse(self, testcase_template):
   """ parse testcase_template, replace all variables with bind value.
   variables marker: ${variable}.
   @param (dict) testcase_template
       {
           "request": {
               "url": "http://127.0.0.1:5000/api/users/${uid}",
               "method": "POST",
               "headers": {
                   "Content-Type": "application/json",
                   "authorization": "${authorization}",
                   "random": "${random}"
               },
               "body": "${data}"
           },
           "response": {
               "status_code": "${expected_status}"
           }
       }
   @return (dict) parsed testcase with bind values
       {
           "request": {
               "url": "http://127.0.0.1:5000/api/users/1000",
               "method": "POST",
               "headers": {
                   "Content-Type": "application/json",
                   "authorization": "a83de0ff8d2e896dbd8efb81ba14e17d",
                   "random": "A2dEx"
               },
               "body": '{"name": "user", "password": "123456"}'
           },
           "response": {
               "status_code": 201
           }
       }
   """
   return self.substitute(testcase_template)

另外,如果算上单元测试用例的行数(731 行),总的Python代码行数能达到 1000 行的样子。嗯,代码可以精简,但是单元测试覆盖率还是要保证的,不达到 90% 以上的单元测试覆盖率,真不好意思说自己做了开源项目啊。

那这不足 300 行的 Python 代码,实际实现了哪些功能呢?

对比下《接口自动化测试的最佳工程实践(ApiTestEngine)》中规划的特性,已经实现了大半(前六项),至少已经算是一个有模有样的接口测试框架了。

  • 支持 API 接口的多种请求方法,包括 GET/POST/HEAD/PUT/DELETE 等
  • 测试用例与代码分离,测试用例维护方式简洁优雅,支持YAML/JSON
  • 测试用例描述方式具有表现力,可采用简洁的方式描述输入参数和预期输出结果
  • 接口测试用例具有可复用性,便于创建复杂测试场景
  • 测试执行方式简单灵活,支持单接口调用测试、批量接口调用测试、定时任务执行测试
  • 具有可扩展性,便于扩展实现 Web 平台化
  • 测试结果统计报告简洁清晰,附带详尽日志记录,包括接口请求耗时、请求响应数据等
  • 身兼多职,同时实现接口管理、接口自动化测试、接口性能测试(结合 Locust)

后面剩下的特性还在实现的过程中,但是可以预见得到,最后框架本身总的Python代码行数也不会超过 500 行。

当然,单纯地比代码行数的确是没有什么意义,写得爽写得开心才是最重要的。

最后引用下Guido van Rossum的语录:

Life is short, go Pythonic!

阅读更多

最后的最后

《ApiTestEngine 演进之路》系列文章还在继续写,只是前几天主要精力在编码实现上,博客方面没有同步更新,接下来我会整理好思路,继续完成余下的部分。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 24 条回复 时间 点赞

代码估计很精炼啊,我看了下我们这边的 python 版本代码都不止那么点,应该几千行了

卡斯 回复

主要原因是我充分复用了 requests 库和 unittest 库的 API,包括后续性能测试实现那部分,会复用 Locust

debugtalk 回复

其实是业务不一样,我们这边需要实现各种业务,例如加密解密,数据库各种操作等等,日志的各种处理,流程的转向等等,甚至包括数据的生成逻辑,任务的调度,消息队列等等,还有预期判断 request 发送消息 uinittest 基本没用🙈

卡斯 回复

requests 主要是处理跟 HTTP 请求响应部分的;至于你说的那些业务逻辑,是单独实现的,后面你可以看下我的案例(还在写)。

debugtalk 回复

😂 我指的只是业务流转,并不涉及测试案例~

卡斯 回复

业务流转不应该就是体现在用例里面么?例如生成一个订单号,然后去选仓、出库等操作,都可以通过一个用例场景来配置实现啊

#7 楼 @debugtalk 粗看了下 github 的代码,挺不错的,我会继续关注的。

—— 来自 TesterHome 官方 安卓客户端

Nisir 回复

有空了可以细看下,能提些建议就更好了

debugtalk 回复

业务的一些特殊处理 流转的衔接逻辑,这些通用的都需要抽离出来,不体现在用例层面的

debugtalk 回复

你的是通用框架,属于基础型。卡斯的还包含了一些根据公司业务定制的部分,属于完整解决方案型。我觉得区别应该在这里。

卡斯 回复

@kasi @chenhengjie123 我的理解应该是都可以采用统一的模式的,后面我详细介绍下我使用的方式哈,到时候再 @ 你们帮忙看下

现在觉得,半自动化才好用。。手动改小代码,随着业务的变化而变化😎

debugtalk 回复

业务的特殊性 不同行业很难统一化 另外还有一个最大的问题就是 python 真的只适合 api 的,对于微服务或者其他协议的支撑力度还是弱了点,所以我们这边淘汰掉 python 版本的底层了

卡斯 回复

刚好我遇到一个要测微服务,sdk 方面的接口,有些加密的参数必须走 sdk。现在我手动运行 sdk 获取到参数后,然后复制到 python 测试接口框架,这样测试速度也挺快的。。。

无人值守回归测试怎么办

卡斯 回复

我们选 java ,主要是因为大部分后端都用 java ,各种协议接入方便

如果要考虑长期体系化、平台化的发展,还是 java 比较实在。
然后我非常推荐底层主体,支撑用 java 去实现,一些工具化的东西可以结合 python 非常实用~

那就没法持续集成了

卡斯 回复

对于其它的协议,就只有找开源的客户端了,之前我们有基于 XMPP 协议搞了一个 Python 客户端,来实现内部通讯工具的自动化测试

大大我也推荐一下 java,现在很多后台框架用 java 写的,为方便测试我们是可以在现有框架基础上,自己在开发代码基础上,加一个测试接口类,优化效率。大大这么牛 B,等飞机的过程中就可以入门,下飞机就精通了。

tttttttttggggg 回复

求别黑😂
Java 之前其实也学过的,只是当前公司项目中 Java 后台的不多,而即使是用 Java 开发的,从通讯协议交互层面,Python 也都可以搞定,所以也就没有使用 Java 了。

太好了,我这种超级小白都能看得懂 。简单修改了一下:1、把测试用例文件中的 config 提取出来,放到外部,用来切换不同的环境(test || online)2、测试用例加入级别 (p1 p2 or smoke),在 load 时可以设定跑全局还是冒烟 , 仅仅是为了满足我们目前工作的需求,减少测试用例的维护

小弥勒 回复

赞!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册