Invoking django tests in subdirectories - django

I recently split up an app into subdirectories. For example, I had a "shop" app, and I split it up into shop/foo, shop/bar, shop/baz subdirectories, treating each one as a separate app, so my INSTALLED_APPS now looks like:
"shop",
"shop.foo",
"shop.bar",
"shop.baz",
...
I want to be able to run the tests in shop/foo/tests.py by doing:
python manage.py test shop.foo
However, if I do that, I get the error:
ValueError: Test label 'shop.foo' does not refer to a test
On the other hand, I can run the tests by doing this:
python manage.py test foo
Why is this happening, and what can I change so that I can run the tests as "shop.foo" instead of "foo"?

This is because Django expects the arguments to test command to be of the format:
app_label[.TestCase[.test_method]]
There is no way of doing this with the stock test runner (see, Carl Meyers comment). If everything goes well, this should be fixed in Django 1.5, but in the meantime you can use an alternate runner which accepts full module paths: django-discovery-runner.

django-discover-runner has been made part of Django 1.6.. :)
For Version <1.6 , it can be used as a third party app.

Related

using unittest.skip with django-jenkins

I have added #unittest.skip decorator for few of my test methods. It works as expected while running with python manage.py test --settings=PATH_TO_SETTING
But it does not work with python manage.py jenkins --settings=PATH_TO_SETTING
I read that I need to add JENKINS_TEST_RUNNER to settings file but I am not aware of how to add that class.
How can I make it work with jenkins ?
Adding the JENKINS_TEST_RUNNER is not solving the problem.
it can be added as
JENKINS_TEST_RUNNER = 'django_jenkins.runner.CITestSuiteRunner'
I solved the problem by setting the name attribute explicitly on the classes in whose test functions i am using unittest.skip

Testing backend code in Django

I am writing an authentication back-end in Django to log only a few users.
It is in a folder called restrictedauthentification/ which is at the root of my Django Project. (I am written it down for a specific project.)
It has two files in it : backend.py and tests.py
In the last file, I have written down some tests for it.
But I can't run them with command ./manage.py test because it isn't an installed app.
Any ideas how I could run them ?
Okay, I found a solution that keep me from turning my backend into a module.
Somthing that I didn't understand and that could help some beginners : In python, a test cannot run itself. It need to be executed by a TestRunner.
Now, one could use the TextTestRunner bundled python that execute the tests and show the results on the standard output, but when testing with django, one need to do one thing before and after the test: calling the function setup_test_environment() and teardown_test_environment().
So I just created a class that inherit from TextTestRunner and redefine its methode run() in order that it execute the two functions provided by Django.
Here it is :
from restrictedauthentification.tests import TestRestrictedAuthentification
from django.test.utils import setup_test_environment, teardown_test_environment
from unittest import TextTestRunner
class DeadSimpleDjangoTestRunner(TextTestRunner):
def run(self, test):
setup_test_environment()
super().run(test)
teardown_test_environment()

How to run a single test or single TestCase with django-nose?

With Django's normal test runner, you can drill down to run tests in a specific app, a specific subclass of TestCase, or a specific test within a specific subclass of TestCase.
E.g.:
./manage.py test myapp.MyTestCase.test_something
However, django-nose doesn't appear to support anything beyond testing a specific app. How do I replicate the last two behaviors?
Nose supports the following syntax (note : between test script name and test class name):
./manage.py test myapp.tests.test_script:MyTestCase.test_method
The correct answer is ./manage.py test myapp/tests/test_script:MyTestCase.test_method.
Using dots in the relative path did not work for me, but slashes did.

nose does not discover unit tests using load_tests

Python 2.7.1
Nose 1.1.2
I have read related questions on this but they do not help. I have Test cases that look like the below
For example in my_tests.py
def load_tests(loader, tests, pattern):
return unittest.TestSuite(MyTest() for scenario_name in list)
I have several such modules with load_tests method and I run them using unittest as follows
test_loader = unittest.defaultTestLoader.discover( '.', my_pattern_var);
test_runner = unittest.TextTestRunner();
result = test_runner.run(test_loader)
sys.exit(not result.wasSuccessful())
If I replace this with the equivalent nose code nose.main() it finds 0 tests.
Questions
How do I get nose to discover tests? WITHOUT actually losing the ability to just run my tests using python unittest. I would like to use NOSE as an addon to python unittest to get clover and coverage reports
How do I get it to run tests matching only a specific pattern?
sorry for getting back so late. We basically did the same thing you're trying to do here for a console script except we named all of our test modules integration_foo.py. Anyhow the solution is straightforward, just run nose programmatically.
import re
from nose.config import Config
TEST_REGEX = '(?:^|[\\b_\\./-])[Ll]oad'
# Change the test match pattern
nose_config = Config()
nose_config.testMatch = re.compile(TEST_REGEX)
# Specify the use of a Plugin Manager, load plugins
nose_config.plugins = BuiltinPluginManager()
nose_config.plugins.loadPlugins()
run(config=nose_config)
So this basic option changes the regex pattern nose is looking for from all methods labeled test to all methods labeled load. However this is not what you would need completely to run nose, it is also necessary to get some kind of parser object or pass a specific set of argv to nose.
If you want to pass a specific set of argv to be parsed by nose just do
run(config=nose_config, argv=["foo", "bar"])
Otherwise you can probably specify nose specific arguments at the command line and as long as you don't throw in anything funky nose shouldn't error.
Check out the nose source code at https://github.com/nose-devs/nose/tree/master/nose its where I got all the information I needed to write this

Django Unit Test fails project-wide but passes app-wide

I'm using Django 1.4 with Python 2.7 on Ubuntu 12.10.
I have a project with several apps and dozens of unit tests. We've recently run into a little issue using the #override_settings decorator.
Here is some code:
#override_settings(MEDIA_URL='/test/media/')
def test_get_content_dict(self):
self.assertEqual(
self.offer.get_content_dict(),
{ 'some stuff': some stuff }
When tests are run at the app level everything passes.
python manage.py test my_app --settings=proton.settings.test
But when we run at the project level it fails.
python manage.py test --settings=proton.settings.test
It's failing due to some stuff using /test/media but the model method offer.get_contect_dict() using /media, which is our actual MEDIA_URL.
We can change the MEDIA_URL in our settings/test.py file, but that would require all tests to use /test/media (which might be a good idea anyway).
Clearly the problem is in Django's core.files.storage.FileSystemStorage.__init__() - it sets the base_url earlier in the test suite but does not re-instantiate the object after each test (for obvious reasons) so the #override_settings doesn't actually do anything.
Is this a bug or is this working as intended? Any suggestions to an elegant solution other than forcing all unit tests to use /test/media by setting our MEDIA_URL constant in our settings/test.py to /test/media?