web-dev-qa-db-ja.com

PyCharmにpytestのエラー差分全体を表示するにはどうすればよいですか?

Pycharm を使用して pytest 単体テストを実行しています。 REST APIをテストしているため、JSONのブロックを検証する必要があることがよくあります。テストが失敗すると、次のようになります。

FAILED
test_document_api.py:0 (test_create_documents)
{'items': [{'i...ages': 1, ...} != {'items': [{'...ages': 1, ...}

Expected :{'items': [{'...ages': 1, ...}
Actual   :{'items': [{'i...ages': 1, ...}
 <Click to see difference>

「クリックして違いを見る」リンクをクリックすると、ほとんどの違いが楕円の点に変換されます。

Pycharm comparison with differences elided

これは何が違うのかわからないので役に立たない。この動作は、単一の文字列または数値よりも大きな差がある場合に発生します。

私はPycharmやpytestが大きな出力の違いの有益でない部分を排除しようとすることを想定しています。ただし、ここではあまりにも攻撃的で、すべてを排除しています。

Pycharmまたはpytest、あるいはその両方を使用して、違い全体を表示するにはどうすればよいですか?

追加しようとしました-vvvをpytestの追加の引数に追加しますが、効果はありません。


元の投稿から、コマンドラインから単体テストを実行したときに同じ動作が発生することを確認しました。したがって、これはPycharmではなくpytestの問題です。

私がこれまでに得た答えを見て、私が本当に求めているのは「pytestではmaxDiff=Noneテストのソースコードを変更せずに? "pytestについて読んだことで得た印象は、-vvスイッチは、この設定を制御するものですが、そうではないようです。

24
W.P. McNeill

PyCharmソースを詳しく調べる場合pytest出力全体から、PyCharmはClick to see differenceダイアログに表示するデータを解析するために1行を使用します。これはAssertionError: <message>行です:

def test_spam():
>       assert v1 == v2
E       AssertionError: assert {'foo': 'bar'} == {'foo': 'baz'}
E         Differing items:
E         {'foo': 'bar'} != {'foo': 'baz'}
E         Use -v to get the full diff

完全なdiff行を切り捨てずに表示したい場合は、出力でこの行をカスタマイズする必要があります。単一のテストの場合、これはassertステートメントにカスタムメッセージを追加することで実行できます。

def test_eggs():
    assert a == b, '{0} != {1}'.format(a, b)

この動作をすべてのテストに適用する場合は、カスタム pytest_assertrepr_compare フックを定義します。 conftest.pyファイル:

# conftest.py
def pytest_assertrepr_compare(config, op, left, right):
    if op in ('==', '!='):
        return ['{0} {1} {2}'.format(left, op, right)]

値の等価比較は、長すぎる場合でも削除されます。完全な行を表示するには、-vvフラグを使用して冗長性を増やす必要があります。

これで、AssertionError行の値の等価比較が削除されず、完全な差分がClick to see differenceダイアログに表示され、差分部分が強調表示されます。

enter image description here

19
hoefling

Pytestはunittestと統合されているため、回避策として、それをunittestとして設定してからTest.maxDiff = Noneまたは特定のテストごとにself.maxDiff = None

https://docs.pytest.org/en/latest/index.html

単体テスト(トライアルを含む)およびノー​​ズテストスイートをそのまま実行できます。

これらも役に立つかもしれません...

https://stackoverflow.com/a/21615720/953079

https://stackoverflow.com/a/23617918/953079

4
shmuels

Pytestのコードベースを確認しました。おそらく、これらのいくつかを試すことができます。

1)テスト実行の詳細レベルを設定します。

./app_main --pytest --verbose test-suite/

2)「CI」または「BUILD_NUMBER」の環境変数を追加します。切り捨てファイルへのリンクで、これらの環境変数が切り捨てブロックが実行されるかどうかを決定するために使用されていることがわかります。

import os

os.environ["BUILD_NUMBER"] = '1'
os.environ["CI"] = 'CI_BUILD'

3)トランケートモジュールでDEFAULT_MAX_LINESおよびDEFAULT_MAX_CHARSを設定しようとします(プライベートモジュールを使用しているため、これは推奨されません):

from _pytest.assertion import truncate

truncate.DEFAULT_MAX_CHARS = 1000
truncate.DEFAULT_MAX_LINES = 1000

コードによると、-vvオプションは機能するはずなので、それがあなたのためではないのは奇妙です:

現在のデフォルトの動作は、「-vv」モードで実行されているか、CIで実行されていない限り、〜8端末行でアサーションの説明を切り捨てることです。

私の答えの基礎となっているPytestトランケーションファイル: pytest/truncate.py

ここで何かが役立つことを願っています!

1
cullzie

Pycharmでは、実行構成の追加の引数フィールドに-vvを入力するだけで問題を解決できます。

または、少なくとも、私のマシンでは動作しました...

0
kfox

私は似たようなものに出くわしていて、2つのdictsのニース差分を持つ文字列を返す関数を作成しました。 pytestスタイルのテストでは、次のようになります。

assert expected == actual, build_diff_string(expected, actual)

そしてunittestスタイルで

self.assertEqual(expected, actual, build_diff_string(expected, actual)

欠点は、この問題のあるすべてのテストを変更する必要があることですが、それはKeep It Simple and Stupidソリューションです。

0
jocassid