Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run checks at the start of tests #414

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 34 additions & 2 deletions pytest_django/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
from __future__ import with_statement

import os
import sys
from contextlib import contextmanager
from io import StringIO

import pytest

from contextlib import contextmanager

from . import live_server_helper

from .django_compat import is_django_unittest
Expand Down Expand Up @@ -97,6 +98,8 @@ def django_db_setup(
**setup_databases_args
)

run_checks(request)

def teardown_database():
with django_db_blocker.unblock():
teardown_databases(
Expand All @@ -108,6 +111,35 @@ def teardown_database():
request.addfinalizer(teardown_database)


def run_checks(request):
from django.core.management import call_command
from django.core.management.base import SystemCheckError

config = request.config

# Only run once per process
if getattr(config, '_pytest_django_checks_ran', False):
return
config._pytest_django_checks_ran = True

out = StringIO()
try:
call_command('check', stdout=out, stderr=out)
except SystemCheckError as exc:
config._pytest_django_checks_exc = exc

if hasattr(request.config, 'slaveinput'):
# Kill the xdist test process horribly
# N.B. 'shouldstop' may be obeyed properly in the future as hinted at in
# https://github.com/pytest-dev/pytest-xdist/commit/e8fa73719662d1be5074a0750329fe0c35583484
print(exc.args[0])
sys.exit(1)
else:
# Ensure we get the EXIT_TESTSFAILED exit code
request.session.testsfailed += 1
request.session.shouldstop = True


def _django_db_fixture_helper(transactional, request, django_db_blocker):
if is_django_unittest(request):
return
Expand Down
9 changes: 9 additions & 0 deletions pytest_django/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from .fixtures import django_username_field # noqa
from .fixtures import live_server # noqa
from .fixtures import rf # noqa
from .fixtures import run_checks # noqa
from .fixtures import settings # noqa
from .fixtures import transactional_db # noqa
from .pytest_compat import getfixturevalue
Expand Down Expand Up @@ -329,6 +330,14 @@ def pytest_runtest_setup(item):
_disable_class_methods(cls)


def pytest_terminal_summary(terminalreporter, exitstatus):
config = terminalreporter.config
check_exc = getattr(config, '_pytest_django_checks_exc', None)
if check_exc:
terminalreporter.write('\n')
terminalreporter.write(str(check_exc))


@pytest.fixture(autouse=True, scope='session')
def django_test_environment(request):
"""
Expand Down
59 changes: 59 additions & 0 deletions tests/test_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,65 @@ def test_set_non_existent(settings):
])


@pytest.mark.django_project(extra_settings="""
INSTALLED_APPS = ['tpkg.app']
""")
class TestChecks:

def test_checks_are_run(self, django_testdir):
django_testdir.create_app_file("""
from django.core.checks import Error, register

@register()
def succeed(app_configs, **kwargs):
succeed.did_run = True
return []
""", '__init__.py')
django_testdir.makepyfile("""
from tpkg.app import succeed

def test_simple(db):
assert getattr(succeed, 'did_run', None) is True
""")

result = django_testdir.runpytest_subprocess('-s')
assert result.ret == 0

def test_failing_checks_fail_tests(self, django_testdir):
django_testdir.create_app_file("""
from django.core.checks import Error, register

@register()
def fail(app_configs, **kwargs):
return [Error('My failure message', id='test.001')]
""", '__init__.py')
django_testdir.makepyfile("""
def test_simple(db):
assert True
""")

result = django_testdir.runpytest_subprocess('-s')
assert result.ret != 0
result.stdout.fnmatch_lines(['*My failure message*'])

def test_failing_checks_fail_tests_on_xdist(self, django_testdir):
django_testdir.create_app_file("""
from django.core.checks import Error, register

@register()
def fail(app_configs, **kwargs):
return [Error('My failure message', id='test.001')]
""", '__init__.py')
django_testdir.makepyfile("""
def test_simple(db):
assert True
""")

result = django_testdir.runpytest_subprocess('-s', '-n2')
assert result.ret != 0
result.stdout.fnmatch_lines(['*My failure message*'])


class TestLiveServer:
def test_url(self, live_server):
assert live_server.url == force_text(live_server)
Expand Down