#django #pytest #pytest-django
Вопрос:
Я пишу приложение django. Я пытаюсь выполнить unittest и pytest с охватом. И в зависимости от того, как я провожу тесты, я получаю разные отчеты о покрытии.
Соответствующий Код
У меня есть это в settings_test.py , бегун для pytest:
class PytestTestRunner(UnManagedModelTestRunner):
def __init__(self, verbosity=1, failfast=False, keepdb=False, **kwargs):
self.verbosity = verbosity
self.failfast = failfast
self.keepdb = keepdb
def run_tests(self, test_labels):
"""Run pytest and return the exitcode.
It translates some of Django's test command option to pytest's.
"""
import pytest
argv = []
if self.verbosity == 0:
argv.append('--quiet')
if self.verbosity == 2:
argv.append('--verbose')
if self.verbosity == 3:
argv.append('-vv')
if self.failfast:
argv.append('--exitfirst')
if self.keepdb:
argv.append('--reuse-db')
argv.extend(test_labels)
return pytest.main(argv)
TEST_RUNNER = "settings_test.UnManagedModelTestRunner"
А также этот скрипт для запуска тестов:
runner.py
USAGE = """
USAGE:
python runner.py (will run unittest suite)
python runner.py unittest (will run unittest suite)
python runner.py pytest (will run pytest suite coverage)
"""
TEST_RUNNERS_MAP = {
'pytest': 'testapp.settings_test.PytestTestRunner', # pytest
'unittest': 'testapp.settings_test.UnManagedModelTestRunner', # unittest
}
if __name__ == "__main__":
os.environ['DJANGO_SETTINGS_MODULE'] = 'testapp.settings_test'
django.setup()
# Get argument to decide which test suite to run.
arguments = sys.argv[1:]
arg = arguments[0] if 0 < len(arguments) else "unittest"
runner = TEST_RUNNERS_MAP[arg]
TestRunner = get_runner(settings, test_runner_class=runner)
test_runner = TestRunner()
failures = test_runner.run_tests(["unit_tests"])
sys.exit(bool(failures))
Тестовые запуски
$ pytest
Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------------------------------------------
api/apps.py 4 0 0 0 100%
api/models/enum_model_base.py 25 10 2 0 56% 14,28,31
api/models/ingredient.py 11 0 0 0 100%
api/models/model_base_with_timestamp.py 6 0 0 0 100%
api/routes.py 5 0 0 0 100%
api/serializers/ingredients.py 6 6 0 0 0% 1-9
api/urls.py 5 5 0 0 0% 1-7
api/views/view_set_base.py 55 55 10 0 0% 1-123
api/views/ingredients.py 6 6 0 0 0% 1-9
------------------------------------------------------------------------------------------------
TOTAL 123 82 12 0 30%
FAIL Required test coverage of 100.0% not reached. Total coverage: 30.37%
I think with the next one the only difference is urls file.
$ coverage run runner.py unittest
$ coverage report
Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------------------------------------------
api/apps.py 4 0 0 0 100%
api/models/enum_model_base.py 25 10 2 0 56% 14,28,31
api/models/ingredient.py 11 0 0 0 100%
api/models/model_base_with_timestamp.py 6 0 0 0 100%
api/routes.py 5 0 0 0 100%
api/serializers/ingredients.py 6 6 0 0 0% 1-9
api/urls.py 5 0 0 0 100%
api/views/view_set_base.py 55 55 10 0 0% 1-123
api/views/ingredients.py 6 6 0 0 0% 1-9
But if I run pytest from the script. Most of them are at 0%
$ python runner.py pytest
Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------------------------------------------
api/apps.py 4 4 0 0 0% 1-6
api/models/enum_model_base.py 25 25 2 0 0% 1-57
api/models/ingredient.py 11 11 0 0 0% 1-14
api/models/model_base_with_timestamp.py 6 6 0 0 0% 1-13
api/routes.py 5 0 0 0 100%
api/serializers/ingredients.py 6 6 0 0 0% 1-9
api/urls.py 5 5 0 0 0% 1-7
api/views/view_set_base.py 55 55 10 0 0% 1-123
api/views/ingredients.py 6 6 0 0 0% 1-9
------------------------------------------------------------------------------------------------
TOTAL 123 118 12 0 4%
FAIL Required test coverage of 100.0% not reached. Total coverage: 3.70%