年度大版本,tep3回归纯粹Python接口测试框架

image1

回顾

tep是基于pytest开发的接口测试框架,上个版本从小工具升级为了关键字驱动框架,通过pystats发现最近半年仍然有4000+人次在安装使用tep。时隔1年后,我对tep进行了一次大版本改造,抛弃tep2的Java代码风格,重新回归到tep1的纯粹Python风格。

纯粹Python

所谓纯粹Python,体现在两个方面,一个方面是tep源码进行了重写,更加Pythonic,自动化用例写起来也更加简单易懂;另一方面是抛弃了依赖Java的Allure和依赖C++的loguru,分别使用Python技术栈的pytest-html和logging替代。

tep3版本

简介

tep是Try Easy Pytest的首字母缩写,帮你轻松上手pytest。

框架特点:

  • 基于pytest封装,成熟、稳定且扩展性强。

  • 框架完全由Python构建,没有混杂其他语言。

  • 原生Python语法,学习Python,零成本使用框架。

  • HAR包转换pytest用例。

安装

支持Python3.8以上版本

创建虚拟环境:python -m venv venv

激活虚拟环境,Windows用户:activate.bat Mac用户:source venv/bin/activate

安装tep:pip install tep

验证安装成功:tep -V

目录结构

data
file
fixture
report
scripts
tests
.gitignore
conftest.py
pytest.ini
run.py

tep new demo就能快速创建项目名称为demo的项目脚手架。

用例示范

简单的请求:

from tep import request


def test():
    response = request("get", url="http://httpbin.org/status/200")
    assert response.status_code == 200

复杂的场景:

from tep import request
from tep import v

from data.global_data import GlobalData


class Data:
    v({
        "domain": GlobalData.domain,
        "skuNum": 2,
        "payAmount": 0.2
    })
    body_add_cart = '{"skuId":"${skuId}","skuNum":${skuNum}}'
    body_order = '{"skuId":"${skuId}","price":${skuPrice},"skuNum":${skuNum},"totalPrice":${totalPrice}}'
    body_pay = '{"orderId":"${orderId}","payAmount":${payAmount}}'


def test():
    url = v("${domain}/searchSku?skuName=book")
    response = request("get", url=url, headers=GlobalData.headers)
    assert response.status_code < 400
    v("skuId", response.jsonpath("$.skuId")[0])
    v("skuPrice", response.jsonpath("$.price")[0])

    url = v("${domain}/addCart")
    body = v(Data.body_add_cart)
    response = request("post", url=url, headers=GlobalData.headers, json=body)
    assert response.status_code < 400
    v("skuNum", response.jsonpath("$.skuNum")[0])
    v("totalPrice", response.jsonpath("$.totalPrice")[0])

    url = v("${domain}/order")
    body = v(Data.body_order)
    response = request("post", url=url, headers=GlobalData.headers, json=body)
    assert response.status_code < 400
    v("orderId", response.jsonpath("$.orderId")[0])

    url = v("${domain}/pay")
    body = v(Data.body_pay)
    response = request("post", url=url, headers=GlobalData.headers, json=body)
    assert response.status_code < 400
    assert response.jsonpath("$.success")[0] == "true"

用例和数据

数据怎么存放,这里给出了一个参考方案,在用例内定义class Data,然后通过类变量存放数据。不同的项目,不同的场景,不同的参数,可以考虑不一样的存放方式。

tep函数

不同于以往的fixture封装,tep内部没有再定义fixture,而是对外暴露函数:

__all__ = [
    "request",
    "v",
    "run",
    "har2case"
]

在使用时import即可,更容易理解。

函数v()

这是我认为tep3的最大亮点。函数v()根据不同的入参,有不同的含义:

  • 传入字典类型:初始化变量池

  • 传入字符串:解析变量

  • 传入2个参数:设置变量

变量值支持占位符写法${},参考JMeter或HttpRunner。

通过函数v()来管理变量,用例代码清爽了不少。

fixture

fixture在创建脚手架时,自动生成了3个:

  • fixture_login

  • fixture_login_xdist

  • fixture_mysql

主要用于生成数据和执行setup/teardown,更多用法可以深入学习pytest fixture。

har2case

抓取har包后,可以快速转换为自动化用例:

import os

from tep import har2case
from tep.config import Config


def test():
    har2case({
        "har": os.path.join(Config().FILE_DIR, "har", "flow.har"),
        "dir": os.path.join(Config().TESTS_DIR, "generated"),
        "overwrite": 1
    })

同时支持批量替换:

import os

from tep import har2case
from tep.config import Config


def test():
    har2case({
        "har": os.path.join(Config().FILE_DIR, "har", "flow.har"),
        "dir": os.path.join(Config().TESTS_DIR, "generated"),
        "overwrite": 1,
        "var": {"domain": "http://127.0.0.1:5000"},
        "url": {"http://127.0.0.1:5000": "${domain}"},
        "headers": {"Content-Type": "application/json", "Cookie": "de2e3ffu29"}
    })

测试报告

run.py入口执行,设置report后即可生成:

from tep import run

if __name__ == '__main__':
    run({
        "path": ["test_flow.py"],  # Relative path to tests, file or directory
        "report": 1  # Generate html report, 0: False, 1: True
    })

更多内容请安装tep体验或查看源码阅读。

源码

tep3 https://github.com/dongfanger/tep

tep2 https://github.com/dongfanger/tep/tree/2.2.4

tep1 https://github.com/dongfanger/tep/tree/1.0.0

欢迎大家讨论,对于接口测试框架,你有什么想法呢。