Django 1.6 test discovery cannot find test modules - django

Django 1.6.10 cannot find test modules located outside my apps when running any of these code (ref: https://docs.djangoproject.com/en/1.6/topics/testing/overview/#running-tests)
./manage.py test tests/app1/
./manage.py test tests/app1/test_views
I keep getting these errors
django.core.exceptions.ImproperlyConfigured: App with label tests/app1/ could not be found
django.core.exceptions.ImproperlyConfigured: App with label tests/app1/test_views could not be found
Here is my project structure:
- project
- app1
- __init__.py
- models.py
- views.py
- forms.py
- admins.py
- app2
- ..as per above
- tests
- __init__.py (blank)
- app1
- __init__.py (blank)
- test_views.py
- test_forms.py
- app2
- __init__.py (blank)
- test_views.py
- test_walkthrough.py
I read Django Discovery runner a few times and still cannot find out where did I go wrong. Any help please - what do I miss
Replacing / with . gives the same error however when execute
./manage.py test tests.app1.test_views.MyTestCase
./manage.py test tests.app1.test_views.MyTestCase.test_mymethod
I get ValueError.
ValueError: Test label 'tests.app1.test_views.MyTestCase.test_mymethod' should be of the form app.TestCase or app.TestCase.test_method
Further update:
I finally got it to work when adding --testrunner='django.test.runner.DiscoverRunner' to the command line. As per Django doc, any of these patterns works now (using / is a way of providing a path to a directory to discover tests below that directory):.
./manage.py test --testrunner='django.test.runner.DiscoverRunner' tests.app1
./manage.py test --testrunner='django.test.runner.DiscoverRunner' tests.app1.test_views.MyTestCase
./manage.py test --testrunner='django.test.runner.DiscoverRunner' tests/app1/
Still do not know why I have to provide --testrunner value. I am using Mezzanine in my code too and have double confirmed that settings.TEST_RUNNER is pointing to django.test.runner.DiscoverRunner
Can anyone help explaining why do I need --testrunner flag in django 1.6? Thank you in advance.

You should be referring to them as modules, not paths:
./manage.py test tests.app1
./manage.py test tests.app1.test_views
Read more about running tests in the docs.

Related

Django 2.1.7: Makemigrations command result: "No change detected in app"

(I am aware that a number of Django users have had the same issue.
I have looked at a number of solutions online but none has worked for me so far.)
I have set up my apps.py, settings.py and models.py files as explained in Django official tutorial (please see the 3 files below).
When I enter in the terminal:
$ python3 manage.py makemigrations munichliving_app
It returns:
No changes detected in app 'munichliving_app'
(file settings.py) in INSTALLED_APP --> I added and tested both one at a time:
'munichliving_app' and
'munichliving_app.apps.MunichLivingConfig'
apps.py file: https://pastebin.com/raw/qaYy1x44
setting.py file: https://pastebin.com/raw/cSsbfPsx
models.py: https://pastebin.com/raw/U0QeM16k
Django official tutorial states that I should see something along the lines of:
Migrations for 'polls':
polls/migrations/0001_initial.py:
- Create model Choice
- Create model Question
- Add field question to choice
Thank you.
Your app is munichliving (the module that contains models.py), but you have munichliving_app in your INSTALLED_APPS setting. The munichlivin_app is the project folder (the one that contains settings.py). It doesn't normally contain models so you shouldn't usually have to add it to INSTALLED_APPS or make migrations for it.
Replace 'munichliving_app' with 'munichliving' in your INSTALLED_APPS.
Next, I would remove your apps.py because it doesn't appear to be used. If you do keep it, then change it to name='munichliving', then use'munichliving.apps.MunichLivingConfig'inINSTALLED_APPS`.
Finally, create migrations with
./manage.py makemigrations munichliving
Try this:
python manage.py migrate --fake appname
Or delete the migration folder in your app, go to the database and delete the file in django_migrations table, then migrate again:
python manage.py makemigrations
python manage.py migrate

How can I store 3rd party package migrations in a Django project?

I'm using the page module in feincms and when I add extensions to my settings I'd like to be able to store the migrations in my git repo.
There is some documentation on migrations in FeinCMS, but it looks incomplete, and I'm not able to get this working.
The file structure I have is:
- app
- feincms_
- migrate
- __init__.py
...
...
settings.py
...
MIGRATION_MODULES = {
'page': 'feincms_.migrate.page',
'medialibrary': 'feincms_.migrate.medialibrary',
}
...
Ok, silly me. I needed a directory with an __init__.py for each module.
i.e.
- app
- feincms_
- migrate
- __init__.py
- page
- __init__.py
- medialibrary
- __init__.py
...
...
So to sum this up, in order to set the location for any module's migrations in Django, you have to specify a valid python path in MIGRATION_MODULES. This path can be anywhere you like, but you have to make sure that it exists.

uwsgi and flask - cannot import name "appl"

I created several servers, without any issue, with the stack nginx - uwsgi - flask using virtualenv.
with the current one uwsgi is throwing the error cannot import name "appl"
here is the myapp directory structure:
/srv/www/myapp
+ run.py
+ venv/ # virtualenv
+ myapp/
+ init.py
+ other modules/
+ logs/
here is the /etc/uwsgi/apps-avaliable/myapp.ini
[uwsgi]
# Variables
base = /srv/www/myapp
app = run
# Generic Config
# plugins = http, python
# plugins = python
home = %(base)/venv
pythonpath = %(base)
socket = /tmp/%n.sock
module = %(app)
callable = appl
logto = %(base)/logs/uwsgi_%n.log
and this is run.py
#!/usr/bin/env python
from myapp import appl
if __name__ == '__main__':
DEBUG = True if appl.config['DEBUG'] else False
appl.run(debug=DEBUG)
appl is defined in myapp/ _ init _ .py as an instance of Flask()
(underscores spaced just to prevent SO to turn them into bold)
I accurately checked the python code and indeed if I activate manually the virtualenvironment and execute run.py manually everything works like a charm, but uwsgi keeps throwing the import error.
Any suggestion what should I search more ?
fixed it, it was just a read permissions issue. The whole python app was readable by my user but not by the group, therefore uwsgi could not find it.
This was a bit tricky because I deployed successfully many time with the same script and never had permissions issues

Django is ignoring my TestCase fixtures

I've got Django 1.4. In my test.py, I've got the requisite TestCase import:
from django.test import TestCase
To isolate the issue, I've added the line:
fixtures = ['westeros']
to the default example test case, i.e.
class SimpleTest(TestCase):
fixtures = ['westeros']
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)
Using django-admin.py dumpdata, I created a fixture file called "westeros" in my customers/fixtures directory, where "customers" is an app that is listed in settings.INSTALLED_APPS.
When I run the test, at any verbosity, Django simply ignores the fixture and passes the test_basic_addition test. No error, no fixture loading. It's as if the TestCase import isn't there. Any ideas on what could be wrong or how to debug this?
It's ok to omit the extension when defining fixtures as you have done, i.e.
fixtures = ['westeros']
However, the fixture file itself must have the extension that corresponds to its serializer e.g westeros.json, westeros.json.zip or westeros.xml for json, zipped json or xml respectively.
Where is your westeros file located?
It needs to either be in a fixtures directory inside an app or in the dir specified by FIXTURE_DIRS in your settings.py file
You can run with tests with verbosity=2 to get full output.
https://docs.djangoproject.com/en/1.0/ref/django-admin/#test
Is your fixtures file named westeros ? or does it have a file extension?
Django will fail silently on fixture loads as you see. (at least up until 1.3, I haven't used fixtures in new 1.4 version yet). But you are not actually testing if the fixtures are loading.
Throw in a self.assertGreater(YourModel.objects.all(), 0) or somethign to verify that there are no objects, or drop in a debbuger and start querying some of your models.

Load Multiple Fixtures at Once

Is there anyway to load one fixture and have it load multiple fixtures?
I'd ideally like to type:
python manage.py loaddata all_fixtures
And have that load all of the data instead of having to type everything. Is this possible?
Using $ python manage.py loaddata myfixtures/*.json would work as Bash will substitute the wildcard to a list of matching filenames.
I have multiple apps on the project directory and have each app with its 'fixtures' directory. So using some bash I can do:
python3 manage.py loaddata */fixtures/*.json
And that expands all of the json files inside of the fixtures directory on each app in my project. You can test it by simply doing:
ls */fixtures/*.json
Why not create a Makefile that pulls in all your fixtures? eg something like:
load_all_fixtures:
./manage.py loaddata path/to/fixtures/foo.json
./manage.py loaddata path/to/fixtures/bar.json
./manage.py loaddata path/to/fixtures/baz.json
And then at the shell prompt, run
make load_all_fixtures
(This kind of approach is also good for executing unit tests for certain apps only and ignoring others, if need be)
This thread shows up among the first results with a Google search "load data from all fixtures" and doesn't mention what IMO is the correct solution for this, ie the solution that allows you to load any fixtures you want without any wildcard tricks nor a single modification of the settings.py file (I also used to do it this way)
Just make your apps' fixtures directories flat (and not the usual Django scheme that e.g. goes app_name/templates/app_name/mytemplate.html), ie app_name/fixtures/myfixture.[json, yaml, xml]
Here's what the django doc says :
For example:
django-admin loaddata foo/bar/mydata.json
would search /fixtures/foo/bar/mydata.json for each installed application, /foo/bar/mydata.json for each directory in FIXTURE_DIRS, and the literal path foo/bar/mydata.json.
What that means is that if you have a fixtures/myfixture.json in all your app directories, you just have to run
./manage.py loaddata myfixture
to load all the fixtures that are located there within your project ... And that's it ! You can even restrict what apps you load fixtures from by using --app or --exclude arguments.
I'll mention that I use my fixtures only to populate my database while doing some development so I don't mind having a flat structure in my 'fixtures' directories ... But even if you use your fixtures for tests it seems like having a flat structure is the Django-esque way to go, and as
that answer suggests, you would reference the fixture from a specific app by just writing something like :
class MyTestCase(TestCase):
fixtures = ['app_name/fixtures/myfixture.json']
My command is this, simple. (django 1.6)
python manage.py loaddata a.json b.json c.json
If you want to have this work on linux and windows you simply could use this for loading all your json-Fixtures:
import os
files = os.listdir('path/to/my/fixtures')
def loaddata(file):
if os.path.splitext(file)[1] == '.json' and file != 'initial_data.json':
print file
os.system("python manage.py loaddata %s" % file)
map(loaddata, files)
Works for me with Django-admin version 3.1.4
python manage.py loaddata json_file_1 json_file_2
My folder structure is like this -
app_name_1
├──fixtures
├────json_file_1.json
├────json_file_2.json
app_name_2
├──fixtures
├────json_file_3.json
Manage.py loaddata will look automatically in certain places, so if you name your fixtures the same in each app, or put all your fixtures in the same folder it can be easy to load them all. If you have many different fixtures, and need a more complex naming schema, you can easily load all your fixtures using find with -exec
find . -name "*.json" -exec manage.py loaddata {} \;
As I state in this [question][2], I also have this in a fabfile. EDIT: use python manage.py if manage.py is not in your VE path.
If your fixtures are located into the same folder, you can simply ls and xargs: ls myfolder | xargs django-admin loaddata.
Example with this structure:
$ tree fixtures/
root_dir/fixtures/
├── 1_users.json
├── 2_articles.json
└── 3_addresses.json
$ ls -d fixtures/* | xargs django-admin loaddata
would do the same as:
$ django-admin loaddata 1_users.json
$ django-admin loaddata 2_articles.json
$ django-admin loaddata 3_addresses.json
After doing a bit of searching, I ended up writing this script. It searches through all directories named "fixtures" for .json files and runs a "python manage.py loaddata {fixture_name}.json". Sometimes ordering matters for foreign key constraints, so it leaves a fixture in the queue if the constraint cannot be resolved.
(Note: It requires the pip package simple_terminal that I wrote. And I set it up to be run by 'python manage.py runscript ', which requires django-extensions.)
# load_fixture.py
#
# A script that searches for all .json files in fixtures directories
# and loads them into the working database. This is meant to be run after
# dropping and recreating a database then running migrations.
#
# Usage: python manage.py runscript load_fixtures
from simple_terminal import Terminal
from django.core.management import call_command
from django.db.utils import IntegrityError
def load_fixture(fixture_location):
# runs command: python manage.py loaddata <fixture_location>
call_command('loaddata', fixture_location)
def run():
with Terminal() as t:
# get all .json files in a fixtures directory
fixture_locations = t.command(
'find . -name *.json | grep fixtures | grep -v env')
while fixture_locations:
# check that every iteration imports are occuring
errors = []
length_before = len(fixture_locations)
for fl in fixture_locations:
try:
# try to load fixture and if loaded remove it from the array
load_fixture(fl)
print("LOADED: {}".format(fl))
fixture_locations.remove(fl)
except IntegrityError as e:
errors.append(str(e))
# if import did not occur this iteration raise exception due to
# missing foreign key reference
length_after = len(fixture_locations)
if length_before == length_after:
raise IntegrityError(' '.join(errors))
This works well for me; it finds all files located in fixtures directories within the the src directory:
python manage.py loaddata \
$(ls -1 src/**/fixtures/* | tr '\n' '\0' | xargs -0 -n 1 basename | tr '\n' ' ')
python manage.py loaddata ./*/fixtures/*.json
This command will look for the folder fixture in all the directory and then it will pick up all the files with json extension and will install the fixtures.
This way you won't have to have just one folder for fixtures instead you can have fixtures on app level and in multiple apps.
It will work with the ideal folder structure like this -
app_name_1
├──fixtures
├────json_file_1.json
├────json_file_2.json
app_name_2
├──fixtures
├────json_file_3.json