58

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, Django flips out.

Is there a way to do what I'm trying to do or do I have to have all my tests in one file?

Jason Swett
  • 43,526
  • 67
  • 220
  • 351

5 Answers5

143

From version 1.6 of Django, the test discovery mechanism changed. You no longer need to import everything from tests/__init__.py, but now you have to make sure that all your files containing tests match the pattern test*.py.

So, instead of having app/tests/models.py and app/tests/views.py, now you should have app/tests/test_models.py and app/tests/test_views.py.

You could also create a file named app/tests/test.py and include your other files from there. The thing is that the runner will look for files matching the pattern test*.py and execute them.

Artur Soler
  • 2,974
  • 2
  • 23
  • 24
  • 12
    +1 for Django 1.6. Moreover the imports in `__init__.py` no longer work. – davekr Jan 07 '14 at 15:11
  • 2
    To add to this. Create tests/ folder add __init__.py (no imports) create tests/tests.py (and place the imports in there) That way you can leave of the test prefix of each test file. If thats preferred – McP Jan 11 '14 at 20:41
  • 3
    also make sure tests.py is removed when tests packages is being used – f3r3nc Apr 22 '14 at 14:16
  • 6
    I needed to create an (empty) `__init__.py` file in my `tests/` folder sothat Pylint doesn't show error about the views it can't resolve. – David Dahan Aug 13 '14 at 17:39
  • 3
    Reference: Django docs https://docs.djangoproject.com/en/1.8/topics/testing/overview/#running-tests – Wtower Jul 29 '15 at 13:52
  • How exactly do you "include your other files from there [test.py]?" Do you mean import them? – Jim Sep 02 '17 at 04:20
  • It looks like creating files matching `test*.py` isn't enough: they should match `test_*.py`? Thank you for your answer! EDIT actually most everything works, but not `test-*.py`? :shrug: – lmat - Reinstate Monica Apr 08 '21 at 18:47
17

Note: This describes behavior prior to Django 1.6. See Artur Soler's answer for Django 1.6 and later.

Make a package: myapp/tests/

Within the package, put as many different testing modules as you want. In the __init__.py within tests, import the tests from those modules. (Or some variation on this theme.)

edit: Wow, didn't notice you already mentioned a tests package.

The important thing is to get everything available from the package. Django will get the tests from the package, so they have to be visible in __init__.py.

[edit: Added note about Django version 1.6]

Community
  • 1
  • 1
dappawit
  • 12,182
  • 2
  • 32
  • 26
3

Just to add to Artur Soler's great answer...

You can also use the --pattern option to specify how your test files are named.

For example if your test files are named foo_test.py, bar_test.py and similar, you can use:

$ ./manage.py test --pattern="*_test.py"
Community
  • 1
  • 1
geckon
  • 8,316
  • 4
  • 35
  • 59
2

In your __init__.py put something like:

from foo_test import *
from bar_test import *
Evgeny
  • 6,533
  • 5
  • 58
  • 64
  • Does the package have to be registered with settings.py? – Darwin Tech Nov 06 '12 at 19:40
  • 1
    When you have a file called ```__init__.py``` then the folder will act as a module. As long as the folder's parent is in the ```sys.path``` for python then no extra "registration" in ```settings.py``` is required, just import and use. – Evgeny Nov 07 '12 at 10:21
  • I setup a test package in my app and in the `__inti__.py` I imported two modules - `tests.py` and `selenium_tests.py`. But how can I elect to run just the selenium tests? I tried `./manage.py test myapp.selenium_tests` or `./manage.py test myapp.tests.slenium_tests` but it doesn't recognize them. – Darwin Tech Nov 07 '12 at 17:28
  • You probably don't need to add ```myapp.```, and in general re-check your syntax for errors. – Evgeny Nov 07 '12 at 20:42
  • I think the `myapp` is necessary as I have `selenium_tests.py` in other apps. So any idea how I would select just the `selenium_tests` for a specific app? – Darwin Tech Nov 07 '12 at 21:06
  • In order to run it like `./manage.py test myapp.tests.selenium_tests` I think you would have to create a `selenium_tests` package rather than file... – ilovett Dec 11 '13 at 00:19
0

As @artur-soler explained,

Let's say you have an app named "AppName":

AppName tests

Your __init__.py inside the tests folder should consists of something like -

from AppName.tests import *
Matan Dobrushin
  • 107
  • 1
  • 10