首页 > 编程语言 >python接口自动化pytest+yaml+allure

python接口自动化pytest+yaml+allure

时间:2023-04-02 18:45:06浏览次数:51  
标签:__ python pytest yaml allure test import

简介

  1. 分层 common公共层 data数据层 test层+main文件
  2. 其中pytest框架使用pytest.ini全局配置和conftest.py夹具

test层

  1. 下载对于的安装包
  2. 编写对于的用例
  3. 实现参数化
  4. 编写对于的fixture和pytest全局配置

常用pytest执行方法
main方法: pytest.main(['-vs','-n 2'])
console: pytest -vs -n 2
pytest.ini文件: addopts = -vs -n 2

常用命令
-v 详细信息
-s 输出打印信息
-n 多线程跑
--reruns 失败重跑
-m 执行分组
-k 执行包含该字符串的

下载对于的依赖

代码展示

import pytest
import requests

from common.readFile import re_yaml
from common.tools import dic_execute
from common.readFile import re_conf


class TestCase:
    # 分组--参数化
    @pytest.mark.smock
    @pytest.mark.parametrize("dic", re_yaml())
    def test_demo1(self, get_csrf, get_config, dic):
        # 获取基础配置
        base_url = get_config
        # 用夹具获取cookie和token
        cookie, token = get_csrf
        # 测试标题
        print(dic['description'])
        # 拿测试数据,发请求
        info = dic_execute(dic['data'])
        url = base_url + "users"

        data = {
            "id": 11,
            "name": info['date'],
            "username": info['user'],
            "datetime": info['pwd'],
            "token" :token
        }

        res = requests.request('post', url, data=data, cookies={'cookie': cookie})
        print(res.text)
        assert res.status_code == info['assert']

    # 排序
    @pytest.mark.run(order=1)
    def test_demo2(self, get_config):
        print('测试pytest demo2')
        assert 1 == 2

    # 跳过
    @pytest.mark.skip("版本原因跳--过")
    def test_demo3(self, get_config):
        print('测试pytest demo3')

    #分组
    @pytest.mark.smock
    def test_demo4(self, get_config):
        print('测试pytest demo4')


if __name__ == '__main__':
    pytest.main()

夹具conftest.py文件

import re

import pytest

from common.readFile import re_conf


@pytest.fixture(scope="class")
def get_config():
    """
    读取配置信息
    """
    print("setup_class 读取config.ini文件信息")
    base_url = re_conf("http", "baseUrl")
    return base_url


@pytest.fixture(scope="class")
def get_csrf():
    print("get_csrf get请求,获取响应页面")
    mock_response_text = '''
    <html>
        <head>
        </head>
        <body>
        .....'name'='crsf' token='token123abcdefg123'
        </body>
    </html>
    '''
    cookie = "ADFBE response.cookie()"
    token = re.search("'name'='crsf' token='(.*?)'", mock_response_text).group(1)
    return cookie, token

外层的pytest.ini全局配置

[pytest]
addopts = -vs --alluredir ./temp --clean-alluredir -p no:warnings -m smock -n 2
testpath = ./tests
python_files=test_*.py
python_classes=Test*
python_function=test
# 分组
markers =
    smoke:冒烟用例
    usermanage:用户管理模块
    productmanage:商品管理模块
#filterwarnings =
#    error
#    ignore::UserWarning

common层

读文件方法

import configparser
import os

import yaml

path = os.path.dirname(__file__)
config_path = os.path.join(path, '../', "data/config.ini")
yaml_path = os.path.join(path, '../', 'data/data.yaml')


# 从ini文件中读取参数
def re_conf(title, key=None, file=config_path):
    conf = configparser.ConfigParser()
    conf.read(file, encoding='utf-8')

    if key is None:
        # 读取字段到Section对象
        return conf[title]
    else:
        # 读取具体的值
        return conf.get(title, key)


# 读取yaml文件
def re_yaml(file=yaml_path):
    with open(file, 'r', encoding='utf-8') as f:
        test_data = yaml.safe_load(f)
    return test_data


if __name__ == '__main__':
    # 方式一
    confObj = re_conf(title="http", file="../data/config.ini")
    print(confObj)
    print("方式一 " + confObj.get("baseUrl"))
    # 方式二
    data = re_conf(title="http", key="baseUrl", file="../data/config.ini")
    print("方式二 " + data)
    # 读yaml
    print(re_yaml(), type(re_yaml()))

执行字符串代码

import datetime


# 读取文件数据后,把可执行代码执行
def dic_execute(dic: dict):
    for k, v in dic.items():
        if isinstance(v, str):
            if v.startswith('<') and v.endswith('>'):
                dic[k] = eval(v[1:-1])

    return dic


if __name__ == '__main__':
    pass

主执行方法

import os
import pytest as pytest

if __name__ == '__main__':
    pytest.main()
    # # 把json报告转为html
    os.system("allure generate ./temp -o ./report --clean")
    # 用allure打开json报告
    os.system("allure serve ./temp")

allure

1.需要电脑上安装了allure并且配置了环境变量
windows:下载,解压,并配置环境变量:https://github.com/allure-framework/allure2/releases

常用方法

示例

import allure
import pytest

@allure.feature('test_success')
def test_success():
    """this test succeeds"""
    assert True

@allure.feature('test_failure')
def test_failure():
    """this test fails"""
    assert False

@allure.feature('test_skip')
def test_skip():
    """this test is skipped"""
    pytest.skip('for a reason!')

@allure.feature('test_broken')
def test_broken():
    raise Exception('oops')

if __name__ == '__main__':
    # pytest.main(["-s","allure-test.py"])
    '''
    -q: 安静模式, 不输出环境信息
    -v: 丰富信息模式, 输出更详细的用例执行信息
    -s: 显示程序中的print/logging输出
    '''
    pytest.main(['-s', '-q','test_allure02.py','--clean-alluredir','--alluredir=allure-results'])
    os.system(r"allure generate -c -o allure-report")

标签:__,python,pytest,yaml,allure,test,import
From: https://www.cnblogs.com/wn-garden/p/17281003.html

相关文章

  • Python 多线程死循环挂服务器时CPU占用过高问题
    我的某个程序里有这样一段代码,把程序挂在服务器爬取信息,因此用到死循环,同时又需要进行三个任务,于是使用了多线程。刚开始在死循环部分并没有加time.sleep(60),于是它一直在for循环,同时会进行.is_alive()(不确定这个消耗大不大),但总之这使得CPU占用过高。而加上sleep之后,直接就降下......
  • Python 文件与路径操作
    路径表示绝对路径:绝对路径是指从盘符开始的文件全路径,一般表现为“/”。如“C:/Users/TheUser/Desktop/temp.txt”(Windows)、“/Users/TheUser/Desktop/temp.txt”(Windows)、“/home/TheUser/temp.txt”(Linux)。相对路径:相对路径是指从本文件开始算起的文件路径,总体长......
  • K8S用yaml资源清单部署redis数据库,数据持久化保存
    1.创建redis存储数据目录和配置文件mkdir-p/data/redis/redis-config/touch/data/redis/redis-config/redis.confcat>>/data/redis/redis-config/redis.conf<<EOFrequirepass123456bind0.0.0.0save9001save30010save6010000EOF2.编写redis的yaml资源清单api......
  • k8s快速生成yaml的两种方式
    第一.kubectlcreate命令[root@k8s-master~]#kubectlcreatedeploymentnginx--image=nginx-oyaml--dry-run#不创建pod,打印出来W010616:21:43.89167917615helpers.go:663]--dry-runisdeprecatedandcanbereplacedwith--dry-run=client.apiVersion:apps/v......
  • python系列教程208——为什么使用lambda
    声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享这套python系列教程,希望能帮到大家!由于这套python教程不是由我所写,所以不如我的AI技术教学风趣幽默,学起来比较枯燥;但它的知识点还是讲到位的了,也值......
  • Python基础之pyautogui模块(详细总结鼠标键盘操作)
    来源:https://zhuanlan.zhihu.com/p/471275277仅用于个人学习(以防自己忘记)1.GUI控制功能控制鼠标键盘使用的模块为:pyautogui,这个模块操作起鼠标键盘的时候,非常的迅速,而且如果该模块控制了鼠标后,程序比较难关闭,这时我们有两个方法专门针对以上的情况:1.1自动防故障功能 ......
  • 用OpenCv-Python自带的LBPH识别器实现简单人脸识别(上)
    用OpenCv-Python自带的LBPH识别器实现简单人脸识别(上)引言:本文开发环境为:Windows10+phchram+Anaconda5.2(Python3.6)+Opencv4.5.5,用opencv-contrib原生的API完成了人脸识别的功能,其可以任意添加人脸ID数据,但其效果比较差(勉强能用),如果日后有时间的话,给大家出一期(挖坑)利......
  • 用OpenCv-Python自带的LBPH识别器实现简单人脸识别(下)
    介绍本文附录了通过LBPH实现简单人脸识别的源代码,分类效果并不是很好,供个人学习使用。人脸录入.pyimportcv2cap=cv2.VideoCapture(0)flag=1num=0while(cap.isOpened()):ret_flag,Vshow=cap.read()cv2.imshow("Capture_Test",Vshow)k=cv2.w......
  • javascript VS python 变量作用域
    js中函数内部默认是可以读取到外部声明的变量,python不可以,必须使用关键字globalglobal必须在函数内部使用,用以内化函数外部变量。在函数外部是无法声明全局变量的,或者说所谓的全局变量在函数内部是不好使的,这还叫什么全局变量?应该叫局外变量。而global是内部跟局外变量建立一种......
  • 孤狼老师-接口测试自动化(Python版完整版)-日志记录&测试报告
            此时,由于每次执行方法前,都会执行一遍setup,故每次都要初始化一次LoggerHelper方法,每次都会加载一次配置文件,优化LoggerHelper:        针对多个接口用例,使用如下方式:   ......