2014-02-15 23 views
1

我有自定義的fixture,它在測試過程中收集有關DB查詢的信息,並且在測試失敗的情況下使用該fixture,我想添加fixture收集的信息來報告。我怎樣才能做到這一點?如何修改特定測試的故障報告

UPDATE

如何,它看起來像:

from contextlib import contextmanager 
import db 
import pytest 

def make_cursor_handler(): 
    ... 
    return cursor_handler, list_with_log 

@contextmanager 
def wrap_cursor(): 
    old_handler = db.cursor_handler 
    db.cursor_handler, list_with_log = make_cursor_handler() 
    yield list_with_log 
    db.cursor_handler = old_handler 

@pytest.yield_fixture 
def cursor_fixture(): 
    with wrap_cursor() as log: 
     yield log #How would I print it inside error report without including it in assert message? 
+0

如果可以的話請給一些更多的細節。 –

回答

4

可以使用pytest-capturelog捕獲的測試中寫的所有日誌信息,包括安裝和拆卸過程中。所以,無論你登錄的是你的報告的一部分,這可能是非常有用的(我們確實在公司使用它,雖然我們使用鼻子,它沒有任何插件AFAIK處理它)。

pip install pytest-capturelog 

然後你就可以在測試過程中任何地方登錄消息(安裝,拆卸,夾具,在輔助功能),pytest-capturelog應當予以受理:

import logging 

log = logging.getLogger(__name__) 

def setup_function(function): 
    log.info("setup log message") 

def test_it(): 
    log.info("test log message") 
    assert False 

結果(見Captured log):

==================== test session starts ===================== 
platform linux2 -- Python 2.7.4 -- py-1.4.20 -- pytest-2.5.2 
plugins: capturelog 
collected 1 items 

file.py F 

========================== FAILURES ========================== 
__________________________ test_it ___________________________ 

    def test_it(): 
     log.info("test log message") 
>  assert False 
E  assert False 

file.py:10: AssertionError 
------------------------ Captured log ------------------------ 
file.py      6 INFO  setup log message 
file.py      9 INFO  test log message 
================== 1 failed in 0.01 seconds ================== 
+0

輸出正是我所需要的。如果沒有外部插件,我會接受這種解決方案。 –

+0

雖然這肯定會起作用,有什麼理由不能在夾具中使用'print'msg「'而不是使用日誌?當測試失敗(並且不需要額外的插件)時,這將出現在捕獲的stdout節中。 – flub

+0

打印不會給你像文件,行和日誌級別的日誌上下文。小項目通常可以,但不適用於更復雜的項目。行爲良好的第三方庫(請求,django,...)無論如何都在使用日誌記錄,因此您將丟失所有相關信息。 –

1

您可以使用附加信息調用報告標題,還是讓您的定製夾具打印附加信息?它看起來像他們在pytest.org上給出的例子。

報告標題代碼here

def pytest_report_header(config): 
    return "Additional Information here" 

夾具代碼here

如果您發佈的代碼,我認爲我們可以更好地解決。

@pytest.fixture 
def something(request): 
    def fin(): 
     # request.node is an "item" because we use the default 
     # "function" scope 
     if request.node.rep_setup.failed: 
      print "setting up a test failed!", request.node.nodeid 
     elif request.node.rep_setup.passed: 
      if request.node.rep_call.failed: 
       print "executing test failed", request.node.nodeid 
    request.addfinalizer(fin) 
0

打印作品,但它不是很靈活。如果你真的想要隔離你的測試的輸出並且不想看到其他東西,這真是太好了。如果您有興趣查看來自應用程序的各種軟件包和組件(django,httplib等)的錯誤,那麼您希望使用日誌記錄。

要在沒有插件的測試報告中獲取日誌輸出,只需設置日誌輸出到stdout/stderr;這基本上將日誌調用轉換爲超強打印調用。然後,如果在沒有-s開關的情況下運行pytest ,則會將輸出添加到測試結果中。

以下是如何配置日誌記錄;務必儘早執行!

import logging 
from sys import stdout, stderr 

# this is our root logger, give it the name you want 
log = logging.getLogger("myScript") 

# prevents adding the same handlers over and over again if your script is read multiple times 
if not len(log.handlers): 
    log.setLevel(logging.DEBUG) 
    # we are setting a file log, and also redirecting to stdout/stderr 
    logger_file_handler = logging.FileHandler('myScript.debug.log') 
    console_flow_handler = logging.StreamHandler(stdout) 
    console_error_handler = logging.StreamHandler(stderr) 
    # set their levels. file gets all, console gets info and up, stderr gets warnings and up 
    logger_file_handler.setLevel(logging.DEBUG) 
    console_flow_handler.setLevel(logging.INFO) 
    console_error_handler.setLevel(logging.WARNING) 
    # ok, add them! 
    log.addHandler(logger_file_handler) 
    log.addHandler(console_flow_handler) 
    log.addHandler(console_error_handler) 
    # don't propagate messages to parent (root), else we get duplicates - this may or may not fit your situation 
    log.propagate = False 

然後在您的測試,你可以這樣做:

import logging; log = logging.getLogger("myScript.TestName") 

def test_something(): 
    log.debug("This only goes into the log file") 
    log.info("This will be printed to console too") 
    log.warning("This goes to stdout and stderr - pytest will print stderr into its own section so that you can see them quickly") 
    assert 0 # if it fails, you get the logs. if it pass, you get nothing.