pytest の出力を管理する

Python トレースバックの印刷を変更する

トレースバック印刷を変更する例:

pytest --showlocals     # show local variables in tracebacks
pytest -l               # show local variables (shortcut)
pytest --no-showlocals  # hide local variables (if addopts enables them)

pytest --capture=fd  # default, capture at the file descriptor level
pytest --capture=sys # capture at the sys level
pytest --capture=no  # don't capture
pytest -s            # don't capture (shortcut)
pytest --capture=tee-sys # capture to logs but also output to sys level streams

pytest --tb=auto    # (default) 'long' tracebacks for the first and last
                     # entry, but 'short' style for the other entries
pytest --tb=long    # exhaustive, informative traceback formatting
pytest --tb=short   # shorter traceback format
pytest --tb=line    # only one line per failure
pytest --tb=native  # Python standard library formatting
pytest --tb=no      # no traceback at all

--full-trace は、エラー時に非常に長いトレースを印刷します (--tb=long よりも長い) 。 また、KeyboardInterrupt (Ctrl+C) でスタックトレースが印刷されることを保証します。 これは、テストに時間がかかりすぎて Ctrl+C で中断し、テストがどこで ハング しているかを確認する場合に非常に便利です。 デフォルトでは、出力は表示されません (KeyboardInterrupt は pytest によってキャッチされるため) 。 このオプションを使用すると、トレースが表示されることを確認できます。

冗長性

印刷の冗長性を変更する例:

pytest --quiet          # quiet - less verbose - mode
pytest -q               # quiet - less verbose - mode (shortcut)
pytest -v               # increase verbosity, display individual test names
pytest -vv              # more verbose, display more details from the test output
pytest -vvv             # not a standard , but may be used for even more detail in certain setups

-v フラグは、pytest 出力の冗長性をさまざまな側面で制御します: テストセッションの進行状況、テストが失敗したときのアサーションの詳細、--fixtures を使用したフィクスチャの詳細など。

この簡単なファイルを考えてみましょう:

# content of test_verbosity_example.py
def test_ok():
    pass


def test_words_fail():
    fruits1 = ["banana", "apple", "grapes", "melon", "kiwi"]
    fruits2 = ["banana", "apple", "orange", "melon", "kiwi"]
    assert fruits1 == fruits2


def test_numbers_fail():
    number_to_text1 = {str(x): x for x in range(5)}
    number_to_text2 = {str(x * 10): x * 10 for x in range(5)}
    assert number_to_text1 == number_to_text2


def test_long_text_fail():
    long_text = "Lorem ipsum dolor sit amet " * 10
    assert "hello world" in long_text

通常、pytest を実行すると次の出力が得られます (ヘッダーをスキップして残りに焦点を当てています) :

$ pytest --no-header
=========================== test session starts ============================
collected 4 items

test_verbosity_example.py .FFF                                       [100%]

================================= FAILURES =================================
_____________________________ test_words_fail ______________________________

    def test_words_fail():
        fruits1 = ["banana", "apple", "grapes", "melon", "kiwi"]
        fruits2 = ["banana", "apple", "orange", "melon", "kiwi"]
>       assert fruits1 == fruits2
E       AssertionError: assert ['banana', 'a...elon', 'kiwi'] == ['banana', 'a...elon', 'kiwi']
E
E         At index 2 diff: 'grapes' != 'orange'
E         Use -v to get more diff

test_verbosity_example.py:8: AssertionError
____________________________ test_numbers_fail _____________________________

    def test_numbers_fail():
        number_to_text1 = {str(x): x for x in range(5)}
        number_to_text2 = {str(x * 10): x * 10 for x in range(5)}
>       assert number_to_text1 == number_to_text2
E       AssertionError: assert {'0': 0, '1':..., '3': 3, ...} == {'0': 0, '10'...'30': 30, ...}
E
E         Omitting 1 identical items, use -vv to show
E         Left contains 4 more items:
E         {'1': 1, '2': 2, '3': 3, '4': 4}
E         Right contains 4 more items:
E         {'10': 10, '20': 20, '30': 30, '40': 40}
E         Use -v to get more diff

test_verbosity_example.py:14: AssertionError
___________________________ test_long_text_fail ____________________________

    def test_long_text_fail():
        long_text = "Lorem ipsum dolor sit amet " * 10
>       assert "hello world" in long_text
E       AssertionError: assert 'hello world' in 'Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ips... sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet '

test_verbosity_example.py:19: AssertionError
========================= short test summary info ==========================
FAILED test_verbosity_example.py::test_words_fail - AssertionError: asser...
FAILED test_verbosity_example.py::test_numbers_fail - AssertionError: ass...
FAILED test_verbosity_example.py::test_long_text_fail - AssertionError: a...
======================= 3 failed, 1 passed in 0.12s ========================

次に注意してください:

  • ファイル内の各テストは、出力で単一の文字で表示されます: 合格の場合は .、失敗の場合は F

  • test_words_fail が失敗し、2 つのリストのインデックス 2 が異なることを示す短い要約が表示されます。

  • test_numbers_fail が失敗し、辞書アイテムの左右の違いの要約が表示されます。 同一のアイテムは省略されます。

  • test_long_text_fail が失敗し、in ステートメントの右側が内部しきい値 (現在は 240 文字) よりも長いため、...` を使用して切り捨てられます。

次に、pytest の冗長性を高めることができます:

$ pytest --no-header -v
=========================== test session starts ============================
collecting ... collected 4 items

test_verbosity_example.py::test_ok PASSED                            [ 25%]
test_verbosity_example.py::test_words_fail FAILED                    [ 50%]
test_verbosity_example.py::test_numbers_fail FAILED                  [ 75%]
test_verbosity_example.py::test_long_text_fail FAILED                [100%]

================================= FAILURES =================================
_____________________________ test_words_fail ______________________________

    def test_words_fail():
        fruits1 = ["banana", "apple", "grapes", "melon", "kiwi"]
        fruits2 = ["banana", "apple", "orange", "melon", "kiwi"]
>       assert fruits1 == fruits2
E       AssertionError: assert ['banana', 'a...elon', 'kiwi'] == ['banana', 'a...elon', 'kiwi']
E
E         At index 2 diff: 'grapes' != 'orange'
E
E         Full diff:
E           [
E               'banana',
E               'apple',...
E
E         ...Full output truncated (7 lines hidden), use '-vv' to show

test_verbosity_example.py:8: AssertionError
____________________________ test_numbers_fail _____________________________

    def test_numbers_fail():
        number_to_text1 = {str(x): x for x in range(5)}
        number_to_text2 = {str(x * 10): x * 10 for x in range(5)}
>       assert number_to_text1 == number_to_text2
E       AssertionError: assert {'0': 0, '1':..., '3': 3, ...} == {'0': 0, '10'...'30': 30, ...}
E
E         Omitting 1 identical items, use -vv to show
E         Left contains 4 more items:
E         {'1': 1, '2': 2, '3': 3, '4': 4}
E         Right contains 4 more items:
E         {'10': 10, '20': 20, '30': 30, '40': 40}
E         ...
E
E         ...Full output truncated (16 lines hidden), use '-vv' to show

test_verbosity_example.py:14: AssertionError
___________________________ test_long_text_fail ____________________________

    def test_long_text_fail():
        long_text = "Lorem ipsum dolor sit amet " * 10
>       assert "hello world" in long_text
E       AssertionError: assert 'hello world' in 'Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet '

test_verbosity_example.py:19: AssertionError
========================= short test summary info ==========================
FAILED test_verbosity_example.py::test_words_fail - AssertionError: asser...
FAILED test_verbosity_example.py::test_numbers_fail - AssertionError: ass...
FAILED test_verbosity_example.py::test_long_text_fail - AssertionError: a...
======================= 3 failed, 1 passed in 0.12s ========================

次に注意してください:

  • ファイル内の各テストは、出力で独自の行を取得します。

  • test_words_fail は、インデックスが異なることに加えて、失敗した 2 つのリストを完全に表示します。

  • test_numbers_fail は、2 つの辞書のテキスト差分を切り捨てて表示します。

  • test_long_text_fail は、切り捨ての内部しきい値が現在は大きいため (現在は 2400 文字) 、in ステートメントの右側を切り捨てなくなりました。

次に、さらに冗長性を高めると:

$ pytest --no-header -vv
=========================== test session starts ============================
collecting ... collected 4 items

test_verbosity_example.py::test_ok PASSED                            [ 25%]
test_verbosity_example.py::test_words_fail FAILED                    [ 50%]
test_verbosity_example.py::test_numbers_fail FAILED                  [ 75%]
test_verbosity_example.py::test_long_text_fail FAILED                [100%]

================================= FAILURES =================================
_____________________________ test_words_fail ______________________________

    def test_words_fail():
        fruits1 = ["banana", "apple", "grapes", "melon", "kiwi"]
        fruits2 = ["banana", "apple", "orange", "melon", "kiwi"]
>       assert fruits1 == fruits2
E       AssertionError: assert ['banana', 'apple', 'grapes', 'melon', 'kiwi'] == ['banana', 'apple', 'orange', 'melon', 'kiwi']
E
E         At index 2 diff: 'grapes' != 'orange'
E
E         Full diff:
E           [
E               'banana',
E               'apple',
E         -     'orange',
E         ?      ^  ^^
E         +     'grapes',
E         ?      ^  ^ +
E               'melon',
E               'kiwi',
E           ]

test_verbosity_example.py:8: AssertionError
____________________________ test_numbers_fail _____________________________

    def test_numbers_fail():
        number_to_text1 = {str(x): x for x in range(5)}
        number_to_text2 = {str(x * 10): x * 10 for x in range(5)}
>       assert number_to_text1 == number_to_text2
E       AssertionError: assert {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4} == {'0': 0, '10': 10, '20': 20, '30': 30, '40': 40}
E
E         Common items:
E         {'0': 0}
E         Left contains 4 more items:
E         {'1': 1, '2': 2, '3': 3, '4': 4}
E         Right contains 4 more items:
E         {'10': 10, '20': 20, '30': 30, '40': 40}
E
E         Full diff:
E           {
E               '0': 0,
E         -     '10': 10,
E         ?       -    -
E         +     '1': 1,
E         -     '20': 20,
E         ?       -    -
E         +     '2': 2,
E         -     '30': 30,
E         ?       -    -
E         +     '3': 3,
E         -     '40': 40,
E         ?       -    -
E         +     '4': 4,
E           }

test_verbosity_example.py:14: AssertionError
___________________________ test_long_text_fail ____________________________

    def test_long_text_fail():
        long_text = "Lorem ipsum dolor sit amet " * 10
>       assert "hello world" in long_text
E       AssertionError: assert 'hello world' in 'Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet '

test_verbosity_example.py:19: AssertionError
========================= short test summary info ==========================
FAILED test_verbosity_example.py::test_words_fail - AssertionError: assert ['banana', 'apple', 'grapes', 'melon', 'kiwi'] == ['banana', 'apple', 'orange', 'melon', 'kiwi']

  At index 2 diff: 'grapes' != 'orange'

  Full diff:
    [
        'banana',
        'apple',
  -     'orange',
  ?      ^  ^^
  +     'grapes',
  ?      ^  ^ +
        'melon',
        'kiwi',
    ]
FAILED test_verbosity_example.py::test_numbers_fail - AssertionError: assert {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4} == {'0': 0, '10': 10, '20': 20, '30': 30, '40': 40}

  Common items:
  {'0': 0}
  Left contains 4 more items:
  {'1': 1, '2': 2, '3': 3, '4': 4}
  Right contains 4 more items:
  {'10': 10, '20': 20, '30': 30, '40': 40}

  Full diff:
    {
        '0': 0,
  -     '10': 10,
  ?       -    -
  +     '1': 1,
  -     '20': 20,
  ?       -    -
  +     '2': 2,
  -     '30': 30,
  ?       -    -
  +     '3': 3,
  -     '40': 40,
  ?       -    -
  +     '4': 4,
    }
FAILED test_verbosity_example.py::test_long_text_fail - AssertionError: assert 'hello world' in 'Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet '
======================= 3 failed, 1 passed in 0.12s ========================

次に注意してください:

  • ファイル内の各テストは、出力で独自の行を取得します。

  • test_words_fail は、この場合、以前と同じ出力を提供します。

  • test_numbers_fail は、2 つの辞書の完全なテキスト差分を表示します。

  • test_long_text_fail も以前のように右側を切り捨てませんが、現在 pytest はサイズに関係なくテキストをまったく切り捨てません。

これらは、冗長性が通常のテストセッション出力にどのように影響するかの例でしたが、冗長性は他の状況でも使用されます。 たとえば、pytest --fixtures -v を使用すると、_ で始まるフィクスチャも表示されます。

より高い冗長性レベル (-vvv-vvvv など) の使用はサポートされていますが、現在のところ pytest 自体には影響はありませんが、一部のプラグインはより高い冗長性を利用する場合があります。

細かい冗長性

アプリケーション全体の冗長性レベルを指定することに加えて、特定の側面を独立して制御することも可能です。 これは、出力の特定の側面に対して構成ファイルに冗長性レベルを設定することで行われます。

verbosity_assertions: pytest が実行されるときにアサーション出力の冗長性を制御します。 値が 2pytest --no-header を実行すると、前の例と同じ出力が得られますが、ファイル内の各テストは出力で単一の文字で表示されます。

verbosity_test_cases: pytest が実行されるときにテスト実行出力の冗長性を制御します。 値が 2pytest --no-header を実行すると、最初の冗長性の例と同じ出力が得られますが、ファイル内の各テストは出力で独自の行を取得します。

詳細なサマリーレポートの作成

-r フラグを使用して、テストセッションの最後に「短いテストサマリー情報」を表示できます。 これにより、大規模なテストスイートで、すべての失敗、スキップ、xfail などの明確な概要を簡単に把握できます。

デフォルトでは、失敗とエラーをリストするために fE になります。

例:

# content of test_example.py
import pytest


@pytest.fixture
def error_fixture():
    assert 0


def test_ok():
    print("ok")


def test_fail():
    assert 0


def test_error(error_fixture):
    pass


def test_skip():
    pytest.skip("skipping this test")


def test_xfail():
    pytest.xfail("xfailing this test")


@pytest.mark.xfail(reason="always xfail")
def test_xpass():
    pass
$ pytest -ra
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 6 items

test_example.py .FEsxX                                               [100%]

================================== ERRORS ==================================
_______________________ ERROR at setup of test_error _______________________

    @pytest.fixture
    def error_fixture():
>       assert 0
E       assert 0

test_example.py:6: AssertionError
================================= FAILURES =================================
________________________________ test_fail _________________________________

    def test_fail():
>       assert 0
E       assert 0

test_example.py:14: AssertionError
================================= XPASSES ==================================
========================= short test summary info ==========================
SKIPPED [1] test_example.py:22: skipping this test
XFAIL test_example.py::test_xfail - reason: xfailing this test
XPASS test_example.py::test_xpass - always xfail
ERROR test_example.py::test_error - assert 0
FAILED test_example.py::test_fail - assert 0
== 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12s ===

-r オプションは、その後にいくつかの文字を受け入れます。 上記の a は「合格を除くすべて」を意味します。

使用できる文字の完全なリストは次のとおりです:

  • f - failed

  • E - error

  • s - skipped

  • x - xfailed

  • X - xpassed

  • p - passed

  • P - 出力付きで passed

グループの (非) 選択のための特殊文字:

  • a - pP を除くすべて

  • A - すべて

  • N - なし、これは何も表示しないために使用できます (fE がデフォルトであるため)

複数の文字を使用できます。 たとえば、失敗したテストとスキップされたテストのみを表示するには、次のように実行できます:

$ pytest -rfs
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 6 items

test_example.py .FEsxX                                               [100%]

================================== ERRORS ==================================
_______________________ ERROR at setup of test_error _______________________

    @pytest.fixture
    def error_fixture():
>       assert 0
E       assert 0

test_example.py:6: AssertionError
================================= FAILURES =================================
________________________________ test_fail _________________________________

    def test_fail():
>       assert 0
E       assert 0

test_example.py:14: AssertionError
========================= short test summary info ==========================
FAILED test_example.py::test_fail - assert 0
SKIPPED [1] test_example.py:22: skipping this test
== 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12s ===

p を使用すると、合格したテストがリストされ、P は、合格したが出力がキャプチャされたテストに「PASSES」という追加セクションを追加します:

$ pytest -rpP
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 6 items

test_example.py .FEsxX                                               [100%]

================================== ERRORS ==================================
_______________________ ERROR at setup of test_error _______________________

    @pytest.fixture
    def error_fixture():
>       assert 0
E       assert 0

test_example.py:6: AssertionError
================================= FAILURES =================================
________________________________ test_fail _________________________________

    def test_fail():
>       assert 0
E       assert 0

test_example.py:14: AssertionError
================================== PASSES ==================================
_________________________________ test_ok __________________________________
--------------------------- Captured stdout call ---------------------------
ok
========================= short test summary info ==========================
PASSED test_example.py::test_ok
== 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12s ===

注釈

デフォルトでは、スキップされたテストのパラメータ化されたバリアントは、同じスキップ理由を共有している場合に一緒にグループ化されます。 --no-fold-skipped を使用して、スキップされた各テストを個別に印刷できます。

resultlog 形式のファイルを作成する

プレーンテキストの機械可読の結果ファイルを作成するには、次のコマンドを発行できます:

pytest --resultlog=path

そして、path の場所にあるコンテンツを確認します。 このようなファイルは、たとえば PyPy-test ウェブページで使用され、いくつかのリビジョンにわたるテスト結果を表示します。

警告

このオプションはめったに使用されず、pytest 6.0 で削除される予定です。

このオプションを使用する場合は、新しい pytest-reportlog プラグインの使用を検討してください。

詳細については、the deprecation docs を参照してください。

JUnitXML 形式のファイルを作成する

Jenkins や他の継続的インテグレーションサーバーで読み取ることができる結果ファイルを作成するには、この呼び出しを使用します:

pytest --junit-xml=path

path に XML ファイルを作成します。

ルートテストスイート XML アイテムの名前を設定するには、構成ファイルで junit_suite_name オプションを構成できます:

[pytest]
junit_suite_name = my_suite

Added in version 4.0.

JUnit XML 仕様では、"time" 属性はセットアップとテアダウンを含む総テスト実行時間を報告する必要があることを示しているようです (12)。 これはデフォルトの pytest の動作です。 代わりに呼び出し時間のみを報告するには、次のように junit_duration_report オプションを構成します:

[pytest]
junit_duration_report = call

record_property

テストの追加情報を記録したい場合は、record_property フィクスチャを使用できます:

def test_function(record_property):
    record_property("example_key", 1)
    assert True

これにより、生成された testcase タグに追加のプロパティ example_key="1" が追加されます:

<testcase classname="test_function" file="test_function.py" line="0" name="test_function" time="0.0009">
  <properties>
    <property name="example_key" value="1" />
  </properties>
</testcase>

または、この機能をカスタムマーカーと統合できます:

# content of conftest.py


def pytest_collection_modifyitems(session, config, items):
    for item in items:
        for marker in item.iter_markers(name="test_id"):
            test_id = marker.args[0]
            item.user_properties.append(("test_id", test_id))

そして、あなたのテストで:

# content of test_function.py
import pytest


@pytest.mark.test_id(1501)
def test_function():
    assert True

次のようになります:

<testcase classname="test_function" file="test_function.py" line="0" name="test_function" time="0.0009">
  <properties>
    <property name="test_id" value="1501" />
  </properties>
</testcase>

警告

この機能を使用すると、最新の JUnitXML スキーマのスキーマ検証が壊れることに注意してください。 これは、一部の CI サーバーで使用する場合に問題になる可能性があります。

record_xml_attribute

testcase 要素に追加の XML 属性を追加するには、record_xml_attribute フィクスチャを使用できます。 これを使用して既存の値を上書きすることもできます:

def test_function(record_xml_attribute):
    record_xml_attribute("assertions", "REQ-1234")
    record_xml_attribute("classname", "custom_classname")
    print("hello world")
    assert True

record_property とは異なり、これにより新しい子要素は追加されません。 代わりに、生成された testcase タグ内に属性 assertions="REQ-1234" を追加し、デフォルトの classname"classname=custom_classname" で上書きします:

<testcase classname="custom_classname" file="test_function.py" line="0" name="test_function" time="0.003" assertions="REQ-1234">
    <system-out>
        hello world
    </system-out>
</testcase>

警告

record_xml_attribute は実験的な機能であり、そのインターフェースは将来のバージョンでより強力で一般的なものに置き換えられる可能性があります。 ただし、機能自体は保持されます。

これを record_xml_property の代わりに使用すると、CI ツールを使用して XML レポートを解析する際に役立ちます。 ただし、一部のパーサーは、許可される要素と属性について非常に厳格です。 多くのツールは、受信 XML を検証するために xsd スキーマ (以下の例のようなもの) を使用します。 パーサーで許可されている属性名を使用していることを確認してください。

以下は、Jenkins が XML レポートを検証するために使用するスキームです:

<xs:element name="testcase">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="skipped" minOccurs="0" maxOccurs="1"/>
            <xs:element ref="error" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="failure" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="system-out" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="system-err" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="assertions" type="xs:string" use="optional"/>
        <xs:attribute name="time" type="xs:string" use="optional"/>
        <xs:attribute name="classname" type="xs:string" use="optional"/>
        <xs:attribute name="status" type="xs:string" use="optional"/>
    </xs:complexType>
</xs:element>

警告

この機能を使用すると、最新の JUnitXML スキーマのスキーマ検証が壊れることに注意してください。 これは、一部の CI サーバーで使用する場合に問題になる可能性があります。

record_testsuite_property

Added in version 4.5.

すべてのテストに関連するプロパティを含む可能性のあるプロパティノードをテストスイートレベルで追加する場合は、record_testsuite_property セッションスコープのフィクスチャを使用できます:

record_testsuite_property セッションスコープのフィクスチャを使用して、すべてのテストに関連するプロパティを追加できます。

import pytest


@pytest.fixture(scope="session", autouse=True)
def log_global_env_facts(record_testsuite_property):
    record_testsuite_property("ARCH", "PPC")
    record_testsuite_property("STORAGE_TYPE", "CEPH")


class TestMe:
    def test_foo(self):
        assert True

フィクスチャは、生成された XML のテストスイートレベルに追加された <property> タグの namevalue を受け取る呼び出し可能なものです:

<testsuite errors="0" failures="0" name="pytest" skipped="0" tests="1" time="0.006">
  <properties>
    <property name="ARCH" value="PPC"/>
    <property name="STORAGE_TYPE" value="CEPH"/>
  </properties>
  <testcase classname="test_me.TestMe" file="test_me.py" line="16" name="test_foo" time="0.000243663787842"/>
</testsuite>

name は文字列である必要があり、value は文字列に変換され、適切に XML エスケープされます。

生成された XML は、record_property および record_xml_attribute とは異なり、最新の xunit 標準と互換性があります。

テストレポートをオンラインの pastebin サービスに送信する

各テスト失敗のための URL を作成する:

pytest --pastebin=failed

これにより、テスト実行情報がリモートの Paste サービスに送信され、各失敗に対して URL が提供されます。 通常どおりテストを選択するか、特定の失敗のみを送信する場合は、たとえば -x を追加できます。

テストセッション全体のログの URL を作成する:

pytest --pastebin=all

現在、https://bpaste.net/ サービスへの貼り付けのみが実装されています。

バージョン 5.2 で変更.

何らかの理由で URL の作成に失敗した場合、テストスイート全体が失敗するのではなく、警告が生成されます。