djangodjango-adminpytestpytest-djangodjango-management-command

How to call pytest-django from python manage.py test?


I have made my custom management command called pytest_wrp

So when I call

python manage.py test

This bit of code is called:

class Command(test.Command):

    def handle(self, *args, **options):
        super(Command, self).handle(*args, **options) # this calls the python manage.py test
        self.stdout.write("My code starts from here.")
        management.call_command(pytest_wrp.Command(), '--pact-files="{argument}"'.format(argument=path_to_file), '--pact-provider-name="MyService"', verbosity=0)

The pytest_wrp basically has this code in it:

class Command(BaseCommand):
    help = "Runs tests with Pytest"

    def add_arguments(self, parser):
        parser.add_argument("args", nargs=argparse.REMAINDER)

    def handle(self, *args, **options):
        pytest.main(list(args)) # This doesn't accept the pact args, even if you specify a "--" separator

But this calls pytest not pytest-django Hence the extra arguments that I am passing don't get recognized and pytest can't start the test suite.

I wanna pass the extra arguments for some of the test cases. If there is some way to call pytest-django directly and pass the extra arguments in code that would be optimal.


Solution

  • I found my solution here: Can I still use `manage.py test` after switching to django-pytest? and for full and comprehensive documentation you need to see this. To put it simply, you need to override the config/test.py or config.py depending how your app was setup

    TEST_RUNNER = "your_project.your_app.runner"
    

    And your runner.py would look something like this

    class PytestTestRunner(object):
        """Runs pytest to discover and run tests."""
    
        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')
    
            # NOTE: You don't need to quote the argument value here, they do some weird string pattern matching internally
            argv.append('--pact-files={argument}'.format(argument=path_to_file)) 
            argv.append('--pact-provider-name=MyService')
            argv.extend(test_labels)
            return pytest.main(argv)
    

    Please make sure you have pytest-django package

    pip install pytest-django