2016-04-09 18 views
15

pytestプラグインを使用して特定の例外の外観をカスタマイズしようとしています - 具体的には、例外を嘲笑する(呼び出されると思われるメソッドは呼び出されませんでした)それらの例外のトレースバックに無用なノイズが含まれています。pytest内の特定の例外のエラーメッセージをカスタマイズする

これは、私がこれまで持っているものであるが、動作しますが、非常にハックです:

import pytest 
import flexmock 

@pytest.hookimpl() 
def pytest_exception_interact(node, call, report): 
    exc_type = call.excinfo.type 

    if exc_type == flexmock.MethodCallError: 
     entry = report.longrepr.reprtraceback.reprentries[-1] 
     entry.style = 'short' 
     entry.lines = [entry.lines[-1]] 
     report.longrepr.reprtraceback.reprentries = [entry] 

私はhookimplで正しいことをやっている場合、単純なと例外タイプをチェックしていると思いますステートメント。

私も働いていた単純な文字列、とreport.longreprをreplaceingしようとしたが、その後私は(端末の色)をフォーマットするには負けます。私は短くしたい出力の種類の例として、ここではモックアサーションの失敗

です:

=================================== FAILURES ==================================== 
_______________________ test_session_calls_remote_client ________________________ 

    def test_session_calls_remote_client(): 
     remote_client = mock.Mock() 
     session = _make_session(remote_client) 
     session.connect() 
     remote_client.connect.assert_called_once_with() 
     session.run_action('asdf') 
>  remote_client.run_action.assert_called_once_with('asdff') 

tests/unit/executor/remote_test.py:22: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/python-3.6.3/lib/python3.6/unittest/mock.py:825: in assert_called_once_with 
    return self.assert_called_with(*args, **kwargs) 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.run_action' id='139987553103944'> 
args = ('asdff',), kwargs = {}, expected = (('asdff',), {}) 
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x7f51646269d8> 
actual = call('asdf'), cause = None 

    def assert_called_with(_mock_self, *args, **kwargs): 
     """assert that the mock was called with the specified arguments. 

      Raises an AssertionError if the args and keyword args passed in are 
      different to the last call to the mock.""" 
     self = _mock_self 
     if self.call_args is None: 
      expected = self._format_mock_call_signature(args, kwargs) 
      raise AssertionError('Expected call: %s\nNot called' % (expected,)) 

     def _error_message(): 
      msg = self._format_mock_failure_message(args, kwargs) 
      return msg 
     expected = self._call_matcher((args, kwargs)) 
     actual = self._call_matcher(self.call_args) 
     if expected != actual: 
      cause = expected if isinstance(expected, Exception) else None 
>   raise AssertionError(_error_message()) from cause 
E   AssertionError: Expected call: run_action('asdff') 
E   Actual call: run_action('asdf') 

/opt/python-3.6.3/lib/python3.6/unittest/mock.py:814: AssertionError 
====================== 1 failed, 30 passed in 0.28 seconds ====================== 
+4

私はあなたが達成したいことを本当に得られません。スタックの深さを減らしたいのですが、特定のコールを削除したいですか?あなたが得るものと達成したいものの例を挙げることができますか? –

+1

私が解決したい主な問題は、模擬期待が失敗したときにpythonの 'mock' /' unittest.mock'/'flexmock'ライブラリを使用すると、"メソッドXが呼び出されなかった引数Yで十分である。 – Andreas

+6

出力は現在どのようなものか、どのように見えるかの例がありますか? – theY4Kman

答えて

0

あなたの目標は読みスタックトレースを容易にするためであれば、あなたは以下のコードブロックを使用することができますカスタムエラーメッセージを出力します。このカスタムエラーメッセージはスタックトレースの最後に表示されるため、上にスクロールする必要はありません。 with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"): pass --> Failed: Expecting ZeroDivisionError ソース:pytest's documentationだから、プラグインを作る代わりに、pytestの出力をgrepのようなものにパイプして、スタックトレースの無駄な部分を除外することができます。
正しいpytestデコレータとフック関数(pytest_exception_interact)を使用しているドキュメントに記載されている内容に基づいています。しかし、エラーの型チェックは不要かもしれません。 This section of the documentationは、 "このフックはskip.Exceptionのような内部例外ではない例外が発生した場合にのみ呼び出されます。"

関連する問題