接口测试 接口测试工具 tep 介绍 (开源)

dongfanger · 2020年09月04日 · 最后由 dongfanger 回复于 2020年09月05日 · 198 次阅读

『 tep is a testing tool to help you write pytest more easily. Try Easy Pytest! 』

tep 前身

tep 的前身是接口自动化测试框架 pyface,一款面向对象设计的测试框架,我写过一篇博客介绍。

测试框架 / 测试工具

tep 的定位是 a testing tool,不是 a testing framework

框架/工具,是有区别的。最大的区别,就是我自认为是没有足够的能力去自主开发一套 “框架”!工具的能力,还是妥妥的!

自研的框架意味着不稳定,要花很多精力来踩坑填坑,别人不敢随便用的。工具只是站在巨人的肩膀上,出了问题,这个锅我不背!

tep 是 try easy pytest 的首字母缩写,tep 的目的是帮助你更简单地写 pytest,比如用 pytest+requests 写接口自动化。

pytest 是 python 的测试框架,很成熟。tep 是 pytest 的测试工具,很简单。

pytest 和 tep 都是开源项目。

设计理念

很大程度上借鉴了 HttpRunner(优秀的框架)。不同的是,tep 更着重写 python,而不是写 YAML 文件。

  • 简单是更好的
  • 每个人都能用 python 写自动化

这就是 tep 的设计理念。

项目结构

tests
    __init__.py
.gitignore
conftest.py

tep 提供了快速创建项目的能力,也就是脚手架。执行 tep startproject project_name,就可以创建项目结构,如,这里创建一个 demo,

$ tep startproject demo
2020-07-28 14:34:57.649 | INFO     | tep.scaffold:create_scaffold:40 - Create new project: demo
Project root dir: \PycharmProjects\demo

Created folder: demo
Created folder: demo\tests
Created file: demo\tests\__init__.py
Created file: demo\conftest.py
Created file: demo\.gitignore

tests 是一个 package,用于存放测试脚本,脚本文件以 test_开头或_test 结尾,pytest 才能识别到。个人喜欢以_test 结尾。

conftest.py 是一个全局文件,定义全局变量,也可以定义 fixture、hook、plugin 等,

import os

import pytest


@pytest.fixture(scope="session", autouse=True)
def project_cache(request):
    request.config.cache.set("project_dir", os.path.dirname(os.path.abspath(__file__)))


class Dev:
    test_url = 'https://dev.com'


class Qa:
    test_url = 'https://qa.com'


class Release:
    test_url = 'https://release.com'


# choose environment
env = Qa

# you can define your variables and functions and so on

1 定义了一个 fixture,把项目路径保存到 pytest 缓存中。

2 定义了环境的 class,多环境切换,不需要修改测试脚本。

3 自定义内容,比如用户登录 token 等。

专注于写脚本

项目结构很清晰。在conftest.py进行一些初始化/参数化/清理工作,在tests/写测试脚本。

不像 pyface 那样面向对象的封装,tep 更注重平铺写脚本的方式,这样就离 “每个人都能用 python 写自动化” 更近一步。毕竟封装之后看着容易晕,我也晕。

去除掉框架的约束,给每个人写 python 的自由,在测试脚本里你可以尽情发挥你的代码风格,代码能力,千人千面。代价呢,就是代码质量参差不齐。

这又怎么样呢,用过各种开源/自主研发的测试平台,还不是每个人都在写着自己风格的自动化 case!

大胆写,能写,写出来,跑通,就已经是在写自动化,就已经是在创造价值了!

tep 默认是不会创建 reports 文件夹的, 原因有二。

其一,如果你是本地执行的话,可以使用 --tep-reports 自定义命令行参数,来生成测试报告。

$ pytest --tep-reports

测试结束后会在 project_dir/reports 生成 report-2020-07-28的 allure 测试报告。

其二,如果你是持续集成的话,如 Jenkins,已经提供了 allure report 的插件,配置一下就可以自动生成测试报告,百度“jenkins allure”

附上 allure 常用命令,

pytest --alluredir=result  # 报告目录,会生成一堆数据文件
allure generate result -o html  # 生成html报告
allure serve html  # 启动服务
allure open html  # 打开报告(直接执行自动启动服务) PyCharm可以右键index.html选择Open in Browser

allure下载地址,下载解压后,把 bin 绝对路径添加到系统环境变量 Path 中。allure 需要安装 jdk。

轻封装

tep 尊重原生用法。

requests 的封装只通过装饰器做了 2 个封装,一是记录接口请求响应耗时,二是打印日志。只需要 from tep.client import request ,就可以和 requests.request 一样使用了,没有做任何其他的冗余修改。

#!/usr/bin/python
# encoding=utf-8

"""
@Author  :  Don
@Date    :  7/25/2020 2:02 PM
@Desc    :
"""

import decimal
import json
import time

import requests
import urllib3
from loguru import logger
from requests import sessions

from tep.funcs import NpEncoder

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def request_encapsulate(req):
    def send(*args, **kwargs):
        # elapsed
        start = time.process_time()
        response = req(*args, **kwargs)
        end = time.process_time()
        elapsed = str(decimal.Decimal("%.3f" % float(end - start))) + "s"

        # log
        try:
            log4a = {"method": args[0]}
            for k, v in kwargs.items():
                # if not json, str()
                try:
                    json.dumps(v)
                except TypeError:
                    v = str(v)
                log4a.setdefault(k, v)
            log4a.setdefault("status", response.status_code)
            log4a.setdefault("response", response.text)
            log4a.setdefault("elapsed", elapsed)
            logger.info(json.dumps(log4a, ensure_ascii=False, cls=NpEncoder))
        except AttributeError:
            logger.error("request failed")
        except TypeError:
            logger.warning(log4a)

        return response

    return send


@request_encapsulate
def request(method, url, **kwargs):
    """此处省略1万行代码,没做任何修改,从源码copy过来,只加了个装饰器"""

1 使用 time.process_time() ,记录了耗时。

2 打印日志,把请求响应的 method、url、headers、参数、响应状态码、响应体、耗时等数据保存到 json 中,输出控制台。

日志选择用 loguru 取代 logging,from loguru import logger 直接用,不用再管 handler 了。

  • faker,造数据工具
  • jmespath,json 解析工具
  • deepdiff,json 比较工具
  • pandas、numpy,数据处理工具

安装 tep,自动就把这些开源利器安装上了,无需单独安装。未来会集成更多实用工具到 tep 中。

tep 本身是很轻的。

源码

https://github.com/dongfanger/tep

这里安利一波 pytest官网教程,阅读英文文档,才能真正理解作者的意思。不过,我也会通过"try easy pytest"一系列的文章,把 pytest 的知识点提炼出来,供你学习。学 python,写 pytest,用 tep。测试更专业!

如果你觉得这篇文章写的还不错的话,关注公众号 “测试老树”,你的支持就是我写文章的最大动力。

最佳回复
Jerry li 回复

谢谢😊
我简单说下我做了哪些事
使用 poetry 包管理器添加了胶水代码,把 pytest、requests、allure、faker、jmespath、loguru、deepdiff、pymysql、sqlalchemy、texttable、pandas、numpy 等统一管理,上传到了 pypi,直接就可以安装和更新,方便团队内维护。
基本没怎么封装,就像前面同学说的那样。只是为了个性化定义,用装饰器加了点日志,方便调试。
提供了使用 pytest 组织用例目录的参考,也就是 scaffold。
使用 poetry 结合 pytest hook,写了个 plugin 或者说 hook,自定义了参数--tep-reports,一是加上后可以在本地生成测试报告(用 jenkins 的话就不需要),主要也是本地调试用,跑批量用例看效果。二是 allure trend 默认是没有数据的(jenkins 会自动填充),本地这里也弄了一下,能把每次批量跑的数据 trend 显示出来。
funcs 写了利己的一些公共函数。
dao 用 sqlalchemy 写了 pandas 会用到的 engine,目前只弄了 mysql,访问 db 返回的 dataframe,取数还是挺方便的。texttable 可以在 console 输出表格,方便查数据。
其实没做什么特别意外的事,就是把常用的东西整合整合,方便共享,也是技术积累。哈哈。有点类似工具包吧。很多技术都是跟着 httprunner 学的。
团队测试都想写纯 python,这是我们这样做的最重要原因!
我只是个渣渣😂

共收到 7 条回复 时间 点赞
1楼 已删除

哈哈
1 淡定
2 之前还不知道 requests 可以直接获取耗时,又可以优化下代码了😆
3 没怎么造轮子呀 就是借鉴 httprunner 思路简单组装而已
4 我们本来就是直接写 python

自动化本身并不难,难的是如何让自动化产生价值

小酷 回复

嗯,本来不打算发出来的,每个公司都有自己合适的技术实现。
看来后面还是只在这里发硬干货,不然容易口水战😂

给楼主的动手能力和分享精神点赞!
不过其实简单看来,暂时没看到什么对 pytest 的封装和简化在哪里,可以给一些具体的例子吗?和现在还挺流行的 pytest+allure+jenkins 组合有什么优势呢?

Jerry li 回复

谢谢😊
我简单说下我做了哪些事
使用 poetry 包管理器添加了胶水代码,把 pytest、requests、allure、faker、jmespath、loguru、deepdiff、pymysql、sqlalchemy、texttable、pandas、numpy 等统一管理,上传到了 pypi,直接就可以安装和更新,方便团队内维护。
基本没怎么封装,就像前面同学说的那样。只是为了个性化定义,用装饰器加了点日志,方便调试。
提供了使用 pytest 组织用例目录的参考,也就是 scaffold。
使用 poetry 结合 pytest hook,写了个 plugin 或者说 hook,自定义了参数--tep-reports,一是加上后可以在本地生成测试报告(用 jenkins 的话就不需要),主要也是本地调试用,跑批量用例看效果。二是 allure trend 默认是没有数据的(jenkins 会自动填充),本地这里也弄了一下,能把每次批量跑的数据 trend 显示出来。
funcs 写了利己的一些公共函数。
dao 用 sqlalchemy 写了 pandas 会用到的 engine,目前只弄了 mysql,访问 db 返回的 dataframe,取数还是挺方便的。texttable 可以在 console 输出表格,方便查数据。
其实没做什么特别意外的事,就是把常用的东西整合整合,方便共享,也是技术积累。哈哈。有点类似工具包吧。很多技术都是跟着 httprunner 学的。
团队测试都想写纯 python,这是我们这样做的最重要原因!
我只是个渣渣😂

dongfanger 回复

不错不错,加油!
对应模块像 SQL,numpy 这些感觉还是你们定制使用的比较多,感觉如果能拆分一下自主选择需要的模块就更好了

Jerry li 回复

👍 我试试

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