How to spread django unit tests over multiple files?

Related searches
  • I have a python-django application
  • I'm using the unit testing framework
  • The tests are arranged in the file "tests.py" in the module directory
  • I'm running the tests via ./manage.py test app

Now..

  • The tests.py file is getting rather large/complex/messy
  • I'd like to break tests.py up into smaller collections of tests...

How?

The behavior has changed in Django 1.6, so there is no longer a need to create a package. Just name your files test*.py.

From Django 1.7 documentation

When you run your tests, the default behavior of the test utility is to find all the test cases (that is, subclasses of unittest.TestCase) in any file whose name begins with test, automatically build a test suite out of those test cases, and run that suite.

From Django 1.6 documentation,

Test discovery is based on the unittest module’s built-in test discovery. By default, this will discover tests in any file named "test*.py" under the current working directory.

Previous behavior, from Django 1.5 documentation:

When you run your tests, the default behavior of the test utility is to find all the test cases (that is, subclasses of unittest.TestCase) in models.py and tests.py, automatically build a test suite out of those test cases, and run that suite.

There is a second way to define the test suite for a module: if you define a function called suite() in either models.py or tests.py, the Django test runner will use that function to construct the test suite for that module. This follows the suggested organization for unit tests. See the Python documentation for more details on how to construct a complex test suite.

How to spread django unit tests over multiple files? - django - iOS, I have a python-django application I'm using the unit testing framework The tests are arranged in the file "tests.py" in the module directory I'm running the tests� Right now I have my Django unit tests living at mcif/tests.py. I would prefer to have something more like mcif/tests/foo_test.py, mcif/tests/bar_test.py, etc., but if I organize my tests that way,

Note that this approach is no longer valid from Django 1.6, see this post.

You can create tests folder with ___init___.py inside (so that it becomes a package). Then you add your split test .py files there and import all of them in ___init___.py.

I.e: Substitute the test.py file with a module that looks and acts like the file:

Create a tests Directory under the app in question

app
app\models.py
app\views.py
app\tests
app\tests\__init__.py
app\tests\bananas.py
app\tests\apples.py

Import the submodules into app\tests\__init__.py:

from bananas import *
from apples import *

Now you can use ./manage.py as if they were all in a single file:

./manage.py test app.some_test_in_bananas

How to spread django unit tests over multiple files?, I have a python-django application I'm using the unit testing framework The tests are arranged in the file. I just moved tests.py file to a new directory called tests, then I added __init__.py file therein, but as I run the test python manage.py test it says ran 0 tests in 0.000s. How to solve it? I don't know how to show my files like most do, but here is an image! This app is also added in settings.py Thanks. edit: this is a sample of test_models.py

The answer as stated by Tomasz is correct. However, it can become tedious to ensure that the imports in __init__.py match your file structure.

To automatically detect all tests in the folder you can add this in __init__.py:

import unittest

def suite():   
    return unittest.TestLoader().discover("appname.tests", pattern="*.py")

This will allow you to run ./manage.py test appname but won't handle running specific tests. To do that you can use this code (also in __init__.py):

import pkgutil
import unittest

for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(module_name).load_module(module_name)
    for name in dir(module):
        obj = getattr(module, name)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            exec ('%s = obj' % obj.__name__)

Now you can run all your tests via manage.py test app or specific ones via manage.py test app.TestApples

Splitting Our Tests into Multiple Files, and a Generic Wait Helper, Extend the FT to a Second User, and the "My Lists" Page � 25.4. Let's split it out into several files, in which each has a single test method. import os from django .contrib.staticfiles.testing import from selenium.webdriver.common.keys import Keys from unittest import skip from .base import FunctionalTest� Writing tests¶. Django’s unit tests use a Python standard library module: unittest.This module defines tests using a class-based approach. Here is an example which subclasses from django.test.TestCase, which is a subclass of unittest.TestCase that runs each test inside a transaction to provide isolation:

Just make your directory structure like this:

myapp/
    __init__.py
    tests/
        __init__.py
        test_one.py
        test_two.py
        ...
    ...

And python manage.py test myapp will work as expected.

Advanced testing topics | Django documentation, The following is a unit test using the request factory: If you're testing a multiple database configuration with primary/replica (referred to as master/slave by� Unit Testing C Code ; Is Unit Testing worth the effort? JavaScript unit test tools for TDD ; What is Unit test, Integration Test, Smoke test, Regression Test? Running unittest with typical test directory structure ; How to spread django unit tests over multiple files?

http://docs.python.org/library/unittest.html#organizing-tests talks about splitting the files into modules, and the section right above it has an example.

Writing and running tests | Django documentation, TestCase ) in any file whose name begins with test , automatically build a test suite out of those test cases, and run that suite. For more details about unittest , see� Since Django 1.6 you can run a complete test case, or single test, using the complete dot notation for the element you want to run. Automatic test discovery will now find tests in any file that starts with test under the working directory, so addressing the question you would have to rename your files, but you can now keep them inside the directory you want.

Introduction to Python/Django tests: Fixtures¶ In the first two posts of this series, we talked about how to get the basic infrastructure for your tests up and running. You should have a file with doc tests and one with unit tests. They should be linked into your django project with an __init__.py file. If you were feeling adventurous you may

request.session is a dictionary like any other, so you just use the normal template mechanism for attributes and members: {{ request.session.name }} Don’t forget to pass the request into the template context, or even better ensure you are using RequestContext and have the request context processor enabled.

If the directory contains tests that belong to the different testing frameworks, select the configuration to be used. For example, select Run pytest in <directory name>'. Explore results in the test runner. For Django versions 1.1 and later, PyCharm supports custom test runner, if this test runner is a class.

Comments
  • In django 2.6 it doesn't really discover anything…
  • Currently using Django 1.10, I wanted to put all my test*.py files in a folder called tests to keep the folder clean - this is possible, but you must run ./manage.py test app.tests and all relative imports need to go up a level (from .models becomes from ..models).
  • Doh. You meant create a 'tests' module under the application I'm testing; not a new application called tests. I get it now. Awesome. Thanks!
  • @John: I can't recognize my answer anymore! :-) But you are completely right that it was too vague, even if correct - your examples make it clear, contrary to my original wording.
  • @Tomasz.. Your words are still there - wholly intact. I just fleshed it out a little since you put me on the right track.
  • @John: I wasn't angry at all if that's what you mean :) It was just funny to see my own answer in a bit different shape
  • @jMyles, if by "regular django test runner" you mean python manage.py test myapp then in fact this answer does work just fine. (just tried it)
  • Where do you place the second piece?
  • Both pieces go into __init__.py
  • Note that if any of your test package names coincide with top level module names which get imported during the test run, the pkgutil snippet will cause the import to fail because the tests get added as sys.modules[packagename]. A quick workaround is to del any that cause problems after the above. (Or you could rename your folders ;) )
  • This is great but I ran into an error where, when running an app level test (python manage.py test appName) the second bit of code would throw an error stating that __path__ was not available. I avoided it by wrapping the second snippet in a if '__path__' in locals(): check, which did the trick. Thanks for the answer!
  • +1 this also ensures that the init file adheres to common coding standards, i.e. does not have * or unused imports
  • The 'bit extra' I'm looking for, over rtfm, is the django settings environment, database, and fixtures for the tests.
  • Why can you not call it something that starts with "tests"?
  • I'm using this answer with Django 1.11.4. Reasons to use it: (1) The file "app/testing/__init__.py" remains empty and (2) The command remains the basic "python manage.py test app"