Skip to main content

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

Project description

tep

tepTry Easy Pytest的首字母缩写,是一款基于pytest测试框架的测试工具,集成了各种实用的第三方包和优秀的自动化测试设计思想,帮你快速实现自动化项目落地。

安装

支持Python3.6以上,推荐Python3.8以上。

标准安装:

$ pip install tep

国内镜像:

$ pip --default-timeout=600 install -i https://pypi.tuna.tsinghua.edu.cn/simple tep

检查安装成功:

$ tep -V  # 或者 tep --version
0.2.3

快速创建项目

tep提供了脚手架,预置了项目结构和代码,打开cmd,使用startproject命令快速创建项目:

tep startproject project_name

并且提供了-venv参数,在项目初始化时,可以同时创建一个虚拟环境(推荐):

tep startproject project_name -venv

输出测试报告

tep提供了--tep-reports参数来生成allure测试报告:

pytest  --tep-reports

报告文件存放在根目录的reports/中。

Mock服务

tep自带了一个Flask应用(utils/flask_mock_api.py),提供了登录到下单流程的5个接口,启动后即可一键运行示例中的测试用例。

三种开发模式

tep兼容三种开发模式:tep(用例数据一体)、mvc(用例数据分离)、HttpRunner。

①tep,示例代码如下所示:

import jmespath
from tep.client import request


def test(env_vars, login):
    # 搜索商品
    response = request(
        "get",
        url=env_vars.domain + "/searchSku",
        headers={"token": login.token},
        params={"skuName": "电子书"}
    )
    sku_id = jmespath.search("skuId", response.json())
    sku_price = jmespath.search("price", response.json())
    assert response.status_code < 400

    # 添加购物车
    sku_num = 3
    response = request(
        "post",
        url=env_vars.domain + "/addCart",
        headers={"token": login.token},
        json={"skuId": sku_id, "skuNum": sku_num}
    )
    total_price = jmespath.search("totalPrice", response.json())
    assert response.status_code < 400

    # 下单
    response = request(
        "post",
        url=env_vars.domain + "/order",
        headers={"token": login.token},
        json={"skuId": sku_id, "price": sku_price, "skuNum": sku_num, "totalPrice": total_price}
    )
    order_id = jmespath.search("orderId", response.json())
    assert response.status_code < 400

    # 支付
    response = request(
        "post",
        url=env_vars.domain + "/pay",
        headers={"token": login.token},
        json={"orderId": order_id, "payAmount": "6.9"}
    )
    assert response.status_code < 400
    assert response.json()["success"] == "true"

更多内容请参考《如何使用teprunner测试平台编写从登录到下单的大流程接口自动化用例》

②mvc

from tep.fixture import TepVars

from services.AddCart import AddCart
from services.Login import Login
from services.Order import Order
from services.Pay import Pay
from services.SearchSku import SearchSku

\"\"\"
测试登录到下单流程需要先运行utils / flask_mock_api.py
\"\"\"


class Test:
    case_vars = TepVars()
    case_vars.vars_ = {
        "domain": "http://127.0.0.1:5000",
        "skuNum": "3"
    }

    def test(self):
        # 登录
        Login(Test).post()
        # 搜索商品
        SearchSku(Test).get()
        # 添加购物车
        AddCart(Test).post()
        # 下单
        Order(Test).post()
        # 支付
        Pay(Test).post()

③HttpRunner,示例代码如下所示:

from httprunner import HttpRunner, Config, Step, RunRequest


class TestLoginPay(HttpRunner):
    config = (
        Config("登录到下单流程")
            .variables(
            **{
                "skuNum": "3"
            }
        )
            .base_url("http://127.0.0.1:5000")
    )

    teststeps = [
        Step(
            RunRequest("登录")
                .post("/login")
                .with_headers(**{"Content-Type": "application/json"})
                .with_json({"username": "dongfanger", "password": "123456"})
                .extract()
                .with_jmespath("body.token", "token")
                .validate()
                .assert_equal("status_code", 200)
        ),
        Step(
            RunRequest("搜索商品")
                .get("searchSku?skuName=电子书")
                .with_headers(**{"token": "$token"})
                .extract()
                .with_jmespath("body.skuId", "skuId")
                .with_jmespath("body.price", "skuPrice")
                .validate()
                .assert_equal("status_code", 200)
        ),
        Step(
            RunRequest("添加购物车")
                .post("/addCart")
                .with_headers(**{"Content-Type": "application/json",
                                 "token": "$token"})
                .with_json({"skuId": "$skuId", "skuNum": "$skuNum"})
                .extract()
                .with_jmespath("body.totalPrice", "totalPrice")
                .validate()
                .assert_equal("status_code", 200)
        ),
        Step(
            RunRequest("下单")
                .post("/order")
                .with_headers(**{"Content-Type": "application/json",
                                 "token": "$token"})
                .with_json({"skuId": "$skuId", "price": "$skuPrice", "skuNum": "$skuNum", "totalPrice": "$totalPrice"})
                .extract()
                .with_jmespath("body.orderId", "orderId")
                .validate()
                .assert_equal("status_code", 200)
        ),
        Step(
            RunRequest("支付")
                .post("/pay")
                .with_headers(**{"Content-Type": "application/json",
                                 "token": "$token"})
                .with_json({"orderId": "$orderId", "payAmount": "6.9"})
                .validate()
                .assert_equal("status_code", 200)
                .assert_equal("body.success", "true")
        ),
    ]

猴子补丁扩展request

扩展request,只需要实现utils/http_client.py里面的request_monkey_patch猴子补丁即可:

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

import decimal
import json
import time

import allure
from loguru import logger
from tep import client
from tep.client import TepResponse


def request_monkey_patch(req, *args, **kwargs):
    start = time.process_time()
    desc = ""
    if "desc" in kwargs:
        desc = kwargs.get("desc")
        kwargs.pop("desc")
    response = req(*args, **kwargs)
    end = time.process_time()
    elapsed = str(decimal.Decimal("%.3f" % float(end - start))) + "s"
    log4a = "{}\n{}status:{}\nresponse:{}\nelapsed:{}"
    try:
        kv = ""
        for k, v in kwargs.items():
            # if not json, str()
            try:
                v = json.dumps(v, ensure_ascii=False)
            except TypeError:
                v = str(v)
            kv += f"{k}:{v}\n"
        if args:
            method = f'\nmethod:"{args[0]}" '
        else:
            method = ""
        request_response = log4a.format(method, kv, response.status_code, response.text, elapsed)
        logger.info(request_response)
        allure.attach(request_response, f'{desc} request & response', allure.attachment_type.TEXT)
    except AttributeError:
        logger.error("request failed")
    except TypeError:
        logger.warning(log4a)
    return TepResponse(response)


def request(method, url, **kwargs):
    client.tep_request_monkey_patch = request_monkey_patch
    return client.request(method, url, **kwargs)

可选第三方包安装

# pip install --default-timeout=6000 -i https://pypi.tuna.tsinghua.edu.cn/simple pandas

# mysql
pandas==1.1.0
SQLAlchemy==1.3.19
PyMySQL==0.10.0
texttable==1.6.2

# more

用户手册

https://dongfanger.gitee.io/blog/chapters/tep.html

联系我

https://dongfanger.gitee.io/blog/more.html

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tep-0.9.7.tar.gz (22.8 kB view hashes)

Uploaded Source

Built Distribution

tep-0.9.7-py3-none-any.whl (22.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page