喬在接受的答案中提出了一個評論 ,他問道:
有沒有辦法打印到控制臺并捕獲輸出,以便它顯示在junit報告中?
在UNIX中,這通常被稱為開球 。 理想情況下,開球而不是捕捉將是py.test默認。 非理想情況下,無論py.test還是任何現有的第三方py.test插件( 我知道,無論如何 )支持開球 – 盡pipePython平凡支持開箱即用 。
猴子補丁py.test做任何不支持的東西是不平凡的。 為什么? 因為:
大多數py.testfunction被locking在一個不打算從外部導入的私有_pytest包之后。 試圖在不知道自己在做什么的情況下這樣做通常會導致公共pytest包在運行時引發模糊的exception。 非常感謝py.test。 真的強大的build筑,你到了那里。
即使你真的想搞清楚如何以安全的方式修改私有的_pytest API,你必須在運行由外部py.test命令運行的公共pytest包之前這樣做。 你不能在一個插件(例如,你的testing套件中的一個最高級的conftest模塊)中做到這一點。 當py.test懶洋洋地dynamic地導入你的插件的時候,任何想要猴子打補丁的py.test類都已經被實例化了,而且你沒有權限訪問這個實例。 這意味著,如果你想讓你的猴子補丁有意義的應用,你不能再安全地運行外部的py.test命令。 相反,您必須使用自定義的setuptools test命令來包裝該命令的運行(按順序):
Monkey-patches private _pytest API。
調用公共pytest.main()函數來運行py.test命令。
這個答案monkey-patches py.test的-s和--capture=no選項捕獲stderr而不是 stdout。 默認情況下,這些選項既不捕獲stderr也不捕獲stdout。 當然,這不是開球。 但是,每一次偉大的旅程都是從五年中每個人都忘記的乏味前傳開始的。
為什么這樣做? 我現在要告訴你。 我py.test驅動的testing套件包含慢速functiontesting。 顯示這些testing的標準輸出是有幫助和可靠的,防止leycec達到killall -9 py.test時,另一個長時間運行的functiontesting不能做任何事情,連續數周。 但是,顯示這些testing的stderr可以防止py.test在testing失敗時報告exception回溯。 這是完全無益的。 因此,我們強制py.test捕獲stderr而不是 stdout。
在我們開始之前,這個答案假定你已經有一個自定義的setuptools test命令調用py.test。 如果你不這樣做,請參閱py.test編寫良好的良好實踐頁面的手冊集成部分。
不要安裝pytest-runner ,第三方setuptools插件提供一個自定義的setuptools test命令,同時調用py.test。 如果已經安裝了pytest-runner,則可能需要卸載該pip3軟件包,然后采用上面鏈接的手動方法。
假設您按照上面強調的“ 手動積分”中的說明進行操作 ,那么您的代碼庫應該包含一個PyTest.run_tests()方法。 修改這個方法類似于:
class PyTest(TestCommand): . . . def run_tests(self): # Import the public "pytest" package *BEFORE* the private "_pytest" # package. While importation order is typically ignorable, imports can # technically have side effects. Tragicomically, that is the case here. # Importing the public "pytest" package establishes runtime # configuration required by submodules of the private "_pytest" package. # The former *MUST* always be imported before the latter. Failing to do # so raises obtuse exceptions at runtime... which is bad. import pytest from _pytest.capture import CaptureManager, FDCapture, MultiCapture # If the private method to be monkey-patched no longer exists, py.test # is either broken or unsupported. In either case, raise an exception. if not hasattr(CaptureManager, '_getcapture'): from distutils.errors import DistutilsClassError raise DistutilsClassError( 'Class "pytest.capture.CaptureManager" method _getcapture() ' 'not found. The current version of py.test is either ' 'broken (unlikely) or unsupported (likely).' ) # Old method to be monkey-patched. _getcapture_old = CaptureManager._getcapture # New method applying this monkey-patch. Note the use of: # # * "out=False", *NOT* capturing stdout. # * "err=True", capturing stderr. def _getcapture_new(self, method): if method == "no": return MultiCapture( out=False, err=True, in_=False, Capture=FDCapture) else: return _getcapture_old(self, method) # Replace the old with the new method. CaptureManager._getcapture = _getcapture_new # Run py.test with all passed arguments. errno = pytest.main(self.pytest_args) sys.exit(errno)
要啟用這個猴子補丁,運行py.test,如下所示:
python setup.py test -a "-s"
現在將捕獲Stderr但不是 stdout。 漂亮!
把上面的猴子補丁擴展到發球臺和stderr是一個充滿空閑時間的閱讀練習。