В py.test можно ли сообщать произвольные значения, сгенерированные в тестовых прогонах? - PullRequest
1 голос
/ 06 июня 2019

Я знаю, что есть плагины для тестов производительности и профилирования для py.test, но есть ли способ генерировать произвольные значения, которые сообщаются или каким-то образом доступны после теста?

Представьте, что у меня есть такой тест

def test_minimum_learning_rate():
    """Make some fancy stuff and generate a learning performance value"""
    learning_rate = fancy_learning_function().rate
    pytest.report("rate", learning_rate)
    assert learning_rate > 0.5

Строка pytest.report(..) - это то, что я бы хотел бы иметь (но не там ли, не так ли?)

А теперь я бы хотелчтобы что-то вроде minimum_learning_rate[rate] было записано вместе с фактическими результатами теста в отчет (или, по крайней мере, на экране).

Действительно nice - это какой-то плагин для Jenkins, который создает из этих данных хороший график.

Есть ли типичная формулировка для этого?Я искал kpi, arbitrary values, user defined values, но пока без удачи ..

1 Ответ

2 голосов
/ 07 июня 2019

Если вы просто хотите вывести некоторые значения отладки, вызова print в сочетании с аргументом -s будет достаточно:

def test_spam():
    print('debug')
    assert True

Бег pytest -s:

collected 1 item                                                                                                                                                                                                  

test_spam.py debug
.

Если вы ищете решение, которое лучше интегрируется в pytest поток выполнения, напишите пользовательские хуки. Приведенные ниже примеры должны дать вам некоторые идеи.

Печать пользовательских строк после каждого выполнения теста

# conftest.py

def pytest_report_teststatus(report, config):
    if report.when == 'teardown':  # you may e.g. also check the outcome here to filter passed or failed tests only
        rate = getattr(config, '_rate', None)
        if rate is not None:
            terminalreporter = config.pluginmanager.get_plugin('terminalreporter')
            terminalreporter.ensure_newline()
            terminalreporter.write_line(f'test {report.nodeid}, rate: {rate}', red=True, bold=True)

Тесты:

def report(rate, request):
    request.config._rate = rate

def test_spam(request):
    report(123, request)

def test_eggs(request):
    report(456, request)

Выход:

collected 2 items                                                                                                                                                                                                 

test_spam.py .
test test_spam.py::test_spam, rate: 123

test_spam.py .
test test_spam.py::test_eggs, rate: 456
===================================================== 2 passed in 0.01 seconds =====================================================

Сбор данных и печать после выполнения теста

# conftest.py

def pytest_configure(config):
    config._rates = dict()

def pytest_terminal_summary(terminalreporter, exitstatus, config):
    terminalreporter.ensure_newline()
    for testid, rate in config._rates.items():
        terminalreporter.write_line(f'test {testid}, rate: {rate}', yellow=True, bold=True)

Тесты:

def report(rate, request):
    request.config._rates[request.node.nodeid] = rate

def test_spam(request):
    report(123, request)

def test_eggs(request):
    report(456, request)

Выход:

collected 2 items                                                                                                                  

test_spam.py ..

test test_spam.py::test_spam, rate: 123
test test_spam.py::test_eggs, rate: 456
===================================================== 2 passed in 0.01 seconds =====================================================

Добавление данных в отчет JUnit XML

Использование приспособления record_property:

def test_spam(record_property):
    record_property('rate', 123)

def test_eggs(record_property):
    record_property('rate', 456)

Итоговый отчет:

$ pytest --junit-xml=report.xml
...
$ xmllint --format report.xml
<testsuite errors="0" failures="0" name="pytest" skipped="0" tests="2" time="0.056">
  <testcase classname="test_spam" file="test_spam.py" line="12" name="test_spam" time="0.001">
    <properties>
      <property name="rate" value="123"/>
    </properties>
  </testcase>
  <testcase classname="test_spam" file="test_spam.py" line="15" name="test_eggs" time="0.001">
    <properties>
      <property name="rate" value="456"/>
    </properties>
  </testcase>
</testsuite>
...