我pytest用來運行一些單元測驗。我的一些測驗涉及使用無效引數初始化物件,并測驗引發的例外是否包含預期的錯誤訊息。
為此,我正在使用raises,但是pytest沒有通過測驗而不是捕獲例外。測驗輸出顯示引發了預期的例外。
>>> def test_400_invalid_org_id(self):
...
... # Setting host, org_id and body here.
...
... with pytest.raises(InvalidOrgIdException) as e_info:
... OrgRequest(host, org_id, body)
...
... assert str(e_info.value) == 'Invalid organisation ID.'
E InvalidOrgIdException: Invalid organisation ID.
顯然InvalidOrgIdException是自定義型別(正確匯入),是Exception. 并且由于某種原因pytest.raises(Exception)按預期作業。查看檔案,它表明我應該能夠斷言已捕獲的例外的型別,但這也失敗了。
>>> def test_400_invalid_org_id(self):
...
... # Setting host, org_id and body here.
...
... with pytest.raises(Exception) as e_info:
... OrgRequest(host, org_id, body)
...
... assert str(e_info.value) == 'Invalid organisation ID.'
... assert e_info.type is InvalidOrgIdException
E AssertionError: assert <class 'InvalidOrgIdException'> is InvalidOrgIdException
E where <class 'InvalidOrgIdException'> = <ExceptionInfo InvalidOrgIdException('xxx', '^[a-z0-9]{16}$') tblen=3>.type
比較e_info.typeand時, and方法InvalidOrgIdException是有區別的。請注意,匯入的物件都來自同一個模塊 - 我也不是在嘲笑。__init____str__
>>> pprint(vars(e_info.type))
mappingproxy({'__doc__': 'Organisation ID in path is invalid.',
'__init__': <function InvalidOrgIdException.__init__ at 0x7f58b867e8b0>,
'__module__': 'builtins',
'__str__': <function InvalidOrgIdException.__str__ at 0x7f58b867e9d0>,
'__weakref__': <attribute '__weakref__' of 'InvalidOrgIdException' objects>})
...
>>> pprint(vars(InvalidOrgIdException))
mappingproxy({'__doc__': 'Organisation ID in path is invalid.',
'__init__': <function InvalidOrgIdException.__init__ at 0x7f58b867e670>,
'__module__': 'builtins',
'__str__': <function InvalidOrgIdException.__str__ at 0x7f58b867e700>,
'__weakref__': <attribute '__weakref__' of 'InvalidOrgIdException' objects>})
那么為什么會pytest以這種方式表現,是否有可能改變這種行為呢?
提高類InvalidOrgIdException
class OrgRequest():
def __init__(self) -> None:
raise InvalidOrgIdException() from None
pytest運行的完整輸出
正在從myproject目錄運行測驗(請參閱問題底部的檔案結構)。
python -m pytest tests/unit/test_requests.py --verbose
測驗是使用--verbose引數運行的。我不是pytest專家,但我認為沒有更詳細的輸出可用。
========================================================================================= test session starts ==========================================================================================
platform linux -- Python 3.8.10, pytest-7.0.1, pluggy-1.0.0 -- /usr/bin/python
cachedir: .pytest_cache
rootdir: /home/me/myproject/tests, configfile: pytest.ini
plugins: env-0.6.2, mock-3.7.0
collected 1 item
tests/unit/test_requests.py::TestRequests::test__400_org_id_invalid FAILED
=============================================================================================== FAILURES ===============================================================================================
_________________________________________________________________________________ TestRequests.test_400_org_id_invalid _________________________________________________________________________________
self = <tests.unit.test_requests.TestRequests object at 0x7f7627e07e20>
def test_400_org_id_invalid(self):
with pytest.raises(InvalidOrgIdException) as e_info:
> OrgRequest()
tests/unit/test_requests.py:9:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <myfunction.core.request.OrgRequest object at 0x7f7627e20130>
def __init__(self) -> None:
> raise InvalidOrgIdException() from None
E InvalidOrgIdException: Invalid organisation ID.
myfunction/core/request.py:19: InvalidOrgIdException
======================================================================================= short test summary info ========================================================================================
FAILED tests/unit/test_requests.py::TestRequests::test_400_org_id_invalid - InvalidOrgIdException: Invalid organisation ID.
========================================================================================== 1 failed in 0.06s ===========================================================================================
檔案結構
myproject
├── myfunction
| ├── app.py
| └── core
| ├── exception.py
| └── request.py
└── tests
└── unit
└── test_requests.py
哈奇“修復”
If I move InvalidOrgIdException into the same module as OrgRequest then import the exception from there, the test passes. Obviously though I'd prefer not to do this, as it makes sense for all of the exceptions to live together. And although the "fix" exists, I'd still like to usnderstand what's happening and exactly why it works.
from app import InvalidOrgIdException
uj5u.com熱心網友回復:
正如我的問題中提到的,捕獲的例外的比較pytest.raises()似乎與從我的代碼中匯入的例外不同。我必須承認,我不是 Python 的期望,我不明白為什么這會起作用,但解決方案是將init .py添加到core模塊中,并在其中匯入該包中的所有模塊。
from core.exception import *
from core.logging import *
# etc.
然后在tests/unit/test_requests.py中,我能夠從core包中匯入所有物件。
from myfunction.core import *
現在pytest看到它捕獲的例外和匯入的例外相同,并且我的測驗通過了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/446222.html
上一篇:控制臺應用程式未在AppDomain.CurrentDomain.UnhandledException中使用NLOG記錄錯誤
