一、pytest框架入门
与unittest不同,pytest使用的是python自带的assert关键字来进行断言。
assert关键字后面可以接一个表达式,只要表达式的最终结果为True,那么断言结果判定为通过,用例执行成功,否则用例执行失败。
1、pytest的理解:
pytest是只用自动化测试框架,pytest向下兼容unittest。
pytest有自己的一套命名规范:
(1)文件名:以test开头,或者以test结尾;
(2)类:以Test开头,且类中不能有init方法;
(3)方法或函数:以test_开头;
(4)断言:必须使用assert。
2、assert小例子:
#pytest入门
#2021/8/31
assert '你好哈'
# 异常信息
def f():
return 3
def test_function():
a = f()
assert a + 2 == 3,"判断 a 的值为1,实际当前a 的值为:%s" % a
if __name__=="__main__":
test_function()
执行结果如下:
================== RESTART: E:\python编程代码\python基础\pytest入门.py =================
Traceback (most recent call last):
File "E:\python编程代码\python基础\pytest入门.py", line 16, in <module>
test_function()
File "E:\python编程代码\python基础\pytest入门.py", line 12, in test_function
assert a + 2 == 3,"判断 a 的值为1,实际当前a 的值为:%s" % a
AssertionError: 判断 a 的值为1,实际当前a 的值为:3
3、常用断言方式:
pytest 里面断言实际上就是 python 里面的 assert 断言方法,常用的有以下几种:
- assert xx :判断 xx 为真,判断某个语句是否为真
- assert not xx :判断 xx 不为真,逻辑运算符not
- assert a in b :判断 b 包含 a,判断某个值是否属于某个对象
- assert a == b :判断 a 等于 b,判断等式两边是否相等
- assert a != b :判断 a 不等于 b,判断某个值是否不等于另一个值
4、pytest框架的使用
#test_pytest #2021/8/31 import os #需要用到系统自带的目录、文件操作名来操作 import allure import pytest class Test11: def test_1(self): assert 1+1==2 #判断预期结果与实际结果是否相等 def test_2(self): assert 'Hello' #判断Hello为真 def test_3(self): assert 3 in (1,2,3,4,5,6) #判断3是否在(1,2,3,4,5,6) def test_4(self): assert not 200 #判断不为真 def test_5(self): assert not False #判断不为假 def test_6(self): assert True #判断为真 def test_7(self): assert 3!=9 #判断3不等于9 def test_8(self): assert 9==9 #判断9等于9 def test_9(self): assert not True # 判断为假 if __name__=="__main__": pytest.main(['test_pytest.py','-s']) #-s表示运行执行print语句
执行结果如下:
绿点代表测试用例通过,红色F表示测试用例判定失败。
5、setup(),teardown()
在所有用例方法之前和之后执行
import os #需要用到系统自带的目录、文件操作命令 import allure import pytest class Test11: def setup(self):#(1) print(" 这是开始 ",end='') def test_1(self): #① assert 1+1==2 #判断预期结果与实际结果是否相等 def test_2(self):#② assert 'Hello' #判断Hello为真 def test_3(self):#③ assert 3 in (1,2,3,4,5,6) #判断3是否在(1,2,3,4,5,6) def test_4(self):#④ assert not 200 #判断不为真 def test_5(self):#⑤ assert not False #判断不为假 def test_6(self):#⑥ assert True #判断为真 def test_7(self):#⑦ assert 3!=9 #判断3不等于9 def test_8(self):#⑧ assert 9==9 #判断9等于9 def test_9(self):#⑨ assert not True # 判断为假 def teardown(self):#(2) print(" 这是结束 ",end='') if __name__=="__main__": pytest.main(['test_pytest.py','-s']) #-s表示运行执行print语句
执行顺序如下:
(1)①(2) (1)②(2) (1)③(2)........(1)⑧(2) (1)⑨(2)
运行结果:
6、setup_method(),teardown_method()
在所有用例方法之前和之后执行
import os #需要用到系统自带的目录、文件操作命令 import allure import pytest class Test11: def setup_method(self): # (1) print(" 这是开始 ", end='') def test_1(self): # ① assert 1 + 1 == 2 # 判断预期结果与实际结果是否相等 def test_2(self): # ② assert 'Hello' # 判断Hello为真 def test_3(self): # ③ assert 3 in (1, 2, 3, 4, 5, 6) # 判断3是否在(1,2,3,4,5,6) def test_4(self): # ④ assert not 200 # 判断不为真 def test_5(self): # ⑤ assert not False # 判断不为假 def test_6(self): # ⑥ assert True # 判断为真 def test_7(self): # ⑦ assert 3 != 9 # 判断3不等于9 def test_8(self): # ⑧ assert 9 == 9 # 判断9等于9 def test_9(self): # ⑨ assert not True # 判断为假 def teardown_method(self): # (2) print(" 这是结束 ", end='') if __name__ == "__main__": pytest.main(['test_pytest.py', '-s']) # -s表示运行执行print语句
执行顺序如下:
(1)①(2) (1)②(2) (1)③(2)........(1)⑧(2) (1)⑨(2)
运行结果:
7、setup_class(),teardown_class()
在每个类之前和之后执行
import os #需要用到系统自带的目录、文件操作命令 import allure import pytest class Test11: def setup_class(self):#(1) print(" 这是开始 ",end='') def test_1(self): #① assert 1+1==2 #判断预期结果与实际结果是否相等 def test_2(self):#② assert 'Hello' #判断Hello为真 def test_3(self):#③ assert 3 in (1,2,3,4,5,6) #判断3是否在(1,2,3,4,5,6) def test_4(self):#④ assert not 200 #判断不为真 def teardown_class(self): # (2) print(" 这是结束 ", end='') class Test2: def setup_class(self): # (1) print(" 这是开始 ", end='') def test_5(self):#⑤ assert not False #判断不为假 def test_6(self):#⑥ assert True #判断为真 def test_7(self):#⑦ assert 3!=9 #判断3不等于9 def test_8(self):#⑧ assert 9==9 #判断9等于9 def test_9(self):#⑨ assert not True # 判断不为真 def teardown_class(self):#(2) print(" 这是结束 ",end='') if __name__=="__main__": pytest.main(['test_pytest.py','-s']) #-s表示运行执行print语句
执行顺序如下:
(1)①②③④(2) (1)⑤⑥⑦⑧⑨(2)
运行结果如下:
8、setup_module(),teardown_module()
在整个模块开始之前,和结束之后执行。
import os #需要用到系统自带的目录、文件操作命令 import allure import pytest def setup_module(self): # (1) print(" 这是开始 ", end='') def teardown_module(self):#(2) print(" 这是结束 ",end='') class Test11: def test_1(self): #① assert 1+1==2 #判断预期结果与实际结果是否相等 def test_2(self):#② assert 'Hello' #判断Hello为真 def test_3(self):#③ assert 3 in (1,2,3,4,5,6) #判断3是否在(1,2,3,4,5,6) def test_4(self):#④ assert not 200 #判断不为真 class Test2: def test_5(self):#⑤ assert not False #判断不为假 def test_6(self):#⑥ assert True #判断为真 def test_7(self):#⑦ assert 3!=9 #判断3不等于9 def test_8(self):#⑧ assert 9==9 #判断9等于9 def test_9(self):#⑨ assert not True # 判断为假 if __name__=="__main__": pytest.main(['test_pytest.py','-s']) #-s表示运行执行print语句
执行顺序如下:
(1)①②③④⑤⑥⑦⑧⑨(2)
运行结果如下:
9、以@pytest.fixture()实现setup(),teardown()
import os #需要用到系统自带的目录、文件操作命令 import allure import pytest # 装饰器,相当于setup,缺省值为function级 @pytest.fixture(scope='module') #scope可以加入参数scope='class' ,将级别改为class #scope可以加入参数scope='module' ,将级别改为module #scope='session' ,使用该级别时,将fixture的内容写到conftest.py文件中,目录下的所有文件都使用这个配置 def sum(): print(" 这是开始 ", end='') # (1) yield #yield关键字之后的代码,相当于teardown print(" 这是结束 ",end='') # (2) def test_sum(sum):#⑩ assert 2==2 class Test11: def test_1(self,sum): #① assert 1+1==2 #判断预期结果与实际结果是否相等 def test_2(self,sum):#② assert 'Hello' #判断Hello为真 def test_3(self,sum):#③ assert 3 in (1,2,3,4,5,6) #判断3是否在(1,2,3,4,5,6) def test_4(self,sum):#④ assert not 200 #判断不为真 class Test2: def test_5(self,sum):#⑤ assert not False #判断不为假 def test_6(self,sum):#⑥ assert True #判断为真 def test_7(self,sum):#⑦ assert 3!=9 #判断3不等于9 def test_8(self,sum):#⑧ assert 9==9 #判断9等于9 def test_9(self,sum):#⑨ assert not True # 判断不为真 if __name__=="__main__": pytest.main(['test_pytest.py','-s']) #-s表示运行执行print语句
(1)当@pytest.fixture(),缺省值为空时,即默认值,执行顺序与setup_method(),teardown_method()类似。
(1)⑩(2) (1)①(2) (1)②(2) (1)③(2)........(1)⑧(2) (1)⑨(2)
运行结果如下:
(2)当@pytest.fixture(scope='class'),缺省值为scope='class'时,执行顺序与setup_class(),teardown_class()类似。
(1)⑩(2) (1)①②③④(2) (1)⑤⑥⑦⑧⑨(2)
运行结果如下:
(3)当@pytest.fixture(scope='module'),即缺省值为scope='module'时,执行顺序与setup_module(),teardown_module()类似。
(1)⑩①②③④⑤⑥⑦⑧⑨(2)
运行结果如下:
二、数据驱动
1、@pytest.mark.parametrize('expected_result,real_result', [[4+1, 5], [0+4, 4], [3, 3], [4 + 2, 6], [1 + 5, 6]])
注意:这个方法需写在测试类里面才生效。
import os #需要用到系统自带的目录、文件操作名来操作 import allure import pytest # 装饰器,相当于setup,缺省值为function级 @pytest.fixture(scope='class') #scope可以加入参数scope='class' ,将级别改为class #scope可以加入参数scope='module' ,将级别改为module #scope='session' ,使用该级别时,将fixture的内容写到conftest.py文件中,目录下的所有文件都使用这个配置 def sum(): print(" 这是开始 ", end='') # (1) yield #yield关键字之后的代码,相当于teardown print(" 这是结束 ",end='') # (2) class Test11: @pytest.mark.parametrize('expected_result,real_result', [[4, 5], [3+1, 4], [1+2, 3], [4 +1, 5], [2 + 4, 6]]) def test_sum(self, expected_result, real_result,sum): # ⑩ assert expected_result == real_result class Test2: @pytest.mark.parametrize('expected_result,real_result', [[4+1, 5], [0+4, 4], [3, 3], [4 + 2, 6], [1 + 5, 6]]) def test_sum(self, expected_result, real_result,sum): # ⑩ assert expected_result == real_result if __name__=="__main__": pytest.main(['test_pytest.py','-s']) #-s表示运行执行print语句
运行结果如下: