pytest插件地址
安装:pip install pytest
1.表达用例:
# unittest:
class TestA(unittest.TestCase):
def test_01(self):
print("1")
# pytest:
def test_a():
print("a")
class TestA:
def test_b(self):
print("b")
def ceshi_c(self):
print("我不是测试用例")
2.断言的表达
unittest:assertEqual()、assertTure()… pytest:assert
表达式(结果为Ture:断言成功,否则失败) - 表达式可以是逻辑/成员/比较/函数返回值
3.收集用例
unittest:TestLoader类/函数 + TestSuite、discover pytest:自动收集测试用例
pytest命令运行在哪,就从哪个目录下开始搜索用例
4.用例筛选:pytest - mark
给用例打个标记 - 设计用例的时候就打标记 - 有目的的
先注册标签名
1)pytest.ini文件 – 注释不能使用中文
[pytest]
markers =
标签名1: miao shu xinxi
标签名2
demo
2)打标记范围:测试用例 测试类 模块文件
方法一:在测试用例上/测试类前面加:@pytest.mark.已注册的标签名
@pytest.mark.标记名
def test_aaa():
print("aaa")
assert True
@pytest.mark.标记名
class TestA:
def test_bbb(self):
print("bbb")
assert 1 == 2
其他标记方法:
# 在测试类里,使用以下声明(测试类下,所有用例都被打上该标签):
class TestA(object):
pytestmark = pytest.mark.已注册的标签名 # 单标签
# pytestmark = [pytest.mark.标签1,pytest.mark.标签2] # 多标签模式
# 在模块文件里,同理(py文件下,所有测试函数和测试类里的函数,都有该标签)
import pytest
pytestmark = pytest.mark.已注册的标签名 # 单标签
# pytestmark = [pytest.mark.标签1,pytest.mark.标签2] # 多标签模式
def test_aaa():
print("aaa")
assert True
class TestA:
def test_bbb(self):
print("bbb")
assert 1 == 2
5.运行:
执行顺序
a.文件名 - ASCII
b.文件内部 - 代码的先后顺序,从上到下
1.cmd -
目录下全部搜索用例: pytest -s -v
只运行标记的用例:pytest -m 标记 -s -v
运行某个模块下 pytest -m 标签名 -s -v 模块名
2.run.py – pytest.main()
import pytest
pytest,main(["-s","-v","-m","标签名"]) # 选中的用例
pytest.main() # 收集到的全部
6.fixture前置后置
unittest:setUp&tearDown setupClass&teardownClass - 固定的名称
pytest:function(用例) -> class(测试类) -> Module(.py) -> Session(会话)
==问题1:.怎么知道函数是一个前置后置 ==
在函数前面: @pytest.fixtures
@pytest.fixtures()
def init():
pass
问题2:.如何区分前置后置?
yield - 前后置分隔线
@pytest.fixtures()
def init():
print("我是前置")
a = 1
b = 2
yield
print("我是后置")
问题3:作用域是什么?测试函数/类/模块/会话 ??定义作用域
@pytest.fixtures(scope=)
function:默认值 – unittest当中的setUp和teardowm
class:测试类 - unittest当中的setupclass和teardownclass
module:模块 —整个py文件
session:收集到的所有测试用例
问题4:测试用例当中如何调用前置后置?
注意:同时调用两个前置后置,需要这两个互不影响
在测试用例/类的前面 @pytest.mark.userfixtures(“定义fixture的名称”)
@pytest.fixtures
def init():
print("我是函数级别前置")
a = 1
b = 2
yield
print("我是函数别后置")
@pytest.fixture(scope="class")
def init1():
print("我是类级别前置")
c = 3
d = 4
yield
print("我是类级别后置")
# 测试用例
@pytest.mark.usefixtures("init")
def test_aaa():
print("aaa")
# @pytest.mark.usefixtures("init") # 这个也可以--作用下面所有用例
@pytest.mark.usefixtures("init1") # 作用于类下面的所有用例
# 测试用例
class TestA:
def test_bbb():
print("bbb")
def test_ccc():
print("ccc")
问题5:如何接收fixture的返回值?
# 返回前置中的变量
def init():
yield 返回值
yield 返回值多个 -- 元组 列表
接收返回值的方式
将fixture的函数名称,作为用例的参数 - 用例的参数 = 返回值
…
如果要使用fixture的返回值,用例一定要传参,然后可以不用@pytest.mark.usefixtures() - 会自己找
…
如果不使用fixture的返回值,测试用例要使用,必须声明@pytest.mark.usefixtures()
测试用例如果有参数:
1.数据驱动ddt
2.fixture的返回值
@pytest.fixture()
def init():
print("我是函数级别前置")
a = 1
b = 2
# yield a -- 返回单个
yield [a,b] -- 返回多个,可以用元组/列表
print("我是函数别后置")
@pytest.fixture(scope="class")
def init1():
print("我是类级别前置")
c = 3
d = 4
yield
print("我是类级别后置")
@pytest.mark.usefixtures("init") # 下面用例不使用返回值,就需要声明
class TestA:
def test_bbb(self):
print("bbb")
def test_ccc(self):
print("ccc")
@pytest.mark.usefixtures("init") # 使用返回值,就不需要声明 -- 也可以声明不影响
def test_aaa(init): # 使用返回值,就不需要声明 --会自动找init
print("aaa")
c = init[0] + 1
print(c)
# 不用声明会自己找
@pytest.mark.usefixtures("init1")
class TestD:
def test_ddd(self,init1)
print("ddd")
d = init1[1] + 1
print(d)
fixture本身是可以使用其他fixture的
测试用例级别
import pytest
from selenium import webdriver
from PO.PageObjects.login_page import LoginPage
from PO.TestDatas import Common_Datas
from PO.TestDatas.login_datas import LoginDatas
@pytest.fixture
def init_driver():
"""
前置:打开浏览器,访问地址
后置:退出
"""
driver = webdriver.Chrome()
driver.get(Common_Datas.login_url)
yield driver
driver.quit()
@pytest.fixture
def init_login(init_driver): # 类似继承
LoginPage(init_driver).login(*LoginDatas.success)
yield init_driver # 返回值
"""
执行顺序
init_driver的前置
init_login的前置
init_loginr的后置
init_driver的后置
"""
# session级别最大级别,所有用例都会先执行它
# 需要的地方主动调用 -- 注意使用,容易出事故 --也只有这个级别会打开
@pytest.fixture(scope="session", autouse=True) --只有一个的时候,可以使用自动调用
fixture相互调用 - 作用域级别问题:
class - function级别可以用class的fixture的参数
function - function可以调用
function - class 不可以调用/用function的参数
…
一个作用域的fixture,可以使用比他高的/他同级别fixture的参数
function,可以调class/function/module/session
function最小单位,最后执行。
…
session级别最大级别,所有用例都会先执行它 – 需要的地方主动调用 – 注意使用,容易出事故
总结:conftest.py–定义fixture
fixture - 灵魂很自由。定义/调用
定义:申明pytest.fixture/yield区分前后置/作用域scope
1.测试用例文件当中定义
2.conftest.py当中定义 – 共享 – 前提 很多模块都使用
…conftest.py定义的fixture – conftest.py所在的包下,所有的用例均可以。
…在不同的包下,可以创建自己的conftest.py
…
调用:测试用例/测试类
1.用例不需要使用fixture返回值:@pytest.mark.usefixtures("")
2.用例要使用fixture的返回值:
方式一:@pytest.mark.usefixtures("")。fixture函数名称作为用例参数。
方式二:fixture函数名称作为用例参数。
3.你需要的时候才调用。
4.如果测试类下面,所有的测试用例,都使用同一个函数级别的前置后置,
那么可以直接在类名上,申明调用:@pytest.mark.usefixtures(“函数级别的fixture”)