# coding=utf-8
import pytest
def whatever():
return 9/0
def test_whatever():
try:
whatever()
except ZeroDivisionError as exc:
pytest.fail(exc, pytrace=True)
================================ test session starts =================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
plugins: Django, cov
collected 1 items
pytest_test.py F
====================================== FAILURES ======================================
___________________________________ test_whatever ____________________________________
def test_whatever():
try:
whatever()
except ZeroDivisionError as exc:
> pytest.fail(exc, pytrace=True)
E Failed: integer division or modulo by zero
pytest_test.py:12: Failed
============================== 1 failed in 1.16 seconds ==============================
Pytestがトレースバックを出力するようにするにはどうすればいいですか。whatever
関数のどこで例外が発生したのでしょうか。
pytest.raises(Exception)
はあなたが必要とするものです。
コード
import pytest
def test_passes():
with pytest.raises(Exception) as e_info:
x = 1 / 0
def test_passes_without_info():
with pytest.raises(Exception):
x = 1 / 0
def test_fails():
with pytest.raises(Exception) as e_info:
x = 1 / 1
def test_fails_without_info():
with pytest.raises(Exception):
x = 1 / 1
# Don't do this. Assertions are caught as exceptions.
def test_passes_but_should_not():
try:
x = 1 / 1
assert False
except Exception:
assert True
# Even if the appropriate exception is caught, it is bad style,
# because the test result is less informative
# than it would be with pytest.raises(e)
# (it just says pass or fail.)
def test_passes_but_bad_style():
try:
x = 1 / 0
assert False
except ZeroDivisionError:
assert True
def test_fails_but_bad_style():
try:
x = 1 / 1
assert False
except ZeroDivisionError:
assert True
出力
============================================================================================= test session starts ==============================================================================================
platform linux2 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
collected 7 items
test.py ..FF..F
=================================================================================================== FAILURES ===================================================================================================
__________________________________________________________________________________________________ test_fails __________________________________________________________________________________________________
def test_fails():
with pytest.raises(Exception) as e_info:
> x = 1 / 1
E Failed: DID NOT RAISE
test.py:13: Failed
___________________________________________________________________________________________ test_fails_without_info ____________________________________________________________________________________________
def test_fails_without_info():
with pytest.raises(Exception):
> x = 1 / 1
E Failed: DID NOT RAISE
test.py:17: Failed
___________________________________________________________________________________________ test_fails_but_bad_style ___________________________________________________________________________________________
def test_fails_but_bad_style():
try:
x = 1 / 1
> assert False
E assert False
test.py:43: AssertionError
====================================================================================== 3 failed, 4 passed in 0.02 seconds ======================================================================================
e_info
は例外オブジェクトを保存するので、そこから詳細を抽出できます。たとえば、例外呼び出しスタックまたは内部の別のネストされた例外を確認したい場合です。
こんな意味ですか?
def test_raises():
with pytest.raises(Exception) as excinfo:
raise Exception('some info')
assert excinfo.value.message == 'some info'
Pytestでこのようなケースを処理するには、2つの方法があります。
pytest.raises
関数を使用する
pytest.mark.xfail
デコレーターの使用
pytest.raises
の使用:
def whatever():
return 9/0
def test_whatever():
with pytest.raises(ZeroDivisionError):
whatever()
pytest.mark.xfail
の使用:
@pytest.mark.xfail(raises=ZeroDivisionError)
def test_whatever():
whatever()
pytest.raises
の出力:
============================= test session starts ============================
platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 --
/usr/local/python_2.7_10/bin/python
cachedir: .cache
rootdir: /home/user, inifile:
collected 1 item
test_fun.py::test_whatever PASSED
======================== 1 passed in 0.01 seconds =============================
pytest.xfail
マーカーの出力:
============================= test session starts ============================
platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 --
/usr/local/python_2.7_10/bin/python
cachedir: .cache
rootdir: /home/user, inifile:
collected 1 item
test_fun.py::test_whatever xfail
======================== 1 xfailed in 0.03 seconds=============================
ドキュメント が言うように:
pytest.raises
を使用すると、独自のコードで意図的に発生する例外をテストする場合に向いていますが、チェック関数で@pytest.mark.xfail
を使用すると、未修正のバグ(テストで発生するはずの内容)またはバグを文書化するような場合に向いています依存関係で。
あなたが試すことができます
def test_exception():
with pytest.raises(Exception) as excinfo:
function_that_raises_exception()
assert str(excinfo.value) == 'some info'
この解決策は、私たちが使用しているものです。
def test_date_invalidformat():
"""
Test if input incorrect data will raises ValueError exception
"""
date = "06/21/2018 00:00:00"
with pytest.raises(ValueError):
app.func(date) #my function to be tested
Pytestを参照してください、 https://docs.pytest.org/en/latest/reference.html#pytest-raises
正しい方法はpytest.raises
を使用することですが、私はコメントに興味深い代替方法を見つけました ここ そしてこの質問を将来読む人のために保存したいです:
try:
thing_that_rasises_typeerror()
assert False
except TypeError:
assert True
pytestは絶えず進化していて、最近の過去のNiceの変更の1つでそれが可能になりました同時にテスト
ドキュメントからの2つの例:
with pytest.raises(ValueError, match='must be 0 or None'):
raise ValueError('value must be 0 or None')
with pytest.raises(ValueError, match=r'must be \d+$'):
raise ValueError('value must be 42')
私はこのアプローチをいくつかのプロジェクトで使っていて、とても気に入っています。
"pytrace = True"を削除しようとしましたか?
pytest.fail(exc, pytrace=True) # before
pytest.fail(exc) # after
'--fulltrace'で実行しましたか?
より良い方法は、unittest.TestCaseを継承し、self.assertRaisesを実行するクラスを使用することです。
例えば:
import unittest
def whatever():
return 9/0
class TestWhatEver(unittest.TestCase):
def test_whatever():
with self.assertRaises(ZeroDivisionError):
whatever()
それからあなたは実行することによってそれを実行するでしょう:
pytest -vs test_path