前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Pytest参数选项自由执行测试用例详解(二)

Pytest参数选项自由执行测试用例详解(二)

作者头像
王大力测试进阶之路
发布于 2021-07-28 08:10:08
发布于 2021-07-28 08:10:08
1.3K00
代码可运行
举报
文章被收录于专栏:橙子探索测试橙子探索测试
运行总次数:0
代码可运行

运行pytest可以指定目录和文件,如果不指定,pytest会搜索当前目录及其子目录中以test_开头或以_test结尾得测试函数。我们把pytest搜索测试文件和测试用例的过程称为测试搜索(test discovery)。只要遵循pytest的命名规则,pytest就能自动搜索所有待执行的测试用例。所有的包必须要有init.py文件(在使用各种编辑器时会自动生成)

1、测试文件命名规则,test_xxx.py或xxx_test.py

2、方法、测试函数命名规则,test_xxx

3、测试类命名规则,Testxxx,并且不能带有 init 方法

Pytest参数选项在脚本中和命令行用法详解(一)

-k选项 -K EXPRESSION

使用表达式指定某个关键字的测试用例,如果某测试名是唯一的或多个测试名的前缀或后缀相同,可快速匹配,匹配范围是全局相同目录或下层目录所有(包名、文件名、类名、函数名为变量),文件名、类名、函数名,必须是test_开头或_test结尾的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-k','关键字'])
关键字包含于或等于文件名、类名、函数名,多个关键字之间用and、or、not连接

测试代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
chengzi\test_04.py

import pytest


class TestClass(object):
    def test_one(self):
        assert 2 == 1


    def test_two(self):
        assert 2 == 2

    def test_two2(self):
        assert 2 == 2

执行匹配包名,运行了3条用例

pytest.main(['-v','-k','chengzi'])

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if __name__ == '__main__':
    pytest.main(['-v','-k','chengzi'])
    
 "C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/chengzi/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- C:\Program Files\Python35\python.exe
cachedir: .pytest_cache
metadata: {'Packages': {'pluggy': '0.13.1', 'py': '1.9.0', 'pytest': '6.1.1'}, 'Platform': 'Windows-10-10.0.18362-SP0', 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_101', 'Python': '3.5.2', 'Plugins': {'allure-pytest': '2.8.18', 'metadata': '1.8.0', 'rerunfailures': '9.1.1', 'html': '1.22.0'}}
rootdir: C:\Users\wangli\PycharmProjects\untitled\chengzi
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
collecting ... collected 3 items

test_04.py::TestClass::test_one FAILED                                   [ 33%]
test_04.py::TestClass::test_two PASSED                                   [ 66%]
test_04.py::TestClass::test_two2 PASSED                                  [100%]

================================== FAILURES ===================================
_____________________________ TestClass.test_one ______________________________

self = <chengzi.test_04.TestClass object at 0x000001F27E537B70>

    def test_one(self):
>       assert 2 == 1
E       assert 2 == 1
E         +2
E         -1

test_04.py:5: AssertionError
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_one - assert 2 == 1
========================= 1 failed, 2 passed in 0.63s =========================

Process finished with exit code 0

执行匹配文件名,运行了3条用例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-v','-k','test_04.py'])
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if __name__ == '__main__':
    pytest.main(['-v','-k','test_04.py'])
    
"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/chengzi/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- C:\Program Files\Python35\python.exe
cachedir: .pytest_cache
metadata: {'Platform': 'Windows-10-10.0.18362-SP0', 'Python': '3.5.2', 'Packages': {'py': '1.9.0', 'pluggy': '0.13.1', 'pytest': '6.1.1'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_101', 'Plugins': {'rerunfailures': '9.1.1', 'html': '1.22.0', 'allure-pytest': '2.8.18', 'metadata': '1.8.0'}}
rootdir: C:\Users\wangli\PycharmProjects\untitled\chengzi
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
collecting ... collected 3 items

test_04.py::TestClass::test_one FAILED                                   [ 33%]
test_04.py::TestClass::test_two PASSED                                   [ 66%]
test_04.py::TestClass::test_two2 PASSED                                  [100%]

================================== FAILURES ===================================
_____________________________ TestClass.test_one ______________________________

self = <chengzi.test_04.TestClass object at 0x000002031D345588>

    def test_one(self):
>       assert 2 == 1
E       assert 2 == 1
E         +2
E         -1

test_04.py:6: AssertionError
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_one - assert 2 == 1
========================= 1 failed, 2 passed in 0.48s =========================

Process finished with exit code 0

执行匹配类名,运行了3条用例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-v','-k','Class'])
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

if __name__ == '__main__':
    pytest.main(['-v','-k','Class'])

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/chengzi/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- C:\Program Files\Python35\python.exe
cachedir: .pytest_cache
metadata: {'Plugins': {'html': '1.22.0', 'rerunfailures': '9.1.1', 'metadata': '1.8.0', 'allure-pytest': '2.8.18'}, 'Packages': {'pluggy': '0.13.1', 'py': '1.9.0', 'pytest': '6.1.1'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_101', 'Python': '3.5.2', 'Platform': 'Windows-10-10.0.18362-SP0'}
rootdir: C:\Users\wangli\PycharmProjects\untitled\chengzi
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
collecting ... collected 3 items

test_04.py::TestClass::test_one FAILED                                   [ 33%]
test_04.py::TestClass::test_two PASSED                                   [ 66%]
test_04.py::TestClass::test_two2 PASSED                                  [100%]

================================== FAILURES ===================================
_____________________________ TestClass.test_one ______________________________

self = <chengzi.test_04.TestClass object at 0x0000023ED5C68B00>

    def test_one(self):
>       assert 2 == 1
E       assert 2 == 1
E         +2
E         -1

test_04.py:6: AssertionError
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_one - assert 2 == 1
========================= 1 failed, 2 passed in 0.21s =========================

Process finished with exit code 0

执行匹配函数名,函数名中含test且含two的,运行了2条用例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-v','-k','test and two'])
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if __name__ == '__main__':
    pytest.main(['-v','-k','test and two'])

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/chengzi/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- C:\Program Files\Python35\python.exe
cachedir: .pytest_cache
metadata: {'Platform': 'Windows-10-10.0.18362-SP0', 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_101', 'Plugins': {'rerunfailures': '9.1.1', 'html': '1.22.0', 'allure-pytest': '2.8.18', 'metadata': '1.8.0'}, 'Packages': {'pluggy': '0.13.1', 'py': '1.9.0', 'pytest': '6.1.1'}, 'Python': '3.5.2'}
rootdir: C:\Users\wangli\PycharmProjects\untitled\chengzi
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
collecting ... collected 3 items / 1 deselected / 2 selected

test_04.py::TestClass::test_two PASSED                                   [ 50%]
test_04.py::TestClass::test_two2 PASSED                                  [100%]

======================= 2 passed, 1 deselected in 0.11s =======================

Process finished with exit code 0

-m选项 -m MARKEXPR

标记(marker)用于标记测试并分组,以便快速选中并运行,匹配运行所有标记了装饰器@pytest.mark.marker的类或方法的测试用例,标记名可自行定义,如果标记名为run_all,可使用@pytest.mark.run_all装饰类或函数来做标记,匹配范围是全局相同目录或下层目录所有(类装饰器的标记名、函数装饰器的标记名),文件名、类名、函数名,必须是test_开头或_test结尾的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-v','-m','关键字'])
关键字等于类装饰器或函装饰器@pytest.mark.标记名,里的标记名,多个关键字之间用and、or、not连接

测试代码目录:

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
chengzi\test_01.py
import pytest


class Test_Class(object):
    def test_one(self):
        assert 2 == 1

    @pytest.mark.run_two
    def testtwo(self):
        assert 2 == 2

    def test_two2(self):
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['-v','-m','run_one or run_all'])
    
juzi\test_02.py
@pytest.mark.run_all
class TestClass(object):
    def test_one(self):
        assert 2 == 1


    def test_two(self):
        assert 2 == 2


    def test_two2(self):
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['-v','-m','run_one or run_all'])
 
 import pytest

test_03.py
class TestClass(object):
    @pytest.mark.run_one
    def test_one(self):
        assert 2 == 1

    def test_two(self):
        assert 2 == 2


    def test_two2(self):
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['-v','-m','run_one or run_all'])
    
test_04.py    
class TestClass(object):
    def test_onqq(self):
        assert 2 == 1


    def test_two(self):
        assert 2 == 2

    @pytest.mark.two2
    def test_two2(self):
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['-v','-m','run_one or run_all'])  

执行匹配类或函数装饰器里,标记名为run_one或run_all的测试用例,可以看到匹配运行了4条用例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-v','-m','run_one or run_all'])
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if __name__ == '__main__':
    pytest.main(['-v','-m','run_one or run_all'])
    
"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- C:\Program Files\Python35\python.exe
cachedir: .pytest_cache
metadata: {'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_101', 'Platform': 'Windows-10-10.0.18362-SP0', 'Python': '3.5.2', 'Plugins': {'allure-pytest': '2.8.18', 'html': '1.22.0', 'metadata': '1.8.0', 'rerunfailures': '9.1.1'}, 'Packages': {'pytest': '6.1.1', 'pluggy': '0.13.1', 'py': '1.9.0'}}
rootdir: C:\Users\wangli\PycharmProjects\untitled
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
collecting ... collected 12 items / 8 deselected / 4 selected

test_03.py::TestClass::test_one FAILED                                   [ 25%]
juzi/test_02.py::TestClass::test_one FAILED                              [ 50%]
juzi/test_02.py::TestClass::test_two PASSED                              [ 75%]
juzi/test_02.py::TestClass::test_two2 PASSED                             [100%]

================================== FAILURES ===================================
_____________________________ TestClass.test_one ______________________________

self = <test_03.TestClass object at 0x00000232EDB1BF60>

    @pytest.mark.run_one
    def test_one(self):
>       assert 2 == 1
E       assert 2 == 1
E         +2
E         -1

test_03.py:7: AssertionError
_____________________________ TestClass.test_one ______________________________

self = <juzi.test_02.TestClass object at 0x00000232EDB0B080>

    def test_one(self):
>       assert 2 == 1
E       assert 2 == 1
E         +2
E         -1

juzi\test_02.py:6: AssertionError
============================== warnings summary ===============================
test_03.py:5
  C:\Users\wangli\PycharmProjects\untitled\test_03.py:5: PytestUnknownMarkWarning: Unknown pytest.mark.run_one - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
    @pytest.mark.run_one

test_04.py:12
  C:\Users\wangli\PycharmProjects\untitled\test_04.py:12: PytestUnknownMarkWarning: Unknown pytest.mark.two2 - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
    @pytest.mark.two2

chengzi\test_01.py:8
  C:\Users\wangli\PycharmProjects\untitled\chengzi\test_01.py:8: PytestUnknownMarkWarning: Unknown pytest.mark.run_two - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
    @pytest.mark.run_two

juzi\test_02.py:3
  C:\Users\wangli\PycharmProjects\untitled\juzi\test_02.py:3: PytestUnknownMarkWarning: Unknown pytest.mark.run_all - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
    @pytest.mark.run_all

-- Docs: https://docs.pytest.org/en/stable/warnings.html
=========================== short test summary info ===========================
FAILED test_03.py::TestClass::test_one - assert 2 == 1
FAILED juzi/test_02.py::TestClass::test_one - assert 2 == 1
============ 2 failed, 2 passed, 8 deselected, 4 warnings in 0.24s ============

Process finished with exit code 0

-V(--verbose)选项

输出更加详细的信息,比如用例所在的包、py文件、类名及用例名称等测试的名字和结果都会显示出来,最明显区别就是每个文件中的测试用例都会占一行(先前是每个文件占一行)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-v'])

-s选项

允许终端在测试运行时,输出用例中的调式信息,包括任何符合标准的输出流信息,比如print的打印信息等。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-s'])

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
test-04.py
import pytest


class TestClass(object):
    def test_one(self):
        print('this is test_one')
        assert 2 == 1

    def test_two(self):
        print('this is test_two')
        assert 2 == 2

    @pytest.mark.two2
    def test_two2(self):
        print('this is test_two2')
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['-s'])
    
"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1
rootdir: C:\Users\wangli\PycharmProjects\untitled
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
111
collected 12 items

test_03.py F..
test_04.py this is test_one
Fthis is test_two
.this is test_two2
.
chengzi\test_01.py F..
juzi\test_02.py F..

-x选项

debug调试时,我们希望遇到断言失败时,立即全局停止,这时就可以用到-x

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-x','test_04.py'])

测试代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#设置用例1和用例3断言成功,断言2失败
#执行后,用例1执行了,用例2执行断言失败,脚本停止,用例3没有继续执行
import pytest

class TestClass(object):
    def test_one(self):
        print('this is test_one')
        assert 2 == 2

    def test_two(self):
        print('this is test_two')
        assert 2 == 1

    def test_two2(self):
        print('this is test_two2')
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['-x','test_04.py'])

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1
rootdir: C:\Users\wangli\PycharmProjects\untitled
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
collected 3 items

test_04.py .F

================================== FAILURES ===================================
_____________________________ TestClass.test_two ______________________________

self = <test_04.TestClass object at 0x000001465DA2D780>

    def test_two(self):
        print('this is test_two')
>       assert 2 == 1
E       assert 2 == 1

test_04.py:11: AssertionError
---------------------------- Captured stdout call -----------------------------
this is test_two
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two - assert 2 == 1
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!
========================= 1 failed, 1 passed in 0.88s =========================

Process finished with exit code 0

--maxfail=num

与-x选项类似,测试用例达到指定失败次数,就会全局停止,不在执行,假设允许pytest失败2次后停止,则可以使用--maxfail=2,明确指定可失败次数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['--maxfail=2','test_04.py'])

测试代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#设置用例1和用例2断言失败,用例3断言成功
#使用pytest.main(['--maxfail=2','test_04.py'])
#执行了用例1和用例2,达到2次失败,全局停止,未执行用例3
test_04.py
import pytest


class TestClass(object):
    def test_one(self):
        print('this is test_one')
        assert 2 == 1

    def test_two(self):
        print('this is test_two')
        assert 2 == 1

    @pytest.mark.two2
    def test_two2(self):
        print('this is test_two2')
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['--maxfail=2','test_04.py'])
    
"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/untitled/test_04.py
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-6.1.1, py-1.9.0, pluggy-0.13.1
rootdir: C:\Users\wangli\PycharmProjects\untitled
plugins: allure-pytest-2.8.18, html-1.22.0, metadata-1.8.0, rerunfailures-9.1.1
collected 3 items

test_04.py FF

================================== FAILURES ===================================
_____________________________ TestClass.test_one ______________________________

self = <test_04.TestClass object at 0x000001ACC521D5F8>

    def test_one(self):
        print('this is test_one')
>       assert 2 == 1
E       assert 2 == 1

test_04.py:7: AssertionError
---------------------------- Captured stdout call -----------------------------
this is test_one
_____________________________ TestClass.test_two ______________________________

self = <test_04.TestClass object at 0x000001ACC521A668>

    def test_two(self):
        print('this is test_two')
>       assert 2 == 1
E       assert 2 == 1

test_04.py:11: AssertionError
---------------------------- Captured stdout call -----------------------------
this is test_two
============================== warnings summary ===============================
test_04.py:13
  C:\Users\wangli\PycharmProjects\untitled\test_04.py:13: PytestUnknownMarkWarning: Unknown pytest.mark.two2 - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
    @pytest.mark.two2

-- Docs: https://docs.pytest.org/en/stable/warnings.html
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_one - assert 2 == 1
FAILED test_04.py::TestClass::test_two - assert 2 == 1
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 2 failures !!!!!!!!!!!!!!!!!!!!!!!!!!
======================== 2 failed, 1 warning in 0.17s =========================

Process finished with exit code 0

--lf(--last-failed)选项

执行上次断言失败的用例A,当用例A一直是断言失败,运行脚本一直只执行用例A;当用例A断言成功后,没有失败的用例了,会执行全部用例,如果又有断言失败的用例,下次会执行运行失败的用例(运行脚本会执行上次断言失败的用例,没有失败用例会执行所有用例)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['--lf','test_04.py'])
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#设置test_two用例断言失败,运行j脚本后只跑了test_two用例
import pytest
class TestClass(object):
    def test_one(self):
        print('this is test_one')
        assert 2 == 2

    def test_two(self):
        print('this is test_two')
        assert 2 == 1

    def test_two2(self):
        print('this is test_two2')
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['--lf','test_04.py'])
    
collected 3 items / 2 deselected / 1 selected
run-last-failure: rerun previous 1 failure

test_04.py F                                                             [100%]

================================== FAILURES ===================================
_____________________________ TestClass.test_two ______________________________

self = <test_04.TestClass object at 0x0000028C5FB3A198>

    def test_two(self):
        print('this is test_two')
>       assert 2 == 1
E       assert 2 == 1

test_04.py:11: AssertionError
---------------------------- Captured stdout call -----------------------------
this is test_two
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two - assert 2 == 1
======================= 1 failed, 2 deselected in 0.15s =======================

Process finished with exit code 0

#把用例test_two改成断言正确的,再次运行脚本,仍执行了test_two用例,发现test_two
# 用例断言成功了
import pytest
class TestClass(object):
    def test_one(self):
        print('this is test_one')
        assert 2 == 2

    def test_two(self):
        print('this is test_two')
        assert 2 == 2

    def test_two2(self):
        print('this is test_two2')
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['--lf','test_04.py'])
    
collected 3 items / 2 deselected / 1 selected
run-last-failure: rerun previous 1 failure

test_04.py .                                                             [100%]

======================= 1 passed, 2 deselected in 0.09s =======================

Process finished with exit code 0

#再次运行脚本,执行了全部用例
import pytest
class TestClass(object):
    def test_one(self):
        print('this is test_one')
        assert 2 == 2

    def test_two(self):
        print('this is test_two')
        assert 2 == 2

    def test_two2(self):
        print('this is test_two2')
        assert 2 == 2


if __name__ == '__main__':
    pytest.main(['--lf','test_04.py'])
    
collected 3 items
run-last-failure: 13 known failures not in selected tests

test_04.py ...                                                           [100%]

============================== 3 passed in 0.05s ==============================

Process finished with exit code 0

--ff(--failed-first)选项

--ff选项,运行脚本,会优先执行上次断言失败的用例,再依次执行其他用例,直至运行脚本,上次断言失败的用例这次变为断言成功,下次再运行脚本,才会按正常用例顺序依次执行,与--lf选项作用基本相同,不同之处--ff会运行剩下 的测试用例。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['-s','--ff','test_04.py'])
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 设置test_two2断言失败,首次运行脚本,未优先执行test_two2,
# 结果test_two2断言失败
import pytest
class TestClass(object):
    def test_one(self):
        print('this is test_one')
        assert 2 == 2

    def test_two(self):
        print('this is test_two')
        assert 2 == 2

    def test_two2(self):
        print('this is test_two2')
        assert 2 == 1


if __name__ == '__main__':
    pytest.main(['-s','--ff','test_04.py'])
    
collected 3 items
run-last-failure: 13 known failures not in selected tests

test_04.py this is test_one
.this is test_two
.this is test_two2
F

================================== FAILURES ===================================
_____________________________ TestClass.test_two2 _____________________________

self = <test_04.TestClass object at 0x000001A124621CF8>

    def test_two2(self):
        print('this is test_two2')
>       assert 2 == 1
E       assert 2 == 1

test_04.py:15: AssertionError
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two2 - assert 2 == 1
========================= 1 failed, 2 passed in 0.17s =========================

Process finished with exit code 0

# 脚本不变,再次运行一次,发现优先执行了上次断言失败的用例test_two2
# 再按顺序依次执行,结果test_two2断言失败
collected 3 items
run-last-failure: rerun previous 1 failure first

test_04.py this is test_two2
Fthis is test_one
.this is test_two
.

================================== FAILURES ===================================
_____________________________ TestClass.test_two2 _____________________________

self = <test_04.TestClass object at 0x000002C5D0F03668>

    def test_two2(self):
        print('this is test_two2')
>       assert 2 == 1
E       assert 2 == 1

test_04.py:15: AssertionError
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two2 - assert 2 == 1
========================= 1 failed, 2 passed in 0.10s =========================

Process finished with exit code 0

# test_two2用例改成断言成功,再次执行脚本,发现还是优先执行了上次断言失败的用例test_two2
# 用例,再按顺序依次执行,结果test_two2断言成功
    def test_two2(self):
        print('this is test_two2')
        assert 2 == 2
        
collected 3 items
run-last-failure: rerun previous 1 failure first

test_04.py this is test_two2
.this is test_one
.this is test_two
.

============================== 3 passed in 0.07s ==============================

Process finished with exit code 0

# 脚本不变,再运行依次脚本,发现未优先执行test_two2用例,因为上次结果
# 没有断言失败的,所有不会优先执行,正常依次执行

collected 3 items
run-last-failure: 13 known failures not in selected tests

test_04.py this is test_one
.this is test_two
.this is test_two2
.

============================== 3 passed in 0.03s ==============================

Process finished with exit code 0

--tb=style选项

捕捉到失败时输出信息的显示方式,某个测试用例失败后,pytest会列举出失败信息,包括失败在哪一行、是什么失败、怎么失败的,此过程称“信息回溯”它对找到问题很有帮助,但有时也会对多余的信息感到厌烦,这时--tb=style选项就有用武之地了,style类型有short、line、no。short模式仅输出assert的一行以及系统判定内容(不显示上下文);line模式只使用一行输出显示所有的错误信息;no模式则直接屏蔽全部回溯信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['--tb=no','test_04.py']),屏蔽全部回溯信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
collected 3 items

test_04.py ..F                                                           [100%]

=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two2 - assert 2 == 1
========================= 1 failed, 2 passed in 0.09s =========================
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['--tb=line','test_04.py']),告诉我们错误的位置
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
collected 3 items

test_04.py ..F                                                           [100%]

================================== FAILURES ===================================
C:\Users\wangli\PycharmProjects\untitled\test_04.py:15: assert 2 == 1
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two2 - assert 2 == 1
========================= 1 failed, 2 passed in 0.19s =========================

Process finished with exit code 0
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['--tb=short','test_04.py']),显示回溯信息比前面两种都详细
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
collected 3 items

test_04.py ..F                                                           [100%]

================================== FAILURES ===================================
_____________________________ TestClass.test_two2 _____________________________
test_04.py:15: in test_two2
    assert 2 == 1
E   assert 2 == 1
---------------------------- Captured stdout call -----------------------------
this is test_two2
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two2 - assert 2 == 1
========================= 1 failed, 2 passed in 0.42s =========================

Process finished with exit code 0
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pytest.main(['--tb=long','test_04.py'])输出最详细的回溯信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
collected 3 items

test_04.py ..F                                                           [100%]

================================== FAILURES ===================================
_____________________________ TestClass.test_two2 _____________________________

self = <test_04.TestClass object at 0x00000229D5D7E8D0>

    def test_two2(self):
        print('this is test_two2')
>       assert 2 == 1
E       assert 2 == 1

test_04.py:15: AssertionError
---------------------------- Captured stdout call -----------------------------
this is test_two2
=========================== short test summary info ===========================
FAILED test_04.py::TestClass::test_two2 - assert 2 == 1
========================= 1 failed, 2 passed in 0.18s =========================

Process finished with exit code 0
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 橙子探索测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Pytest跳过执行之@pytest.mark.skip()详解
在我们自动化测试过程中,经常会遇到功能阻塞、功能未实现、环境等一系列外部因素问题导致的一些用例执行不了,这时我们就可以用到跳过skip用例,如果我们注释掉或删除掉,后面还要进行恢复操作。
王大力测试进阶之路
2019/12/15
6.6K1
Pytest Hooks方法之pytest_runtest_makereport获取测试用例结果
pytest提供的钩子(Hooks)方法之pytest_runtest_makereport,可以更清晰的了解用例的执行过程,并获取到每个用例的执行结果。
王大力测试进阶之路
2020/05/20
2.6K0
Python Pytest中fixture之yield唤醒teardown和终结函数addfinalizer
引入 我们之前学习的都是测试用例的前置固件,也就是相当于“setup”。说到这,细心的你可能想到了,那有没有什么方式可以表示出“teardown”?这就是我们今天学习的yield和addfinalizer。
王大力测试进阶之路
2019/10/25
1.3K0
Pytest自定义标记mark及指定文件/类/方法/用例执行
pytest.main(['-s','test01.py','-m=test'])
王大力测试进阶之路
2019/12/15
1.9K0
Pytest Hooks方法之pytest_collection_modifyitems改变测试用例执行顺序
pytest默认执行用例顺序是根据项目下文件名称按ascii码去收集运行的,文件里的用例是从上往下按顺序执行的.
王大力测试进阶之路
2020/05/25
2.2K0
Python Pytest前置setup和后置teardown详解
pytest用例运行级别: ●模块级(setup_module/teardown_module)开始于模块始末,全局的(类外生效、函数中生效) ●函数级(setup_function/teardown_function)只对函数用例生效(类外有函数时生效) ●类级(setup_class/teardown_class)只在类中前后运行一次(在类中生效,类外不生效) ●方法级(setup_method/teardown_method)开始于方法始末(在类中生效,类外不生效) ●类里面的(setup/teardown)运行在调用方法的前后(类中生效、类外有函数时生效)
王大力测试进阶之路
2019/10/25
1.6K0
Python Pytest装饰器@pytest.mark.parametrize详解
Pytest中装饰器@pytest.mark.parametrize('参数名',list)可以实现测试用例参数化,类似DDT 如:@pytest.mark.parametrize('请求方式,接口地址,传参,预期结果',[('get','www.baidu.com','{"page":1}','{"code":0,"msg":"成功"})',('post','www.baidu.com','{"page":2}','{"code":0,"msg":"成功"}')])
王大力测试进阶之路
2019/10/25
8.2K0
Pytest脚本中用例运行方式
脚本树如下: test1文件下test_01.py存放test1和test2用例 test1文件下test_02.py存放test1和test2用例 test2文件下test_03.py存放test1
王大力测试进阶之路
2019/11/09
1.1K0
iOS自动化探索(四)自动化测试框架pytest - 安装和使用
pytest是Python最流行的单元测试框架之一, 帮助更便捷的编写测试脚本, 并支持多种功能复杂的测试场景, 能用来做app测试也能用作函数测试
周希
2019/10/15
1.4K0
Pytest fixture之request传参
Pytest中我们经常会用到数据参数化,我们来介绍下装饰器@pytest.fixture()配合request传参的使用
王大力测试进阶之路
2019/11/28
8820
Pytest之@pytest.mark.usefixtures()、叠加usefixtures、(autouse=True)详解
如果fixture有返回值,那么usefixture就无法获取到返回值,这个是装饰器usefixture与用例直接传fixture参数的区别。
王大力测试进阶之路
2019/10/25
2.4K0
Python pytest框架之@pytest.fixture()和conftest详解
一、fixture简介 学pytest就不得不说fixture,fixture是pytest的精髓所在,类似unittest中setup/teardown这种前后置东西。但是比它们要强大、灵活很多,它的优势是可以跨文件共享 fixture的目的是提供一个固定基线,在该基线上测试可以可靠地和重复地执行。fixture提供了区别于传统单元测试(setup/teardown)有显著改进 1、有独立的命名,并通过声明它们从测试函数、模块、类或整个项目中的使用来激活。 2、按模块化的方式实现,每个fixture都可以互相调用。 3、fixture的范围从简单的单元扩展到复杂的功能测试,允许根据配置和组件选项对fixture和测试用例进行参数化,或者跨函数function、类class、模块module或整个测试会话sessio范围。
王大力测试进阶之路
2019/10/25
5.9K0
python pytest测试框架
2.2使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例
狼啸风云
2020/02/11
1.6K0
Pytest和Allure测试框架-超详细版+实战
:1. 简单灵活,容易上手;支持参数化; 测试用例的skip和xfail 处理; 2. 能够支持简单的单元测试和复杂的功能测试,还可以用来做 selenium/appium等自动化测试、接口自动化测试 (pytest+requests); 3. pytest具有很多第三方插件,并且可以自定义扩展, 比较好 用的如 pytest-allure(完美html测试报告生成) pytest-xdist (多CPU分发)等; 4. 可以很好的和jenkins集成;** 5. **
全栈程序员站长
2022/09/17
2.4K0
Pytest和Allure测试框架-超详细版+实战
pytest文档4-测试用例setup和teardown
学过unittest的都知道里面用前置和后置setup和teardown非常好用,在每次用例开始前和结束后都去执行一次。 当然还有更高级一点的setupClass和teardownClass,需配合@classmethod装饰器一起使用,在做selenium自动化的时候,它的效率尤为突然,可以只启动一次浏览器执行多个用例。 pytest框架也有类似于setup和teardown的语法,并且还不止这四个
上海-悠悠
2018/08/03
1.1K0
pytest文档2-用例运行规则
1.查看pytest命令行参数,可以用pytest -h 或pytest —help查看
上海-悠悠
2018/08/03
1.1K0
Pytest配置文件pytest.ini
pytest.ini文件是pytest的主配置文件,可以改变pytest的运行方式,它是一个固定的文件pytest.ini文件,读取配置信息,按指定的方式去运行。pytest.ini的位置:一般放在项目工程的根目录(即当前项目的顶级文件夹下)
王大力测试进阶之路
2020/09/15
2.1K0
Pytest配置文件pytest.ini
Pytest标记用例失败之xfail
项目自动化测试中,如果接口2依赖接口1的响应结果值,或者用例2依赖用例1的响应结果值,自然需要与接口1或用例1进行关联,但是当接口1或用例1执行失败,接口2或用例2一定也是失败的,所以这时不必要再进行接口2和用例2的执行,只需要判断当接口1或用例1执行失败,直接标记接口2或用例2失败xfail
王大力测试进阶之路
2019/12/15
5680
软件测试|教你用skip灵活跳过用例
日常工作中,我们难免会遇到本次执行不需要所有用例都跑一遍的情况,或者说,我们就是希望某些用例不执行,来看看报错。
霍格沃兹测试开发Muller老师
2023/02/10
5170
Pytest之pytest-assume同用例多断言,断言1失败会执行后续代码及断言2
一般我们做自动化测试时,一个用例会写多个断言,当第一个断言失败后,后面的代码就不会执行了,于是我们引进了pytest-assume插件可以解决断言失败后继续断言的问题。
王大力测试进阶之路
2020/05/29
3.3K0
推荐阅读
相关推荐
Pytest跳过执行之@pytest.mark.skip()详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档