Pytest03-pytest命令行参数

3.pytest命令行参数

3.1 pytest控制台信息详解

    通常在运行pytest之后,会出现如下所示的控制台信息:

C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson01>pytest test_01.py
==================test session starts =======================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson01
collected 2 items

test_01.py .F                                    [100%]

===================FAILURES =================================
__________________ test_add_02 ______________________________

    def test_add_02():
>       assert Add(3,4)==6
E       assert 7 == 6
E        +  where 7 = Add(3, 4)

test_01.py:12: AssertionError
================ short test summary info ====================
FAILED test_01.py::test_add_02 - assert 7 == 6
=============== 1 failed, 1 passed in 0.56s ==================
  • ===== test session starts =====

测试会话分隔符,代表启动了一个新的调用

  • platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1

当前运行的平台,Python、pytest、pytest包的版本等信息

  • rootdir

当前起始目录,pytest搜索测试代码时使用的目录

  • collected 2 items

在搜索的目录中找到的测试函数个数

  • test_01.py .F

test_01.py代表测试文件

  • FAILED

未通过的测试函数的失败原因

  • 1 failed, 1 passed in 0.14s

统计测试函数通过和未通过的数量及运行时间

3.2 Pytest运行结果类型

    在Pytest中,测试函数可能会返回多种结果,不像传统的单元测试框架,仅显示通过和失败。以下是可能返回的结果:

  • PASSED(.)

测试通过。预期成功,实际成功

  • F(FAILED)

表示测试未通过,也可能是XPASS状态与strict选项造成的冲突。预期成功,实际失败

  • SKIPPED(s)

测试函数未执行,即该运行测试时跳过该测试函数,常用测试标记@pytest.mark.skip()@pytest.mark.skipif()指定跳过测试的条件

  • xfail(x)

期望测试失败,而且确实失败。常用测试标记@pytest.mark.xfail()来指定认为会失败的测试函数。预期失败,实际失败

  • XPASS(X)

期望测试失败,但实际结果却是运行通过,即不符合预期。预期失败,实际成功

  • ERROR(E)

运行测试函数时,出现异常或错误,可能由fixture引起

3.3 Pytest命令行参数

    很多时候,运行单元测试框架并不需要界面,更多的时候采用命令行的形式执行,pytest也提供很多的命令行参数,获取命令行参数帮助如下所示:

pytest --help


usage: pytest [options] [file_or_dir] [file_or_dir] [...]

positional arguments:
  file_or_dir
general:
 -x, --exitfirst       exit instantly on first error or failed test.

    下面来学习一些常用的命令行参数

3.3.1 --collect-only

    该参数仅收集测试函数,但并不执行运行操作。如下所示:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest --collect-only
============================= test session starts ================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 3 items
<Module test_01.py>
  <Function test_add_01>
  <Function test_add_02>
<Module test_02.py>
  <Function test_requestBaidu>

3.3.2 -k Expression

    -k选项允许使用表达式来指定期望运行的测试函数。常用于筛选要进行运行的测试函数。在以下示例中,仅运行当前及其子目录中测试函数名含request或temp的测试函数,源代码如下所示:

  • test_01.py
import pytest

# First of sample function
def Add(x:int,y:int)->int:
    return x+y

# First of test function
def test_add_01():
    assert Add(2,3)==5

def test_add_02():
    assert Add(3,4)==6

def test_request_01():
    assert Add(4,3)==7

def test_temp_01():
    assert Add(8,3)==11
  • test_02.py
import requests

import  pytest

url = "http://www.baidu.com"
port = 80

def test_requestBaidu():
    testUrl=f"{url}:{port}"
    r=requests.get(url=testUrl,timeout=10)
    content=r.content.decode("utf8")
    print(content)
    assert "bai" in content
以下先验证筛选的结果是否正确:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest -k "request or temp" --collect-only
============================== test session starts =======================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 5 items / 2 deselected / 3 selected
<Module test_01.py>
  <Function test_request_01>
  <Function test_temp_01>
<Module test_02.py>
  <Function test_requestBaidu>
=========================== 2 deselected in 2.36s =================================

实际运行结果:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest -k "request or temp" -v
======================== test session starts ======================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 5 items / 2 deselected / 3 selected
test_01.py::test_request_01 PASSED                                            [ 33%]
test_01.py::test_temp_01 PASSED                                               [ 66%]
test_02.py::test_requestBaidu PASSED                                          [100%]
====================== 3 passed, 2 deselected in 0.52s ==============================

3.3.3 -m MarkExpr

    该选项常用于标记测试并分组,方便快速运行选中的测试函数,具体的标记可以自定义,可以使用装饰器@pytest.mark。示例如下:

  • test_01.py
import pytest

# First of sample function
def Add(x:int,y:int)->int:
    return x+y

@pytest.mark.TestMark
# First of test function
def test_add_01():
    assert Add(2,3)==5

def test_add_02():
    assert Add(3,4)==6

@pytest.mark.RunThisTestFunc
def test_request_01():
    assert Add(4,3)==7

def test_temp_01():
    assert Add(8,3)==11
  • test_01.py
import requests
import  pytest

url = "http://www.baidu.com"
port = 80

@pytest.mark.RunThisTestFunc
def test_requestBaidu():
    testUrl=f"{url}:{port}"
    r=requests.get(url=testUrl,timeout=10)
    content=r.content.decode("utf8")
    print(content)
    assert "bai" in content

运行结果如下所示:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest -m "RunThisTestFunc or not TestMark" --collect-only
=========================== test session starts ====================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 5 items / 1 deselected / 4 selected
<Module test_01.py>
  <Function test_add_02>
  <Function test_request_01>
  <Function test_temp_01>
<Module test_02.py>
  <Function test_requestBaidu>  
C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest -m "RunThisTestFunc or not TestMark" -v
========================== test session starts =======================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 5 items / 1 deselected / 4 selected
test_01.py::test_add_02 FAILED                                                                   [ 25%]
test_01.py::test_request_01 PASSED                                                               [ 50%]
test_01.py::test_temp_01 PASSED                                                                  [ 75%]
test_02.py::test_requestBaidu PASSED                                                             [100%]

3.3.4 -x, --exitfirst

    正常情况下,pytest会运行每一个搜索到的测试函数,如果某个测试函数断言失败或触发了异常,则该测试函数的运行就停止了,此时pytest会将其标记为失败,然后继续运行后续的测试函数,这也是我们期望的运行模式。那如果我们希望在某一个测试函数在运行失败,则中断不再运行后续的测试函数,此时就可以使用-x选项。

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest -x
========================== test session starts =========================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 6 items
test_01.py .F
=============================== FAILURES ==========================================
_____________________________________________________ test_add_02 _____________________________________________________
    def test_add_02():
>       assert Add(3,4)==6
E       assert 7 == 6
E        +  where 7 = Add(3, 4)
test_01.py:13: AssertionError
==================== 1 failed, 1 passed, 3 warnings in 0.32s =========================

从输出的信息可以看出,总共有6个测试函数,而在运行第2个测试函数,断言失败,则停止整个运行过程,因此,仅运行了2个测试函数,一个测试通过,一个测试失败。

3.3.5 --maxfail=num

    -x选项的特点是一遇到失败,就会直接全部停止。而如果想要pytest在失败n次后再停止,则可通过选项-maxfail指定允许失败的次数。

import pytest

# First of sample function
def Add(x:int,y:int)->int:
    return x+y

@pytest.mark.TestMark
# First of test function
def test_add_01():
    assert Add(2,3)==5

def test_add_02():
    assert Add(3,4)==6

@pytest.mark.RunThisTestFunc
def test_request_01():
    assert Add(4,3)==7

def test_temp_01():
    assert Add(8,3)==12

运行结果如下所示:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest --maxfail=2
=============================== test session starts =====================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 6 items
test_01.py .F.F
================================= FAILURES ==========================================
_________________________________ test_add_02 __________________________________________
    def test_add_02():
>       assert Add(3,4)==6
E       assert 7 == 6
E        +  where 7 = Add(3, 4)
test_01.py:13: AssertionError
________________________________ test_temp_01 _________________________________________
    def test_temp_01():
>       assert Add(8,3)==12
E       assert 11 == 12
E        +  where 11 = Add(8, 3)
test_01.py:20: AssertionError
====================== 2 failed, 2 passed, 3 warnings in 0.35s =========================

如果--maxfail=1,则功能与-x一样

3.3.6 --lf --last-failed

    当一个或多个测试函数运行失败后,我们常常希望能够定位到最后一个运行失败的测试函数,并且希望能重新运行,这时则可以使用--lf选项

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest --lf
============================== test session starts ====================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 4 items / 2 deselected / 2 selected
run-last-failure: rerun previous 2 failures (skipped 3 files)
test_01.py FF                                                                                        [100%]

=================================== FAILURES ==========================================
____________________________ test_add_02 ________________________________________
    def test_add_02():
>       assert Add(3,4)==6
E       assert 7 == 6
E        +  where 7 = Add(3, 4)
test_01.py:13: AssertionError
_____________________________________test_temp_01 _________________________________________
    def test_temp_01():
>       assert Add(8,3)==12
E       assert 11 == 12
E        +  where 11 = Add(8, 3)
test_01.py:20: AssertionError
==================== 2 failed, 2 deselected, 2 warnings in 0.13s =============================

3.3.7 --ff --failed-first

    --ff选项与--lf选项功能基本相同,不同之处如下所示:

--ff 先运行上次失败的测试函数再运行完剩余的测试函数
--lf 仅运行上次失败的测试函数

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest --ff
=============================== test session starts =======================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 6 items
run-last-failure: rerun previous 2 failures first
test_01.py FF..                                                                           [ 66%]
test_02.py .                                                                              [ 83%]
test_03.py .                                                                              [100%]
================================= FAILURES ======================================
______________________________________test_add_02 ____________________________________________
    def test_add_02():
>       assert Add(3,4)==6
E       assert 7 == 6
E        +  where 7 = Add(3, 4)
test_01.py:13: AssertionError
_______________________________________ test_temp_01 _________________________________________
    def test_temp_01():
>       assert Add(8,3)==12
E       assert 11 == 12
E        +  where 11 = Add(8, 3)
test_01.py:20: AssertionError
======================== 2 failed, 4 passed, 3 warnings in 1.88s ======================

3.3.8 -v --verbose

    使用-v/--verbose,常用于输出详细的运行信息。最主要的区别是每个文件中的每个测试函数都占用一行(之前是每一个文件占用一行),测试的结果和名字都会显示出来,而不再在是一个点或字符,如下所示:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest --ff --tb=no -v
======================== test session starts =====================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 6 items
run-last-failure: rerun previous 2 failures first
test_01.py::test_add_02 FAILED                                                                [ 16%]
test_01.py::test_temp_01 FAILED                                                               [ 33%]
test_01.py::test_add_01 PASSED                                                                [ 50%]
test_01.py::test_request_01 PASSED                                                            [ 66%]
test_02.py::test_requestBaidu PASSED                                                          [ 83%]
test_03.py::test_request PASSED                                                               [100%]
====================== 2 failed, 4 passed, 3 warnings in 0.93s =============================

如果运行是彩色终端,则FAILED为红色字体,PASS为绿色字体。

3.3.9 -q --quiet

    该选项与-v功能相反,该选项会输出简化信息,只保留核心信息。如下所示:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest --ff --tb=line -q
FF....                                                                                        [100%]
======================================== FAILURES ====================================
C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01\test_01.py:13: assert 7 == 6
C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01\test_01.py:20: assert 11 == 12
2 failed, 4 passed, 3 warnings in 1.34s

3.3.10 --tb=style

    --tb参数主要决定捕捉到失败后的输出信息的显示方式。其可选值为 auto/long/short/line/native/no,其常用模式解释如下:

  • auto模式:默认值,如果有多个测试函数失败,仅打印第一个和最后一个用例的回溯信息
  • long模式:输出的信息最详细
  • short模式:仅输出assert的一行及系统判定内容,不显示上下文
  • line模式:只使用一行输出显示所有的错误信息
  • native模式:只输出Python标准库的回溯信息,不显示额外信息
  • no模式:直接屏蔽全部回溯信息

    以上模式常用模式为:short/line/no

某个测试函数运行失败后,pytest会列举出失败信息,包括失败出现在哪一行,什么原因导致的失败,该过程称之为信息回溯

示例如下所示:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest -v --tb=line
============================ test session starts ================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 6 items
test_01.py::test_add_01 PASSED                                                              [ 16%]
test_01.py::test_add_02 FAILED                                                              [ 33%]
test_01.py::test_request_01 PASSED                                                          [ 50%]
test_01.py::test_temp_01 FAILED                                                             [ 66%]
test_02.py::test_requestBaidu PASSED                                                        [ 83%]
test_03.py::test_request PASSED                                                             [100%]
==================================== FAILURES ==========================================
C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01\test_01.py:13: assert 7 == 6
C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01\test_01.py:20: assert 11 == 12
========================= 2 failed, 4 passed, 3 warnings in 2.10s ===========================

3.3.11 --durations=N

    --durations=N 该选项不关注测试具体的运行过程,只统计测试过程中哪向个阶段最慢,因此使用该选项可以加快测试分节奏,显示运行最慢的N个阶段,耗时越长越靠前,如果--durations=0,则将所有阶段的耗时从长到短排序后显示。示例如下所示:

C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01>pytest  --durations=3  --tb=line -v
============================test session starts ==========================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01
collected 6 items
test_01.py::test_add_01 PASSED                                                              [ 16%]
test_01.py::test_add_02 FAILED                                                              [ 33%]
test_01.py::test_request_01 PASSED                                                          [ 50%]
test_01.py::test_temp_01 FAILED                                                             [ 66%]
test_02.py::test_requestBaidu PASSED                                                        [ 83%]
test_03.py::test_request PASSED                                                             [100%]
=============================== FAILURES =========================================
C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01\test_01.py:13: assert 7 == 6
C:\Users\Surpass\PycharmProjects\PytestStudy\Lesson01\test_01.py:20: assert 11 == 12
=============================== warnings summary ======================================
================================ slowest 3 test durations =================================
0.50s call     test_03.py::test_request
0.06s call     test_02.py::test_requestBaidu
(0.00 durations hidden.  Use -vv to show these durations.)
======================= 2 failed, 4 passed, 3 warnings in 0.93s ===========================

3.3.12 -h --help

    以上仅仅是常用的一些选项,更多选项可通过-h或--help来进行查看,通过该选项不但能展示原生pytest的用法,还能展示新添加插件的选项和用法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342