pytest单元测试框架学习 入门到精通(持续更新)

1.pytest单元测试框架

1)什么是单元测试框架
单元测试是指在软件开发中,针对软件的最小单位(函数,方法)进行正确性的检查测试。
2)单元测试框架
Java:junit,testng
python:unittest,pytest
3)单元测试框架主要做什么?
1.测试发现:从多个文件中找到我们的测试文件,用例;
2.测试执行:按照一定的顺序和规则去执行,并生成结果;
3.测试判断:通过断言判断预期结果和实际结果的差异;
4.测试报告:统计测试进度,耗时,通过率,生成测试报告。

2.自动化测试框架和单元测试框架的关系。

1)什么是自动化测试框架
2)作用
1.提高测试效率,降低维护成本;
2.减少人工干预,提高测试的准确性,增加代码的复用性;
3.核心思想是让不懂代码的人也能通过该框架,轻松完成测试。
3)pytest单元测试框架和自动化测试框架的关系
单元测试框架:只是自动化测试框架的组成部分之一;
pom设计模式:只是自动化测试框架的组成部分之一。
数据驱动
关键字驱动
全局配置文件的封装
日志监控
selenium,requests二次封装
断言
报告邮件
更多。。。。。。

3.pytest简介

1)pytest是一个非常成熟的python单元测试框架,比unittest更灵活,上手;
2)pytest可以和selenium,requests,appnium结合实现web自动化,接口自动化,app自动化测试;
3)pytest可以实现用例的跳过,错误用例的resuns;
4)pytest可以结合allure生成非常美观的测试报告;
5)pytest可以和jenkins持续集成;
6)pytets有很多强大的插件,并且这些插件能够实现很多非常有用的操作;
pytest
pytest-html 生成html格式的自动化测试报告;
pytest-xdist 测试用例分布式执行,多cpu分发;
pytest-ordering 改变测试用例的执行顺序;
pytest-rerunfailures 用例失败重跑;
allure-pytest 用于生成优美的报告。

pycharm快捷安装,将上述包报道requirements.txt文件中,通过terminal 执行:pip install -r requirements.txt

检查安装完成:pytest --version

4.待定

1)模块名必须以test_开头或以_test结尾;
2)测试类必须以Test开头,且不能有init方法;
3)测试方法必须以test开头。

5.pytest测试用例的运行方式

1).主函数模式
1.运行所有:pytest.main()
2.指定模块:pytest.main([’-vs’, ‘test_login.py’])
3.指定目录:pytest.main([’-vs’,’./interface_testcase’])
4.通过nodeid指定测试用例执行:nodeid由模块名,分隔符,类名,方法名,函数名组成。
pytest.main([’-vs’, ‘./interface_testcase/test_interface.py::test_04_func’])
pytest.main([’-vs’, ‘./test_interface/test_interface.py::Testinterface::test_03_zhidao’])
2)命令行模式
1.运行所有:pytest
2.指定模块:pytest -vs ./test_login.py
3.指定目录:pytest -vs ./test_intestface
4.指定目录:pytest -vs ./test_inteface/test_interface.py::test_04_func
3)py.test 参数 脚本
4)python -m pytest 参数 脚本

注:参数详解:
-s: 表示输出调试信息,包括print打印信息;
-v: 显示更详细信息;
-vs:两参数一起用。
-q:以极简方式运行;	
-n::支持多线程或者分布式执行用例;
	如:pytets -vs ./test_case -n 2
			pytest.main(['-vs', './test_case', '-n=2'])
--reruns NUM :失败用例重跑;
-x: 只要出现一个用例报错,全部都停止;
--maxfail=2:出现两个用例失败就停止;
-k: 测试包含指定字符串用例;
	例:pytest -vs ./test_case -x "ao"
--html ./report/report.html  :生成html测试报告

3)通过读取pytest.ini配置文件运行
pytest.ini是pytest单元测试框架的核心配置文件;
1.位置:一般放在项目的根目录;
2.编码:必须是ANSI,可以使用notepad++修改编码格式;
3.作用:改变pytest的默认行为;
4.运行规则:不管是主函数的运行,命令模式运行,都会读取这个配置文件。
[pytest]
addopts = -vs
testpaths = ./test_case
python_files = test_*.py
python_clasees = Test
python_functions = test
markers =
smoke:冒烟用例
usermanage:用户管理模块
productmanage:商品模块管理

6.pytest执行用例的顺序是怎么样的呢?

unittest 是ascll的大小决定执行的顺序;
pytest默认从上倒下;
改变默认执行顺序:使用mark 标记;
例子: @pytest.mark.run(order=3)

7.如何分组执行(冒烟,分模块执行,分接口和web执行)

smoke:冒烟用例,分布在各个模块里面;
pytest.ini文件中添加相关markers
在这里插入图片描述

命令行执行:
pytest -m “smoke”
pytest -m “smoke or usermanage”

8.pytest跳过测试用例

1)无条件的
@pytest.mark.skip
在这里插入图片描述

2)有条件的
@pytest.mark.skipif(num >= 20, reason=“太大了”)
在这里插入图片描述

9.pytest结合allure-pytest插件生成allure报告

1.下载,解压,配置环境变量path路径;
请提前安装好jdk,并配置好环境变量!!!
https://github.com/allure-framework/allure2/releases
验证:allure --version
问题:dos可以验证,pycharm验证不了,建议重启pycharm

2.加入命令,生成临时json报告;
–alluredir ./temp
3.生成allure报告
os.system(‘allure generate ./temp -o ./report --clean’)
allure generate 命令,固定的
./temp 临时的json报告路径
-o 输出output
./report 生成的allure报告的路径
–clean 清空。./report路径原来的报告

10. @pytest.mark.parametrize(args, value)用法

args:参数名称
value:值(列表,元组,字典列表,字典元组),有多少值,用例就执行多少次。

第一种方式:

import pytest


class TestApi:

    @pytest.mark.parametrize('args', ['haha', 'keke', 'xixi'])
    def test_ala(self, args):
        print(args)


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

第二种方式:类似u’nittest中ddt的@unpack解包

import pytest


class TestApi:

    @pytest.mark.parametrize('name, age', [['dad', 18], ['xiuxiu', 19], ['lula', 20]])
    def test_ala(self, name, age):
        print(name, age)


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

11.前置后置

1.模块级,作用范围为当前模块,模块中的所有用例执行前后分别执行1次前置后置:
setup_module(),前置,所有用例执行前执行一次;
teardown_module(),后置,所有用例执行后执行一次。

import pytest


def setup_module():
    print("\n这是前置!")


def teardown_module():
    print("\n这是后置!")


@pytest.mark.parametrize('a', [1, 2, 3, 4, 5])
def test_f(a):
    print(a)


if __name__ == '__main__':
    pytest.main(['-s', __file__])

2.函数级,作用范围为当前模块中的每一个测试函数,模块中的每条用例执行前后分别执行一次;
setup_function(),前置,每条用例执行前执行一次;
teardown_function(),后置,每条用例执行后执行一次。
3.函数级,作用范围为当前类,类中的所有用例执行前后分别执行一次;
setup_class(),前置,所有用例执行前执行一次;
teardown_class(),后置,所有用例执行后执行一次。

import pytest


class Test:
    def setup_class(self):
        print("\n这是前置!")

    def teardown_class(self):
        print("\n这是后置!")

    @pytest.mark.parametrize('a', [1, 2, 3, 5])
    def test_p(self, a):
        print(a)


if __name__ == '__main__':
    pytest.main(['-s', __file__])

4.方法级,作用范围为当前类中的每一个测试方法,每条用例执行前后分别执行一次前置和后置;
setup_method()或者setup(),前置,每条用例执行前执行一次;
teardown_method()或者teardown(),后置,每条用例执行后执行一次。
5.fixture
1.创建: @pytest.fixture([name, scope, params, autouse])
name: 指定fixture名称, 如果不指定则默认为被装饰的函数名;
scope: 指定fixture的作用范围,module,class,function(默认),session,package;
params:参数
autouse:设置为True,实现自动调用fixture。
例子1:

import pytest

# 创建fixture
@pytest.fixture(name='fx', scope='module', autouse=True)
def login():
    print("这是登录!")
    yield "注销"    # 通过yield实现后置

def test_add(fx):
    a = fx
    print("添加会员!")
    print(a)

def test_qurey():
    print("这是查询!")


if __name__ == '__main__':
    pytest.main(['-vs', __file__])

2.全局fixture
	在项目目录下创建conftest.py文件,在该文件中实现fixture。
	例子待更新。。。。。

11.yaml文件详解–实现自动化

1.用于全局的配置文件ini/yaml
2.用于写测试用例(接口测试用例)
注意:安装pyyaml包

yaml简介:
yaml是一种数据格式,支持换行,注释,多行字符串,裸字符串(整形,字符串)。

语法规则:
1.区分大小写;
2.使用缩进表示层级,不能使用tab键缩进,只能使用空格(和python一样);
3.缩进没有数量的,只要前面是对齐的就行;
4.注释是#

数据组成:

1.map对象,键值对,键:(空格)值;
多行写法:

resp:
    name: dada
    age: 18

单行写法

resp: {name: dada,age: 18}

2.数组list用一组横线开头,如:
多行写法:

-
    resp: 
       - name: dada
       - age: 18

单行写法:

-
    resp: [{name:dada},{age: 18}]

3.编写完ymal文件,需要编写相应的py文件进行解析,获取yaml文件内容,例如YamlUtil.py

import yaml


class YamlUtil:
    def __init__(self, yaml_file):
        """
        指定读取文件
        :param yaml_file:
        """
        self.yaml_file = yaml_file

    def read_yaml(self):
        """
        读取yaml文件
        :return:
        """
        with open(self.yaml_file, encoding='utf-8') as f:
            value = yaml.load(f, Loader=yaml.FullLoader)
            print(value)


if __name__ == '__main__':
    YamlUtil('test_api.yaml').read_yaml()

12.接口自动化测试

1.以百度查询大象页面为例,本问去掉其他相关参数,只添加 搜索关键字wd,
url = ‘https://www.baidu.com/s?’
wd = “大象” # 可能需要进行utf-8编码

test_api.yaml如下:

-
  name: 测试百度查询大象
  request:
    url: https://www.baidu.com
    method: get
    params:
      wd: 大象
    headers:
      Content-Type: application/json
  validate:
    - eq: {code: 200}

yaml_util.py文件内容如下:

import yaml


class YamlUtil:
    def __init__(self, yaml_file):
        """
        指定读取文件
        :param yaml_file:
        """
        self.yaml_file = yaml_file

    def read_yaml(self):
        """
        读取yaml文件
        :return:
        """
        with open(self.yaml_file, encoding='utf-8') as f:
            value = yaml.load(f, Loader=yaml.FullLoader)
            return value

测试case:test_da.py内容如下:

#!encoding:utf-8
import pytest
import requests
from yaml_util import YamlUtil


class TestDax:
    @pytest.mark.parametrize('args', YamlUtil('test_api.yaml').read_yaml())
    def test_daxiang(self, args):
        print(args)
        url = args['request']['url']
        wd = str(str(args['request']['params']['wd']).encode(encoding='utf-8'))[1:].upper()  # 关键字编码,或许可省略,没尝试
        args['request']['params']['wd'] = wd
        params = args['request']['params']
        resp = requests.get(url, params)
        print(resp.status_code)
        print(resp.text)
        assert resp.status_code == args['validate'][0]['eq']['code']

然后使用上文提到创建的test_main相关文件执行,结果图如下:
在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值