2024年最新Pytest和Allure测试框架-超详细版+实战_pytest allure(3),2024年最新这些面试题你会吗

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

test_input = ‘7*5’, expected = 30

@pytest.mark.parametrize(‘test_input,expected’,[(‘3+5’,8),
(‘2-1’,1),(‘7*5’,30)])
def test_eval(test_input,expected):

assert eval(test_input)==expected
E assert 35 == 30          ----提示把30改成35

test_param.py:7: AssertionError

Assertion failed


### 参数化2



import pytest
test_user_data=[‘linda’,‘sai’,‘tom’]
@pytest.fixture(scope=‘module’)
def login(request):
user=request.param
print(‘打开首页登陆%s’%user)
return user

#indirect=True是把login当作函数去执行
@pytest.mark.parametrize(‘login’,test_user_data,indirect=True)
def test_cart(login):
usera=login
print(‘不同用户添加购物车%s’%usera)
assert usera!=‘’

Process finished with exit code 0
打开首页登陆linda
PASSED [ 33%]不同用户添加购物车linda
打开首页登陆sai
PASSED [ 66%]不同用户添加购物车sai
打开首页登陆tom
PASSED [100%]不同用户添加购物车tom


### 参数化3



import pytest
test_user_data=[
{‘user’:‘linda’,‘password’:‘8888’},
{‘user’:‘servenruby’,‘password’:‘123456’},
{‘user’:‘test01’,‘password’:‘’}
]

@pytest.fixture(scope=‘module’)
def login_r(request):
#可以通过dict形式,虽然传递一个参数,但通过key的方式可以达到累死传入多个参数的效果
user=request.param[‘user’]
pwd=request.param[‘password’]
print(‘\n打开首页准备登陆,登陆用户%s,密码%s’%(user,pwd))
if pwd:
return True
else:
return False

#这是pytest参数化驱动,indeirect=True是把login_r当作函数去执行
@pytest.mark.parametrize(‘login_r’,test_user_data,indirect=True)
def test_cart(login_r):
#登陆用例
a=login_r
print(‘测试用例中login_r的返回值%s’%a)
assert a,‘失败原因,密码为空’

开首页准备登陆,登陆用户linda,密码8888
PASSED [ 33%]测试用例中login_r的返回值True

打开首页准备登陆,登陆用户servenruby,密码123456
PASSED [ 66%]测试用例中login_r的返回值True

打开首页准备登陆,登陆用户test01,密码
FAILED [100%]测试用例中login_r的返回值False

打开首页准备登陆,登陆用户linda,密码8888
PASSED [ 33%]测试用例中login_r的返回值True

打开首页准备登陆,登陆用户servenruby,密码123456
PASSED [ 66%]测试用例中login_r的返回值True

打开首页准备登陆,登陆用户test01,密码
FAILED [100%]测试用例中login_r的返回值False

test_mark_param_request2.py:19 (test_cart[login_r2])
login_r = False

@pytest.mark.parametrize(‘login_r’,test_user_data,indirect=True)
def test_cart(login_r):
#登陆用例
a=login_r
print(‘测试用例中login_r的返回值%s’%a)

assert a,‘失败原因,密码为空’
E AssertionError: 失败原因,密码为空
E assert False


### 参数化3\*3



import pytest
test_user_data1=[{‘user’:‘linda’,‘password’:‘888888’},
{‘user’:‘servenruby’,‘password’:‘123456’},
{‘user’:‘test01’,‘password’:‘’}]
test_user_data2=[{‘q’:‘中国平安’,‘count’:3,‘page’:1},
{‘q’:‘阿里巴巴’,‘count’:2,‘page’:2},
{‘q’:‘pdd’,‘count’:3,‘page’:1}]
@pytest.fixture(scope=‘module’)
def login_r(request):
#这是接受不了输入的参数,接收一个参数
user=request.param[‘user’]
pwd=request.param[‘password’]
print(‘\n用户名:%s,密码:%s’%(user,pwd))

@pytest.fixture(scope=‘module’)
def query_param(request):
q=request.param[‘q’]
count=request.param[‘count’]
page=request.param[‘page’]
print(‘查询的搜索词%s’%q)
return request.param

#这是pytest的数据驱动,indeirect=True是把login_r当作函数去执行
#从下往上执行
#两个数据进行组合测试,有3*3个测试用例执行(test_user_data1的个数*test_user_data2的个数
@pytest.mark.parametrize(‘query_param’,test_user_data2,indirect=True)
@pytest.mark.parametrize(‘login_r’,test_user_data1,indirect=True)
def test_login(login_r,query_param):
#登陆用例
print(login_r)
print(query_param)

pytest_mark_request3.py::test_login[login_r1-query_param0] ✓ 44% ████▌ 查询的搜索词pdd
None
{‘q’: ‘pdd’, ‘count’: 3, ‘page’: 1}

pytest_mark_request3.py::test_login[login_r1-query_param2] ✓ 56% █████▋
用户名:linda,密码:888888
None
{‘q’: ‘pdd’, ‘count’: 3, ‘page’: 1}

pytest_mark_request3.py::test_login[login_r0-query_param2] ✓ 67% ██████▋
用户名:test01,密码:
None
{‘q’: ‘pdd’, ‘count’: 3, ‘page’: 1}

pytest_mark_request3.py::test_login[login_r2-query_param2] ✓ 78% ███████▊ 查询的搜索词阿里巴巴
None
{‘q’: ‘阿里巴巴’, ‘count’: 2, ‘page’: 2}

pytest_mark_request3.py::test_login[login_r2-query_param1] ✓ 89% ████████▉ 查询的搜索词中国平安
None
{‘q’: ‘中国平安’, ‘count’: 3, ‘page’: 1}

pytest_mark_request3.py::test_login[login_r2-query_param0] ✓ 100% ██████████


## 五,第三方插件


### 1,调整测试用例的执行顺序


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923160343908.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **场景:未考虑按自然顺序执行时,或想变更执行顺序,比如增加 数据的用例要先执行,再执行删除的用例。测试用例默认是按名 称顺序执行的。  
 • 解决:  
 • 安装:pip install pytest-ordering  
 • 在测试方法上加下面装饰器  
 •@pytest.mark.last    —最后一个执行  
 • @pytest.mark.run(order=1)—第几个执行  
 pytest默认按字母顺序去执行的**



import pytest
@pytest.mark.run(order=1)
def test_01():
print(‘test01’)

@pytest.mark.run(order=2)
def test_02():
print(‘test01’)
@pytest.mark.last
def test_06():
print(‘test01’)

def test_04():
print(‘test01’)

def test_05():
print(‘test01’)
@pytest.mark.run(order=3)
def test_03():
print(‘test01’)

pytest_order.py::test_01 PASSED [ 16%]test01

pytest_order.py::test_02 PASSED [ 33%]test01

pytest_order.py::test_03 PASSED [ 50%]test01

pytest_order.py::test_04 PASSED [ 66%]test01

pytest_order.py::test_05 PASSED [ 83%]test01

pytest_order.py::test_06 PASSED [100%]test01


### 2, 执行用例遇到错误停止


![在这里插入图片描述](https://img-blog.csdnimg.cn/2019092316110841.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **• 正常全部执行完成后才能停止,如果想遇到错误时停止测试: -x;也可以当用例错误个数n达到指定数量时,停止测试:- - maxfail=n  
 • 执行:  
 • pytest -x -v -s 文件名.py      ------- -x是遇到错误就停止  
 • pytest -x -v -s 文件名.py —maxfail=2  ------- --maxfail=2 是遇到两个错误就停止**


### 3,执行用例失败后重新运行


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923161333851.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 \*\*场景:  
 • 测试失败后要重新运行n次,要在重新运行之间添加延迟时 间,间隔n秒再运行。  
 • 执行:  
 • 安装:pip install pytest-rerunfailures  
 • pytest -v - -reruns 5 --reruns-delay 1 —每次等1秒 重试5次


### 4,多条断言前面报错后面依然执行


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923161632732.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 pip3 install pytest-assume 断言后继续执行,但要修改断言\*\*



@pytest.mark.parametrize((‘x’, ‘y’), [(1, 1), (1, 0), (0, 1)])
def test_assume(x, y):
pytest.assume(x == y)
pytest.assume(3 == 4)
pytest.assume(5 == 9)


### 5,多线程并行与分布式执行


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923161715759.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **场景:测试用例1000条,一个用例执行1钟,一个测试人员执行需要1000分 钟。通常我们会用人力成本换取时间成本,加几个人一起执行,时间就会缩  
 短。如果10人一起执行只需要100分钟,这就是一种并行测试,分布式场景。  
 解决:pytest分布式执行插件:pytest-xdist,多个CPU或主机执行  
 前提:用例之间都是独立的,没有先后顺序,随机都能执行,可重复运行不 影响其他用例。  
 安装:Pip3 install pytest-xdist  
 • 多个CPU并行执行用例,直接加-n 3是并行数量:pytest -n 3 • 在多个终端下一起执行**



import pytest
import time

@pytest.mark.parametrize(‘x’,list(range(10)))
def test_somethins(x):
time.sleep(1)

pytest -v -s -n 5 test_xsdist.py ----一次执行5个


运行以下代码,项目结构如下


web\_conf\_py是项目工程名称



│ conftest.py
init.py

├─baidu
│ │ conftest.py
│ │ test_1_baidu.py
│ │ test_2.py
│ │ init.py

├─blog
│ │ conftest.py
│ │ test_2_blog.py
│ │ init.py


代码参考:



web_conf_py/conftest.py

import pytest

@pytest.fixture(scope=“session”)
def start():
print(“\n打开首页”)
return “yoyo”

web_conf_py/baidu/conftest.py

import pytest

@pytest.fixture(scope=“session”)
def open_baidu():
print(“打开百度页面_session”)

web_conf_py/baidu/test_1_baidu.py

import pytest
import time

def test_01(start, open_baidu):
print(“测试用例test_01”)
time.sleep(1)
assert start == “yoyo”

def test_02(start, open_baidu):
print(“测试用例test_02”)
time.sleep(1)
assert start == “yoyo”

if name == “__main__”:
pytest.main([“-s”, “test_1_baidu.py”])

web_conf_py/baidu/test_2.py

import pytest
import time

def test_06(start, open_baidu):
print(“测试用例test_01”)
time.sleep(1)
assert start == “yoyo”
def test_07(start, open_baidu):
print(“测试用例test_02”)
time.sleep(1)
assert start == “yoyo”

if name == “__main__”:
pytest.main([“-s”, “test_2.py”])

web_conf_py/blog/conftest.py

import pytest

@pytest.fixture(scope=“function”)
def open_blog():
print(“打开blog页面_function”)

web_conf_py/blog/test_2_blog.py

import pytest
import time
def test_03(start, open_blog):
print(“测试用例test_03”)
time.sleep(1)
assert start == “yoyo”

def test_04(start, open_blog):
print(“测试用例test_04”)
time.sleep(1)
assert start == “yoyo”

def test_05(start, open_blog):
‘’‘跨模块调用baidu模块下的conftest’‘’
print(“测试用例test_05,跨模块调用baidu”)
time.sleep(1)
assert start == “yoyo”

if name == “__main__”:
pytest.main([“-s”, “test_2_blog.py”])


正常运行需要消耗时间:7.12 seconds



E:\YOYO\web_conf_py>pytest
============================= test session starts =============================
platform win32 – Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, metadata-1.7.0, html-1.19.0, forked-0.2
collected 7 items

baidu\test_1_baidu.py … [ 28%]
baidu\test_2.py … [ 57%]
blog\test_2_blog.py … [100%]

========================== 7 passed in 7.12 seconds ===========================


设置并行运行数量为3,消耗时间:3.64 seconds,大大的缩短了用例时间



E:\YOYO\web_conf_py>pytest -n 3
============================= test session starts =============================
platform win32 – Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, metadata-1.7.0, html-1.19.0, forked-0.2
gw0 [7] / gw1 [7] / gw2 [7]
scheduling tests via LoadScheduling
… [100%]
========================== 7 passed in 3.64 seconds ===========================


### 6,其他有意思的插件


![在这里插入图片描述](https://img-blog.csdnimg.cn/2019092316380183.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 这里就不多说了,喜欢的可以自己研究下


### 7,使用pytest执行unittest的测试用例


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923163847734.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **执行unitest就和原来一样,尽量不要混合使用搞那些花里胡哨的,用哪个就哪个,就不多说了**


### 8,pytest-html生成报告


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923165032170.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告。兼容Python 2.7,3.6


pytest-html  
 1.github上源码地址【https://github.com/pytest-dev/pytest-html】


2.pip安装



$ pip install pytest-html


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923165613879.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)


3.执行方法



$ pytest --html=report.html


html报告  
 1.打开cmd,cd到需要执行pytest用例的目录,执行指令:pytest --html=report.html


![image](https://img-blog.csdnimg.cn/20190923165651977.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 2.执行完之后,在当前目录会生成一个report.html的报告文件,显示效果如下


![image](https://img-blog.csdnimg.cn/20190923165717834.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 指定报告路径  
 1.直接执行"pytest --html=report.html"生成的报告会在当前脚本的同一路径,如果想指定报告的存放位置,放到当前脚本的同一目录下的report文件夹里



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


![在这里插入图片描述](https://img-blog.csdnimg.cn/2019092316584467.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 2.如果想指定执行某个.py文件用例或者某个文件夹里面的所有用例,需加个参数。具体规则参考【pytest文档2-用例运行规则】


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923165818310.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 报告独立显示  
 1.上面方法生成的报告,css是独立的,分享报告的时候样式会丢失,为了更好的分享发邮件展示报告,可以把css样式合并到html里



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


显示选项  
 默认情况下,“ 结果”表中的所有行都将被展开,但具测试通过的行除外Passed。


可以使用查询参数自定义此行为:?collapsed=Passed,XFailed,Skipped。


更多功能  
 1.更多功能查看官方文档【https://github.com/pytest-dev/pytest-html】


## 六,日志管理及代码覆盖率


### 1, pytest中logging的应用


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923172224170.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)


### 2, 日志及级别的含义


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923172249900.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **自动化测试用例的调试信息非常有用,可以让我们知道现在的运行情况到,执行到哪步以及相应的出错信息等,可以在pytest里面,有时并不会输出所有信息,比如默认情况下pass的测试用例是没有print输出的。本文将介绍如何在pytest里面实时显示所有的log信息。**


**1. 用print输出log信息**  
 slowTest\_print.py



import time

def test_1():
print ‘test_1’
time.sleep(1)
print ‘after 1 sec’
time.sleep(1)
print ‘after 2 sec’
time.sleep(1)
print ‘after 3 sec’
assert 1, ‘should pass’

def test_2():
print ‘in test_2’
time.sleep(1)
print ‘after 1 sec’
time.sleep(1)
print ‘after 2 sec’
time.sleep(1)
print ‘after 3 sec’
assert 0, ‘failing for demo purposes’


运行上述程序,pytest会capture所有的输出,保存直到所有的测试用例都执行结束,并且只输出那些失败的测试用例的信息,对于成功的测试用例,没有print的信息显示。  
 从下面的运行结果,如果需要查看test\_1()的运行情况,没有log信息可看,print没有显示。



C:\Users\yatyang\PycharmProjects\pytest_example>pytest -v slowTest_print.py
============================= test session starts =============================
platform win32 – Python 2.7.13, pytest-3.0.6, py-1.4.32, pluggy-0.4.0 – C:\Python27\python.exe
cachedir: .cache
metadata: {‘Python’: ‘2.7.13’, ‘Platform’: ‘Windows-7-6.1.7601-SP1’, ‘Packages’: {‘py’: ‘1.4.32’, ‘pytest’: ‘3.0.6’, ‘pluggy’: ‘0.4.0’}, ‘JAVA_HOME’: ‘C:\Program Files (x86)\Java\jd
k1.7.0_01’, ‘Plugins’: {‘html’: ‘1.14.2’, ‘metadata’: ‘1.3.0’}}
rootdir: C:\Users\yatyang\PycharmProjects\pytest_example, inifile:
plugins: metadata-1.3.0, html-1.14.2
collected 2 items

slowTest_print.py::test_1 PASSED
slowTest_print.py::test_2 FAILED

================================== FAILURES ===================================
___________________________________ test_2 ____________________________________

def test\_2():
    print 'in test\_2'
    time.sleep(1)
    print 'after 1 sec'
    time.sleep(1)
    print 'after 2 sec'
    time.sleep(1)
    print 'after 3 sec'
  assert 0, 'failing for demo purposes'

E AssertionError: failing for demo purposes
E assert 0

slowTest_print.py:22: AssertionError
---------------------------- Captured stdout call -----------------------------
in test_2
after 1 sec
after 2 sec
after 3 sec
===================== 1 failed, 1 passed in 6.45 seconds ======================

C:\Users\yatyang\PycharmProjects\pytest_example>


我们可以用‘-s’参数或者 ‘–capture=no’,这样就可以输出所有测试用的print信息。但是pytest还是会等着所有的测试用例都执行完毕才会显示运行结果。可以看到下面的test\_1也显示出print的相关信息。



C:\Users\yatyang\PycharmProjects\pytest_example>py.test --capture=no slowTest_print.py
============================= test session starts =============================
platform win32 – Python 2.7.13, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
metadata: {‘Python’: ‘2.7.13’, ‘Platform’: ‘Windows-7-6.1.7601-SP1’, ‘Packages’: {‘py’: ‘1.4.32’, ‘pytest’: ‘3.0.6’, ‘pluggy’: ‘0.4.0’}, ‘JAVA_HOME’: ‘C:\Program Files (x86)\Java\jd
k1.7.0_01’, ‘Plugins’: {‘html’: ‘1.14.2’, ‘metadata’: ‘1.3.0’}}
rootdir: C:\Users\yatyang\PycharmProjects\pytest_example, inifile:
plugins: metadata-1.3.0, html-1.14.2
collected 2 items

slowTest_print.py test_1
after 1 sec
after 2 sec
after 3 sec
.in test_2
after 1 sec
after 2 sec
after 3 sec
F

================================== FAILURES ===================================
___________________________________ test_2 ____________________________________

def test\_2():
    print 'in test\_2'
    time.sleep(1)
    print 'after 1 sec'
    time.sleep(1)
    print 'after 2 sec'
    time.sleep(1)
    print 'after 3 sec'
  assert 0, 'failing for demo purposes'

E AssertionError: failing for demo purposes
E assert 0

slowTest_print.py:22: AssertionError
===================== 1 failed, 1 passed in 6.17 seconds ======================


**2. Python Logging用法**  
 一般情况下,一些程序的调试过程中我们会让它输出一些信息,特别是一些大型的程序,我们通过这些信息可以了解程序的运行情况,python提供了一个日志模块logging,它可以把我们想要的信息全部保存到一个日志文件中,方便查看。



import logging

logging.debug(‘This is debug message’)
logging.info(‘This is info message’)
logging.warning(‘This is warning message’)


屏幕上打印:  
 WARNING:root:This is warning message  
 默认情况下,logging将日志打印到屏幕,日志级别为WARNING;  
 日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,当然也可以自己定义日志级别。


**3. 在pytest中用logging代替print**  
 我们现在来看看在pytest的测试用例里面用logging的输出代替print,有什么不同。  
 slowTest\_logging.py



import time
import logging

logging.basicConfig(level=logging.DEBUG)

def test_1():
log = logging.getLogger(‘test_1’)
time.sleep(1)
log.debug(‘after 1 sec’)
time.sleep(1)
log.debug(‘after 2 sec’)
time.sleep(1)
log.debug(‘after 3 sec’)
assert 1, ‘should pass’

def test_2():
log = logging.getLogger(‘test_2’)
time.sleep(1)
log.debug(‘after 1 sec’)
time.sleep(1)
log.debug(‘after 2 sec’)
time.sleep(1)
log.debug(‘after 3 sec’)
assert 0, ‘failing for demo purposes’


运行结果如下,log信息的显示是不是可读性更好了呢。可是pytest还是要等所有的结果都运行完毕才完全输出到屏幕上,没法看到实时的运行情况。比如现在要测试一个新的image,不知道quality如何,如果测试用例非常多,测试人员就得一直等,也许前面的一些测试用都失败就可以停止执行了。那怎么实现实时显示呢?请看方法4。



C:\Users\yatyang\PycharmProjects\pytest_example>pytest slowTest_logging.py
============================= test session starts =============================
platform win32 – Python 2.7.13, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
metadata: {‘Python’: ‘2.7.13’, ‘Platform’: ‘Windows-7-6.1.7601-SP1’, ‘Packages’: {‘py’: ‘1.4.32’, ‘pytest’: ‘3.0.6’, ‘pluggy’: ‘0.4.0’}, ‘JAVA_HOME’: ‘C:\Program Files (x86)\Java\jd
k1.7.0_01’, ‘Plugins’: {‘html’: ‘1.14.2’, ‘metadata’: ‘1.3.0’}}
rootdir: C:\Users\yatyang\PycharmProjects\pytest_example, inifile:
plugins: metadata-1.3.0, html-1.14.2
collected 2 items

slowTest_logging.py .F

================================== FAILURES ===================================
___________________________________ test_2 ____________________________________

def test\_2():
    log = logging.getLogger('test\_2')
    time.sleep(1)
    log.debug('after 1 sec')
    time.sleep(1)
    log.debug('after 2 sec')
    time.sleep(1)
    log.debug('after 3 sec')
  assert 0, 'failing for demo purposes'

E AssertionError: failing for demo purposes
E assert 0

slowTest_logging.py:25: AssertionError
---------------------------- Captured stderr call -----------------------------
DEBUG:test_2:after 1 sec
DEBUG:test_2:after 2 sec
DEBUG:test_2:after 3 sec
===================== 1 failed, 1 passed in 6.37 seconds ======================



C:\Users\yatyang\PycharmProjects\pytest_example>pytest -s slowTest_logging.py
============================= test session starts =============================
platform win32 – Python 2.7.13, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
metadata: {‘Python’: ‘2.7.13’, ‘Platform’: ‘Windows-7-6.1.7601-SP1’, ‘Packages’: {‘py’: ‘1.4.32’, ‘pytest’: ‘3.0.6’, ‘pluggy’: ‘0.4.0’}, ‘JAVA_HOME’: ‘C:\Program Files (x86)\Java\jd
k1.7.0_01’, ‘Plugins’: {‘html’: ‘1.14.2’, ‘metadata’: ‘1.3.0’}}
rootdir: C:\Users\yatyang\PycharmProjects\pytest_example, inifile:
plugins: metadata-1.3.0, html-1.14.2
collected 2 items

slowTest_logging.py DEBUG:test_1:after 1 sec
DEBUG:test_1:after 2 sec
DEBUG:test_1:after 3 sec
.DEBUG:test_2:after 1 sec
DEBUG:test_2:after 2 sec
DEBUG:test_2:after 3 sec
F

================================== FAILURES ===================================
___________________________________ test_2 ____________________________________

def test\_2():
    log = logging.getLogger('test\_2')
    time.sleep(1)
    log.debug('after 1 sec')
    time.sleep(1)
    log.debug('after 2 sec')
    time.sleep(1)
    log.debug('after 3 sec')
  assert 0, 'failing for demo purposes'

E AssertionError: failing for demo purposes
E assert 0

slowTest_logging.py:25: AssertionError
===================== 1 failed, 1 passed in 6.18 seconds ======================


**4. pytest用logging和–capture=no实现实时输出log信息**  
 请自己去运行下面的程序吧,可以看到该程序是实时输出当前测试用例执行的情况。



C:\Users\yatyang\PycharmProjects\pytest_example>pytest -s slowTest_logging.py
============================= test session starts =============================
platform win32 – Python 2.7.13, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
metadata: {‘Python’: ‘2.7.13’, ‘Platform’: ‘Windows-7-6.1.7601-SP1’, ‘Packages’: {‘py’: ‘1.4.32’, ‘pytest’: ‘3.0.6’, ‘pluggy’: ‘0.4.0’}, ‘JAVA_HOME’: ‘C:\Program Files (x86)\Java\jd
k1.7.0_01’, ‘Plugins’: {‘html’: ‘1.14.2’, ‘metadata’: ‘1.3.0’}}
rootdir: C:\Users\yatyang\PycharmProjects\pytest_example, inifile:
plugins: metadata-1.3.0, html-1.14.2
collected 2 items

slowTest_logging.py DEBUG:test_1:after 1 sec
DEBUG:test_1:after 2 sec
DEBUG:test_1:after 3 sec
.DEBUG:test_2:after 1 sec
DEBUG:test_2:after 2 sec
DEBUG:test_2:after 3 sec
F

================================== FAILURES ===================================
___________________________________ test_2 ____________________________________

def test\_2():
    log = logging.getLogger('test\_2')
    time.sleep(1)
    log.debug('after 1 sec')
    time.sleep(1)
    log.debug('after 2 sec')
    time.sleep(1)
    log.debug('after 3 sec')
  assert 0, 'failing for demo purposes'

E AssertionError: failing for demo purposes
E assert 0

slowTest_logging.py:25: AssertionError
===================== 1 failed, 1 passed in 6.20 seconds ======================


**5.总结**  
 在写自动化测试用例时,添加有用的log信息是非常有必要的。比如在初期的调试过程,能够一旦运行有问题,就可以获取到精确的调试信息。后期在稳定的运行中,其他测试人员来运行也可以很容易上手,所以大家一定要重视测试用例的调试信息。  
 通过本文,应该知道如何用pytest,logging和–capture=no实现运行测试用例的实时输出所有的log信息。


### 3, 代码覆盖率-多用在单元测试中


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923174430415.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **一,上篇(---- pytest-cov)**  
 简介:  
 pytest-cov 是pytest的一个插件,其本质也是引用 python coverage 库 用来统计代码覆盖率。以下这篇文章只供理解,真实项目的话,我们都是用api调用接口的,所以真实项目使用会更复杂一些,这个待下次说明。


**另外说明:coverage 是在覆盖率是语句覆盖的一种,不能对你的逻辑做判读,真实意义的话,需要多结合项目本身,这个覆盖率数据没有很强大说服力,不要盲目追求。  
 一般来说:  
 路径覆盖率 > 判定覆盖 > 语句覆盖**


安装



pip install pytest-cover


安装完后有



py.test -h 可以看到多了以下的用法,说明安装成功:

coverage reporting with distributed testing support:


范例  
 新建三个文件,cau.py 与test\_conver.py 在同一个目录code下。run.py文件在上一级目录pp下。  
 代码关系如下。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923173228498.png)


1.新建函数文件cau.py



#!/usr/bin/env python

-*- coding: utf-8 -*-

def cau (type,n1, n2):

if type==1:
    a=n1 + n2
elif type==2:
    a = n1 - n2
else:
    a=n1 \* n2
return a

2.新建test\_conver.py测试文件:



#!/usr/bin/env python

-*- coding: utf-8 -*-

from code.cau import cau
class Test_cover:
def test_add(self):
a=cau(1,2,3)
assert a==3


3.新建执行脚本run.py



#!/usr/bin/env ```python

-*- coding: utf-8 -*-

import pytest

if name==‘__main__’:
pytest.main([“–cov=./code/” ,“–cov-report=html”,“–cov-config=./code/.coveragerc”] ) # 执行某个目录下case


说明:–cov参数 后面接的是测试的目录 (经给测试,不能指定某个特定的文件。),程序代码跟测试脚本必须在同一个文件下。 --cov-report=html 生成报告 ,只需要python run.py 就可以运行



coveragerc 意思是跳过某些脚本的覆盖率测试。此处跳过test_cover.py文件跟init文件。


内容如下:



[run]
omit =
tests/*
*/init.py
*/test_cover.py


结果  
 生成完后可以直接点击indexhtml  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923173435344.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 可以看到如下的执行情况,绿色代表运行,红色代表未被执行,自己检查下代码逻辑,可以得出该结果是正确的。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923173444582.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **二:下篇(— coverage.py api)**  
 使用pytest-cov 无法统计用 api调用服务的测试脚本所覆盖率,但大部分的项目基本也是使用api调用。所以我们额外需要使用coverage.py api 来统计。  
 当你安装pytest-cov时,已经默认安装了coverage 这个库。


服务启动  
 要想扫描到代码,必须在服务启动的时候要插入coverage相关配置。  
 我这边是flask 启动的,所以在flask启动的代码上添加,如下:



if name == ‘__main__’:
cov = Coverage()
cov.start() # 开始检测代码
print (“qidong”)
app.run(debug=True, host=‘0.0.0.0’,port=9098) #原本只有这一行
cov.stop() # 停止纪录
print (“guanbi”)
cov.save() # 保存在 .coverage 中
print (“save”)
cov.html_report() # 生成 HTML 报告


原本我们是python xx.py 这样启动,但现在不可以。  
 需要改成这样,source 表示目录,xx表示执行文件。



coverage run --source=‘/xxx/’ xx.py


启动运行图如下:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2019092317414216.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 然后调用你的自动化脚本(自动化脚本是直接调的该服务提供的api 。)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923174224869.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 自动化如果正常运行,能看到运行的请求


以上说明你的脚本跟服务是没问题的


ctr-c停掉该脚本后,最后显示save,如果显示”Coverage.py warning: No data was collected. (no-data-collected)“ 说明的服务运行方式有问题,coverage 服务没有运行到你代码


报告生成  
 输入以下命令



coverage report


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923174311748.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 最后一步最后输入



coverage html


这样就可以省 html 文件了。


导出在window上看,具体点击某个文件,点击run,你可以看到绿色的就是运行的。但有问题是,你会发现有些代码应该是要被执行,但却没有被执行。所以coverage的数据准不准很难说。


### 4,allure测试报告框架


**pytest+allure现在都是结合jenkins来搞的,很简单相信大家都会,不会的老哥可以去看我的另一个博客持续集成里的有写**


### 5,定制报告


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191204647.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191912690.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191940799.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923192311432.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923192402610.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 定制报告  
 Feature: 标注主要功能模块  
 Story: 标注Features功能模块下的分支功能  
 Severity: 标注测试用例的重要级别  
 Step: 标注测试用例的重要步骤  
 Issue和TestCase: 标注Issue、Case,可加入URL


**1、Features定制详解**



-*- coding: utf-8 -*-

@Time : 2018/8/17 上午10:10

@Author : WangJuan

@File : test_case.py

import allure
import pytest

@allure.feature(‘test_module_01’)
def test_case_01():
“”"
用例描述:Test case 01
“”"
assert 0

@allure.feature(‘test_module_02’)
def test_case_02():
“”"
用例描述:Test case 02
“”"
assert 0 == 0

if name == ‘__main__’:
pytest.main([‘-s’, ‘-q’, ‘–alluredir’, ‘./report/xml’])


添加feature,Report展示见下图。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191323305.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)


**2、Story定制详解**



-*- coding: utf-8 -*-

@Time : 2018/8/17 上午10:10

@Author : WangJuan

@File : test_case.py

import allure
import pytest

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_01’)
def test_case_01():
“”"
用例描述:Test case 01
“”"
assert 0

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_02’)
def test_case_02():
“”"
用例描述:Test case 02
“”"
assert 0 == 0

if name == ‘__main__’:
pytest.main([‘-s’, ‘-q’, ‘–alluredir’, ‘./report/xml’])


添加story,Report展示见下图。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191419838.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)


**3、用例标题和用例描述定制详解**



-*- coding: utf-8 -*-

@Time : 2018/8/17 上午10:10

@Author : WangJuan

@File : test_case.py

import allure
import pytest

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_01’)
#test_case_01为用例title
def test_case_01():
“”"
用例描述:这是用例描述,Test case 01,描述本人
“”"
#注释为用例描述
assert 0

if name == ‘__main__’:
pytest.main([‘-s’, ‘-q’, ‘–alluredir’, ‘./report/xml’])


添加用例标题和用例描述,Report展示见下图。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191453920.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)


**4 、Severity定制详解**  
 Allure中对严重级别的定义:  
 1、 Blocker级别:中断缺陷(客户端程序无响应,无法执行下一步操作)  
 2、 Critical级别:临界缺陷( 功能点缺失)  
 3、 Normal级别:普通缺陷(数值计算错误)  
 4、 Minor级别:次要缺陷(界面错误与UI需求不符)  
 5、 Trivial级别:轻微缺陷(必输项无提示,或者提示不规范)



-*- coding: utf-8 -*-

@Time : 2018/8/17 上午10:10

@Author : WangJuan

@File : test_case.py

import allure
import pytest

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_01’)
@allure.severity(‘blocker’)
def test_case_01():
“”"
用例描述:Test case 01
“”"
assert 0

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_01’)
@allure.severity(‘critical’)
def test_case_02():
“”"
用例描述:Test case 02
“”"
assert 0 == 0

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_02’)
@allure.severity(‘normal’)
def test_case_03():
“”"
用例描述:Test case 03
“”"
assert 0

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_02’)
@allure.severity(‘minor’)
def test_case_04():
“”"
用例描述:Test case 04
“”"
assert 0 == 0

if name == ‘__main__’:
pytest.main([‘-s’, ‘-q’, ‘–alluredir’, ‘./report/xml’])


添加Severity,Report展示见下图。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2019092319154716.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)


**5、Step定制详解**



-*- coding: utf-8 -*-

@Time : 2018/8/17 上午10:10

@Author : WangJuan

@File : test_case.py

import allure
import pytest

@allure.step(“字符串相加:{0},{1}”)

测试步骤,可通过format机制自动获取函数参数

def str_add(str1, str2):
if not isinstance(str1, str):
return “%s is not a string” % str1
if not isinstance(str2, str):
return “%s is not a string” % str2
return str1 + str2

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_01’)
@allure.severity(‘blocker’)
def test_case():
str1 = ‘hello’
str2 = ‘world’
assert str_add(str1, str2) == ‘helloworld’

if name == ‘__main__’:
pytest.main([‘-s’, ‘-q’, ‘–alluredir’, ‘./report/xml’])


添加Step,Report展示见下图。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191617431.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **6、Issue和TestCase定制详解**



-*- coding: utf-8 -*-

@Time : 2018/8/17 上午10:10

@Author : WangJuan

@File : test_case.py

import allure
import pytest

@allure.step(“字符串相加:{0},{1}”) # 测试步骤,可通过format机制自动获取函数参数
def str_add(str1, str2):
print(‘hello’)
if not isinstance(str1, str):
return “%s is not a string” % str1
if not isinstance(str2, str):
return “%s is not a string” % str2
return str1 + str2

@allure.feature(‘test_module_01’)
@allure.story(‘test_story_01’)
@allure.severity(‘blocker’)
@allure.issue(“http://www.baidu.com”)
@allure.testcase(“http://www.testlink.com”)
def test_case():
str1 = ‘hello’
str2 = ‘world’
assert str_add(str1, str2) == ‘helloworld’

if name == ‘__main__’:
pytest.main([‘-s’, ‘-q’, ‘–alluredir’, ‘./report/xml’])


添加Issue和TestCase,Report展示见下图。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191644813.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 8、attach定制详解



file = open(‘…/test.png’, ‘rb’).read()
allure.attach(‘test_img’, file, allure.attach_type.PNG)


在报告中增加附件:allure.attach(’arg1’,’arg2’,’arg3’):  
 arg1:是在报告中显示的附件名称  
 arg2:表示添加附件的内容  
 arg3:表示添加的类型(支持:HTML,JPG,PNG,JSON,OTHER,TEXTXML)


添加attach参数,Report展示见下图。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923191756828.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)


### 6,pytest运行指定用例


随着软件功能的增加,模块越来越多,也意味用例越来越多,为了节约执行时间,快速得到测试报告与结果,在工作中可以通过运行指定用例,达到快速执行用例


例子目录  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190923192854292.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNjEwMTY3,size_16,color_FFFFFF,t_70)  
 **spec\_sub1\_modul\_test.py**



#coding: UTF-8
import pytest

def test_004_spec():
assert 11
def test_005_spec():
assert True
False

class Test_Class():
def test_006_spec(self):
assert ‘G’ in “Goods”


**spec\_sub2\_modul\_test.py**


![img](https://img-blog.csdnimg.cn/img_convert/537782e92f9681800b50a30b72fd1430.png)
![img](https://img-blog.csdnimg.cn/img_convert/d47e5df1498875011fb1ae816ce3cd6e.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

.read()
 allure.attach('test\_img', file, allure.attach_type.PNG)

在报告中增加附件:allure.attach(’arg1’,’arg2’,’arg3’):
arg1:是在报告中显示的附件名称
arg2:表示添加附件的内容
arg3:表示添加的类型(支持:HTML,JPG,PNG,JSON,OTHER,TEXTXML)

添加attach参数,Report展示见下图。
在这里插入图片描述

6,pytest运行指定用例

随着软件功能的增加,模块越来越多,也意味用例越来越多,为了节约执行时间,快速得到测试报告与结果,在工作中可以通过运行指定用例,达到快速执行用例

例子目录
在这里插入图片描述
spec_sub1_modul_test.py

#coding: UTF-8
import pytest

def test\_004\_spec():
    assert 1==1
def test\_005\_spec():
    assert True==False
    
class Test\_Class():
    def test\_006\_spec(self):
        assert 'G' in "Goods"

spec_sub2_modul_test.py

[外链图片转存中…(img-xgNJcQkd-1715661457630)]
[外链图片转存中…(img-vmUw8egO-1715661457630)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值