1.pytest的格式:模块名用以test开头或者结尾,类名为Test开头,函数名以test开头,同时里面不能含构造函数(__init__),如果有继承,建议用setup和teardown。
2.运行:-v: 表示的是详细日志,-s:表示运行过程中打印print的文本,__file__:表示当前文件
if __name__=="__main__":
pytest.main(["-vs",__file__])
3.pytest只会运行以test开头的函数和方法。
import pytest
class Test_a():
def test_1(self):
print("这是test1")
def test_2(self):
print("这是test2")
def mytest(self):
print("这是mytest")
def yourtest():
print("这是yourtest")
def test_3():
print("这是test_3")
if __name__=="__main__":
pytest.main(["-vs",__file__])
#运行结果:
# test_Q.py::Test_a::test_1 这是test1
# PASSED
# test_Q.py::Test_a::test_2 这是test2
# PASSED
# test_Q.py::test_3 这是test_3
# PASSED
4.pytest.mark主要用的方法是pytest.parameterize。
4.1pytest.mark的skip和skipif的用法,skip表示强制跳过,skipif表示条件成立则跳过
import pytest
a=1
b=2
class Test_a():
def test_1(self):
print("这是test1")
@pytest.mark.skip("reason--->不运行") #skip,原因:不运行
def test_2(self):
print("这是test2")
@pytest.mark.skipif("a<b") #如果a<b,skip
def test_3(self):
print("这是test3")
@pytest.mark.skipif("a>b") #如果a>b,skip
def test_4(self):
print("这是test4")
def mytest(self):
print("这是mytest")
def yourtest():
print("这是yourtest")
def test_5():
print("这是test_5")
if __name__=="__main__":
pytest.main(["-vs",__file__])
#运行结果:
# test_Q.py::Test_a::test_1 这是test1
# PASSED
# test_Q.py::Test_a::test_2 SKIPPED (reason--->不运行)
# test_Q.py::Test_a::test_3 SKIPPED (condition: a<b)
# test_Q.py::Test_a::test_4 这是test4
# PASSED
# test_Q.py::test_5 这是test_5
# PASSED
4.2 pytest.mark运行指定的函数或方法 ,用-m=取名来运行
import pytest
a=1
b=2
class Test_a():
def test_1(self):
print("这是test1")
def test_2(self):
print("这是test2")
def test_3(self):
print("这是test3")
def test_4(self):
print("这是test4")
@pytest.mark.testa
def test_A(self):
print("这是testA")
def mytest(self):
print("这是mytest")
def yourtest():
print("这是yourtest")
def test_5():
print("这是test_5")
if __name__=="__main__":
pytest.main(["-vs","-m=testa",__file__])
#运行结果:
# test_Q.py::Test_a::test_A 这是testA
# PASSED
4.3 pytest.mark.parametrize (变量名,[(参数值1),(参数值2)]),传参
import pytest
from selenium import webdriver
class Test_c():
# def test_login(self): #传统方法传参,只能传一个。或者用ddt多次传参。这里用parametrize多次传参。
# self.driver=webdriver.Chrome()
# self.driver.get("https://www.baidu.com")
# self.driver.find_element('id','kw').send_keys("阴阳师")
# self.driver.find_element('id','su').click()
@pytest.mark.parametrize("url,kw",[('https://www.baidu.com','阴阳师'),('https://www.baidu.com','网易')])
def test_login(self,url,kw):
self.driver = webdriver.Chrome()
self.driver.get(url)
self.driver.find_element('id','kw').send_keys(kw)
self.driver.find_element('id','su').click()
def test_test():
print("这是一个测试")
if __name__=="__main__":
pytest.main(["-vs",__file__])
#运行结果:
# test_c.py::Test_c::test_login[https://www.baidu.com-\u9634\u9633\u5e08] PASSED
# test_c.py::Test_c::test_login[https://www.baidu.com-\u7f51\u6613] PASSED
# test_c.py::t
5.1 pytest.fixture和setup,teardown类似.
setup,teardown的函数,在以test开头的方法启动前运行一次setup的函数,运行完运行一次teardown的函数。
setup_module,teardown_module的函数,在模块启动前运行一次,运行完运行一次
setup_class,teardown_class的函数,只在Test开头的类里的以test开头的方法启动前运行一次setup的函数,运行完运行一次teardown的函数。外面的以test开头的函数照常运行。
pytest.fixture(scope="function",autouse=True),表示每个用例运行前都会执行。需要注意的是fixture的函数不要用test开头或者结尾,要和用例区别开。
import pytest
@pytest.fixture(scope="function",autouse=True) #运行范围:在每个函数运行前和运行后执行,autouse自动执行。
def myfixture():
print("+++++")
yield
print("-----")
class Test_a():
def test_1(self):
print("这是test1")
def test_2(self):
print("这是test2")
def mytest(self):
print("这是mytest")
def yourtest():
print("这是yourtest")
if __name__=="__main__":
pytest.main(["-vs",__file__])
#运行结果:
# test_Q.py::Test_a::test_1 +++++
# 这是test1
# PASSED-----
#
# test_Q.py::Test_a::test_2 +++++
# 这是test2
# PASSED-----
yield和return类似,在return后,该方法下面的语句就不再运行了。yield之前的执行语句类似于setup,yield后面的执行语句类似于teardown,(这两个在接口测试中经常用于token和cookie的传输。)yield和return的值在调用的函数中通常是用fixture函数的名传入。举例:
import pytest
@pytest.fixture(scope="function") #运行范围:在每个函数运行前和运行后执行,这里取消了autouse,则只有指定的函数运行fixture函数。
def myfixture():
print("+++++")
yield[1,2,3,4]
print("-----")
class Test_a():
def test_1(self):
print("这是test1")
def test_2(self,myfixture):
print("fixture传过来的值--->",myfixture) #这里逗号不能去掉。
def mytest(self):
print("这是mytest")
def yourtest():
print("这是yourtest")
if __name__=="__main__":
pytest.main(["-vs",__file__])
#运行结果:
# test_Q.py::Test_a::test_1 这是test1
# PASSED
# test_Q.py::Test_a::test_2 +++++
# fixture传过来的值---> [1, 2, 3, 4]
# PASSED-----
import pytest
@pytest.fixture(scope="function") #运行范围:在每个函数运行前和运行后执行,这里取消了autouse,则只有指定的函数运行fixture函数。
def myfixture():
print("++++++")
a="***"
return a
class Test_a():
def test_1(self):
print("这是test1")
def test_2(self,myfixture):
print("fixture传过来的值--->",myfixture) #这里逗号不能去掉。
def mytest(self):
print("这是mytest")
def yourtest():
print("这是yourtest")
if __name__=="__main__":
pytest.main(["-vs",__file__])
#运行结果:
# test_Q.py::Test_a::test_1 这是test1
# PASSED
# test_Q.py::Test_a::test_2 ++++++
# fixture传过来的值---> ***
# PASSED