2016-04-09 20 views
15

Belirli özel durumların görünümünü özelleştirmek için bir pytest eklentisi yazmaya çalışıyorum - daha özel olarak, alay özel durumları (çağrılması beklenen yöntem çağrılmadı vb.), Çünkü çok şey var Bu istisnaların geri kalanında faydasız gürültü. Özel özel durumlar için hata iletisini pytest'te özelleştirme

Bu

ben çalışır, hangi şimdiye kadar ne var, ancak son derece hacky geçerli:

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] 

ben hookimpl ile doğru olanı yapıyor ve eğer basit ile istisna tipini kontrol ediyorum düşünüyorum Beyan.

report.longrepr'u da çalıştıran basit bir dizeyle değiştirmeyi denedim, ancak sonra biçimlendirmeyi kaybediyorum (terminaldeki renkler). Amacınız okumak için StackTrace kolaylaştırmak için ise

=================================== 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

Gerçekten neye ulaşmak istediğinizi anlamıyorum. Yığının derinliğini azaltmak mı yoksa belirli çağrıları mı silmek istiyorsunuz? Aldığın ve elde etmek istediğin şeyin bir örneğini verebilir misin? –

+1

Çözmek istediğim asıl sorun, python'un “mock”/'unittest.mock' /' flexmock' kitaplıklarını kullanarak, sahte beklentiler başarısız olduğunda, "X yöntemi çağrılmadığında, ekrana dağılmış büyük bir yığın izi var argümanlarla Y "yeterli olur. – Andreas

+6

Çıktının neye benzediğine ve neye benzediğine dair bir örneğiniz var mı? – theY4Kman

cevap

0

, o zaman aşağıda kod bloğu kullanabilirsiniz: Ben kısaltmak istiyorsanız çıktı tipine bir örnek olarak

, burada sahte onaylama işlemi hatası var özel bir hata mesajı vermek için Bu özel hata iletisi, stacktrace'in sonunda görünür, dolayısıyla yukarı kaydırmanıza gerek kalmaz: with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"): pass --> Failed: Expecting ZeroDivisionError Kaynak: pytest's documentation. Bu yüzden, bir eklenti yapmak yerine, grep gibi çıktıları grep gibi bir şeyden geçirebilir ve stacktrace'in işe yaramaz kısımlarını filtreleyebilirsiniz.
Dokümanlarda okuduğum bilgilere göre doğru pytest dekoratör ve kanca işlevini kullanıyorsunuz ( pytest_exception_interact). Ancak, hatayı kontrol etmek gereksiz olabilir. This section of the documentation, "Bu kanca yalnızca skip.Exception gibi bir iç istisna olmayan bir istisna kaldırılmışsa çağrılır."

İlgili konular