pytest_02

 

 

9-参数化parametrize

重要)

pytest.mark.parametrize装饰器可以实现测试用例参数化。

参数是列表,包含了元祖,然后每个元祖包含的是一组参数,然后,代码逻辑再处理根据传参进行逻辑处理

 

2.它也可以标记单个测试实例在参数化,例如使用内置的mark.xfail

# content of test_expectation.py
import pytest
@pytest.mark.parametrize("test_input,expected", [
                        ("3+5", 8),
                        ("2+4", 6),
                        pytest.param("6 * 9", 42, marks=pytest.mark.xfail),
                        ])
def test_eval(test_input, expected):
    print("-------开始用例------")
    assert eval(test_input) == expected



if __name__ == "__main__":
    pytest.main(["-s", "test_canshu1.py"])

 pytest增加多个参数

适用场景  切换环境

import pytest
def pytest_addoption(parser):
    parser.addoption("--input1",default="default input1")
    parser.addoption("--input2",default="default input2")
@pytest.fixture
def input1(request):
    return request.config.getoption("--input1")
@pytest.fixture
def input2(request):
    return request.config.getoption("--input2")

----------------------
test1.py
import pytest
@pytest.mark.unit
def test_print_name(input1,input2):
    print ("Displaying input1: %s" % input1)
    print("Displaying input2: %s" % input2)

pytest执行方式

py.test -s test.py --input1 tt --input2 12

 

pytest-html生成html报告

pip install pytest-html

指定报告路径

1.直接执行"pytest --html=report.html"生成的报告会在当前脚本的同一路径,如果想指定报告的存放位置,放到当前脚本的同一目录下的report文件夹里

pytest --html=./report/report.html

报告独立显示

1.上面方法生成的报告,css是独立的,分享报告的时候样式会丢失,为了更好的分享发邮件展示报告,可以把css样式合并到html里;单独html报告

 pytest --html=report.html --self-contained-html

 

 

失败重试

失败重跑需要依赖pytest-rerunfailures插件,使用pip安装就行

pip install pytest-rerunfailures

用例失败再重跑1次,命令行加个参数--reruns就行了

$ py.test --reruns 1 --html=report.html --self-contained-html

关于reruns参数的2个用法

re-run failing tests to eliminate flaky failures:
  --reruns=RERUNS       number of times to re-run failed tests. defaults to 0.
  --reruns-delay=RERUNS_DELAY
                        add time (seconds) delay between reruns.

pytest  重试机制

第一种:对所有用例使用1、安装:pip install pytest-rerunfailures
2、命令行参数:pytest -- reruns 重试次数 (--reruns-delay 次数之间间隔)
                  pytest --reruns 2 运行失败的用例可以执行2次
                  pytest --reruns 2 --reruns-delay 5 运行失败的用例可以执行2次,每次间隔5秒

pytest.main(["-v","-m","demo","--reruns","2","--reruns-delay","5","--alluredir=../OutPuts/allure-results"])
pytest中的失败截图。

第二种:只对部分用例使用重运行机制在指定的用例使用装饰器,# 通常用上面的
@pytest.mark.flaky(reruns=5, reruns_delay=2)
def test_example():
    import random
    assert random.choice([True, False])

 

 

 

 

 

 

pytest文档10-命令行传参

 

带参数启动

1.如果不带参数执行,那么传默认的default="type1",接下来在命令行带上参数去执行

命令行参数是根据命令行选项将不同的值传递给测试函数,比如平常在cmd执行"pytest --html=report.html",这里面的”--html=report.html“就是从命令行传入的参数
对应的参数名称是html,参数值是report.html

conftest配置参数

1.首先需要在conftest.py添加命令行选项,命令行传入参数”--cmdopt“, 用例如果需要用到从命令行传入的参数,就调用cmdopt函数:

# content of conftest.py
import pytest


def pytest_addoption(parser):
    parser.addoption(
        "--cmdopt", action="store", default="type1", help="my option: type1 or type2"
    )

@pytest.fixture
def cmdopt(request):
    return request.config.getoption("--cmdopt")

2.测试用例编写案例

# content of test_sample.py
import pytest
def test_answer(cmdopt):
    if cmdopt == "type1":
        print("first")
    elif cmdopt == "type2":
        print("second")
    assert 0  # to see what was printed

if __name__ == "__main__":
    pytest.main(["-s", "test_case1.py"])

cmd打开,输入指令启动,也可以在pycharm里面右键执行上面代码

$ pytest -s test_sample.py

 

带参数启动

1.如果不带参数执行,那么传默认的default="type1",接下来在命令行带上参数去执行

$ pytest -s test_sample.py --cmdopt=type2

 

2.命令行传参数有两种写法,还有一种分成2个参数也可以的,参数和名称用空格隔开

$ pytest -s test_case1.py --cmdopt type2

 

pytest文档11-assert断言

断言是写自动化测试基本最重要的一步,一个用例没有断言,就失去了自动化测试的意义了。什么是断言呢?
简单来讲就是实际结果和期望结果去对比,符合预期那就测试pass,不符合预期那就测试 faile

异常断言

为了写关于引发异常的断言,可以使用pytest.raises作为上下文管理器,如下

# content of test_assert1.py

import pytest
def test_zero_division():
    with pytest.raises(ZeroDivisionError):
        1 / 0

运行结果

============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: D:\YOYO\canshuhua, inifile:
plugins: metadata-1.7.0, html-1.19.0
collected 1 item

test_assert1.py.

========================== 1 passed in 0.31 seconds ===========================

如果我们要断言它抛的异常是不是预期的,比如执行:1/0,预期结果是抛异常:ZeroDivisionError: division by zero,那我们要断言这个异常,通常是断言异常的type和value值了。
这里1/0的异常类型是ZeroDivisionError,异常的value值是division by zero,于是用例可以这样设计

 

常用断言

pytest里面断言实际上就是python里面的assert断言方法,常用的有以下几种

  • assert xx 判断xx为真
  • assert not xx 判断xx不为真
  • assert a in b 判断b包含a
  • assert a == b 判断a等于b
  • assert a != b 判断a不等于b

 

pytest文档14-函数传参和fixture传参数request

暂时没用到

登录函数传参

把登录单独出来,写一个函数,传2个参数user和psw,写用例的时候调用登录函数,输入几组user,psw参数化登录用例

测试用例传参需要用装饰器@pytest.mark.parametrize,里面写两个参数

  • 第一个参数是字符串,多个参数中间用逗号隔开
  • 第二个参数是list,多组数据用元祖类型
import pytest
# 测试登录数据
class sk(object):

def login(self,user, psw):
'''普通登录函数'''
print("登录账户:%s"%user)
print("登录密码:%s"%psw)
if psw:
return True
else:
return False
class Test_sk(object):
ks_sk=sk()
test_login_data = [("admin", "111111"), ("admin", "222222")]
@pytest.mark.parametrize("user, psw", test_login_data)
def test_login(self,user, psw):
'''登录用例'''
result = self.ks_sk.login(user, psw)
assert result == True, "失败原因:密码为空"

 

request参数

如果想把登录操作放到前置操作里,也就是用到@pytest.fixture装饰器,传参就用默认的request参数
user = request.param 这一步是接收传入的参数,本案例是传一个参数情况

添加indirect=True参数是为了把login当成一个函数去执行,而不是一个参数

request传2个参数

如果用到@pytest.fixture,里面用2个参数情况,可以把多个参数用一个字典去存储,这样最终还是只传一个参数
不同的参数再从字典里面取对应key值就行,如: user = request.param["user"]

# test_03.py
# coding:utf-8
import pytest

# ** 作者:上海-悠悠 QQ交流群:588402570**

# 测试账号数据
test_user_data = [{"user": "admin1", "psw": "111111"},
                  {"user": "admin1", "psw": ""}]

@pytest.fixture(scope="module")
def login(request):
    user = request.param["user"]
    psw = request.param["psw"]
    print("登录账户:%s" % user)
    print("登录密码:%s" % psw)
    if psw:
        return True
    else:
        return False

# indirect=True 声明login是个函数
@pytest.mark.parametrize("login", test_user_data, indirect=True)
def test_login(login):
    '''登录用例'''
    a = login
    print("测试用例中login的返回值:%s" % a)
    assert a, "失败原因:密码为空"


if __name__ == "__main__":
    pytest.main(["-s", "test_03.py"])

 

 

posted @ 2021-08-04 09:08  walkerpython  阅读(49)  评论(0编辑  收藏  举报