『 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本身是很轻的。

tep可持续发展

我是2014年参加工作的,2018年才开始接触接口测试(汗!),现在有2年多的接口测试经验,其中包括一整年的纯后端接口测试经验。

接口自动化第一次写了接口自动化框架AIM(基于unittest),后来又有pyface,以及中间改造过的各种临时版本。也用过一些开源框架如RobotFramwork、HttpRunner,使用过自研工具,如基于JMeter封装的平台。还有一些网上开源的“web接口自动化平台”,这个我是打个大大的问号的。实用性很差,功能很鸡肋,报错还多。接口自动化测试框架的轮子,造也造不完。

tep“测试工具”的定位完美的避开了所有这些框架的弊端。工具不会定义你如何写自动化脚本,工具只会帮你更好地写自动化脚本。

有理由相信,tep会成长为一款实用的测试工具。

源码

https://github.com/dongfanger/tep

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



专注测试,坚持原创,只做精品。欢迎关注公众号『东方er』



版权申明:本文为博主原创文章,转载请保留原文链接及作者。

pytest封神之路第一步 tep介绍的更多相关文章

  1. pytest封神之路第零步 快速入门

    背景:本文是在系列第五篇发表后的补充篇章,第一篇介绍了tep,可能对不熟悉pytest的朋友不够友好,特意补充入门篇,帮大家快速了解如何动手写pytest.如果你是从这篇文章第一次阅读,那么请忽略以上 ...

  2. pytest封神之路第五步 参数化进阶

    用过unittest的朋友,肯定知道可以借助DDT实现参数化.用过JMeter的朋友,肯定知道JMeter自带了4种参数化方式(见参考资料).pytest同样支持参数化,而且很简单很实用. 语法 在& ...

  3. pytest封神之路第二步 132个命令行参数用法

    在Shell执行pytest -h可以看到pytest的命令行参数有这10大类,共132个 序号 类别 中文名 包含命令行参数数量 1 positional arguments 形参 1 2 gene ...

  4. pytest封神之路第三步 精通fixture

    首先放一句"狠话". 如果你不会fixture,那么你最好别说自己会pytest. (只是为了烘托主题哈,手上的砖头可以放下了,手动滑稽) fixture是什么 看看源码 def ...

  5. pytest封神之路第四步 内置和自定义marker

    可以通过命令行查看所有marker,包括内置和自定义的 pytest --markers 内置marker 内置marker本文先讲usefixtures .filterwarnings .skip ...

  6. pytest封神之路第六步 断言技巧

    pytest的断言把Python语言简洁的优点发挥的淋漓尽致,因为它用的就是Python的标准断言assert. assert基础 assert用法 assert_stmt ::= "ass ...

  7. [EntLib]微软企业库5.0 学习之路——第一步、基本入门

    话说在大学的时候帮老师做项目的时候就已经接触过企业库了但是当初一直没明白为什么要用这个,只觉得好麻烦啊,竟然有那么多的乱七八糟的配置(原来我不知道有配置工具可以进行配置,请原谅我的小白). 直到去年在 ...

  8. 《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态

    1. 简介 今天北京下的雪好大好美啊!!!哎呀,忘记拍照片了,自己想象一下吧.言归真传,今天还是开始pytest的学习和修炼,上一篇写完后群里反响各式各样的,几家欢乐几家愁,有的高兴说自己刚好要用到了 ...

  9. ExtJS学习之路第一步:对比jQuery,认识ExtJS

    最近纷杂的事情比较多了,奔波ing!所以,Node.js 和Canvas动画系列都停止了,等稳定了再重拾书本继续学习!因为某种原因最近在看ExtJS,分享下学习的心得,希望对同道中人有所帮助. 第一用 ...

随机推荐

  1. 前缀和线性基HDU6579

    Operation 题解:看到区间最大异或和,首先想到的是线性基: 线性基可以处理的操作是: 在数列末尾插入一个数 查询全局的子集异或最大值 由于线性基的长度很短,因此我们可以将数列所有前缀的线性基保 ...

  2. DJANGO-天天生鲜项目从0到1-009-搜索功能实现(django-haystack+whoosh+jieba)

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  3. Flutter获取远程数据 刷新UI界面

    import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; void main() => r ...

  4. springboot(七)JavaMail发送邮件

    JavaMail简介: JavaMail是SUN提供给广大Java开发人员的一款邮件发送和接受的一款开源类库,支持常用的邮件协议,如:SMTP.POP3.IMAP,开发人员使用JavaMail编写邮件 ...

  5. Spring葵花宝典

    一 Spring简介 Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架 为了解决企业应用开发的复杂性而创建 二 Spring功能 1. 方便解耦 简化开发 Spring就是一 ...

  6. 如何在sed中使用变量,两种方法

    第一 在sed条件中是不认识变量取值的 sed '/$x/d' test 所以要想它能够识别变量 sed "/$x/d/" test 方法简单就是把"单引号"变 ...

  7. SpringBoot实现前后端数据交互、json数据交互、Controller接收参数的几种常用方式

    1.获取参数的集中常见注解 @PathVariable:一般我们使用URI template样式映射使用,即url/{param}这种形式,也就是一般我们使用的GET,DELETE,PUT方法会使用到 ...

  8. JPA第二天

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"springdata"获取视频和教程资料! b站在线视 ...

  9. Python read和write方法

    Python read和write方法: read(): 从文件中读取字符串 注:Python 字符串可以是二进制数据,而不仅仅是文字. 语法: 文件对象.read([count]) count:打开 ...

  10. PHP simplexml_load_file() 函数

    实例 转换 XML 文件为 SimpleXMLElement 对象,然后输出对象的键和元素: <?php高佣联盟 www.cgewang.com$xml=simplexml_load_file( ...