what magic is "django-admin startapp" doing, that the test runner needs to find my tests.py - django

I was having a problem that the django test runner wasn't finding the tests for my app, like this one:
Django test runner not finding tests
One of the comments on that thread suggested creating a new app with django-admin.py and seeing if the tests ran there. e.g.
django-admin.py startapp delme
then
adding "delme" to my INSTALLED_APPS
then
copying my tests.py from the app where it wasn't getting found into delme/
and viola! the tests did run. So, OK, I have a work arround, but I don't understand. I re-read what I think should be the relevant parts of the django documentation but the penny refuses to drop.
BTW, the app works via runserver and wsgi, so there doesn't appear to be any gross configuration problem. And my tests all pass from their new home, so I obviously need more tests :)
Specifically, I'm running django in a virtualenv, so I had run "django-admin.py startapp" in the (activated) virtualenv where I wanted the tests to run. This doesn't make the tests run in my other virtualenvs, I still have the old symptoms there (Ran 0 tests). I have a multitude of virtualenvs, managed by non-trivial paver scripts. One uses "path.copytree" for deploying projects, rewrites apache config files, restarts apache, writes wsgi files using the appropriate virtualenv, etc. The other uses PIP/GCC/aptitude/etc for bootstrapping/tearing down the different environments, updating packages as per configuration, etc. So I want to understand the difference between django-startapp and simply copying files, so I can fix these paver scripts so the tests can run in any environment I want them to.

The only thing that makes sense to me, after reading your description, is the location of paths for your existing apps. Can you confirm the following things:
Your app is at the same folder level as the delme app
Your app folder contains an __init__.py file
Your app is listed in the INSTALLED_APPS setting
I'm going to guess that it's a missing __init__.py file, as that trips some people up. To answer your specific question, django-admin startapp doesn't do anything magical. It just creates the right folders and files in the correct place.
Your folder structure should be...
my_project/
__init__.py
manage.py
settings.py
my_app/
__init__.py
tests.py
models.py
delme/
__init__.py
tests.py
models.py
Also note this comment
You can't easily name the TestCase class directly. You name the app, the Django runner does it's discovery thing by looking in models.py and tests.py

solved (still with a little whiff of magic).
diff showed that my old app didn't have a models.py but the new app ("delme", working) did. I didn't think the old app needed one, it was importing all it's domain classes from other places.
Touching an empty models.py in my old app fixed it, now the test runner finds the tests.py and everything works as expected. Condlusion - if an app has no models.py, the django test runner won't find the app's tests.py.
What I said about not working in different virtualenvs was bogus (red herring), I was a bit confused about what my deploy scripts were doing.

Related

Django 2.0 - Make test worker to run tests in non-app folder

In Django 2.0, I have following project structure, which I can't change, no matter what:
grocery_store_website
manage.py
grocery_store # contains wsgi, settings,etc.
app1
app1
non-app-utils
__init__.py
helpers.py
serializers.py
model_mixins.py
tests
test_helpers.py # I want test runner to run these.
It turned out, I need to write unit tests for non-app-utils. Mentioned directory is not a registered Django App and never will be. These tests must be located in tests directory, located in non-app-utils. How can I make Django's test runner to discover and run also tests from non-app-utils directory?
If I run Django tests with directly specified path ./manage.py test utils.tests.test_helpers, it works. However ./manage.py test does not. Any ideas how to go on?
Jerin Peter George suggested adding __init__.py file into non-app-utils directory. However, problem was, there is __init__.py file missing in non-app-utils/tests directory!
After I add those and run ./manage.py test, Django's test runner found my tests and ran them as I needed to!

PyCharm cannot resolve reference in __init__.py with Django project apps

I am at my wits end with this issue, and would love some help resolving this.
I have a Django project with a bunch of sub apps as such:
my_project/
manage.py
my_project/
settings.py
urls.py
wsgi.py
app_root/
__init__.py
app1/
__init__.py
models.py
views.py
urls.py
templates/
[various templates].html
app2/
__init__.py
models.py
[etc]
app3/
[etc]
in my django settings.py i have installed apps as such:
app_root.app1,
app_root.app2,
In PyCharm, I've tried various things but essentially have Content Root as the top "my_project/" and app_root, app1, app2, etc as Source Roots. I've tried just having app_root as the only Source Root, and I've tried having only app1, app2, etc only as Source Roots, but nothing makes any difference.
Everything functions fine. app runs and everything. However, PyCharm has an inability to resolve my apps.
However, if i try this:
import app_root
...
def some_function(self):
app_root.app1.models.My_Model.objects.all()
it will highlight app1 with the error "Cannot find reference 'app1' in '__init__.py'"
This also means it can't do autocomplete anywhere in the path while doing app_root.app1. - it has no idea about models, views, etc. despite having an (empty) __init__.py in every directory.
I also cannot use any refactoring because it always says "Function is not under the source root"
I've spent countless hours trying to get PyCharm to behave but simply cannot find a way to do it. Is there any way this can be done so PyCharm will autocomplete my apps and not keep giving inspection warnings?
I had some similar issues. My solution; within the PyCharm preferences I added a path to app_root in my active Python Interpreter.
After an exchange with the PyCharm folks, here is what I learned:
Django imports all apps in INSTALLED_APPS variable and their models using __import__ for its own purposes.
In your case, it runs
__import__("app_root.app1")
__import__("app_root.app1.models")
After that, you call import app_root and obtain module app_root with app_root.app1 and app_root.app1.models already imported by internal Django code
Fact that Django imports apps and models is Django internals, it is undocumented and may be changed in future releases. We believe you should not rely on it in your production code, nor PyCharm should.
Here is example in bare python (no django):
__import__("encodings.ascii")
import encodings
print (encodings.ascii.Codec) # this code works, but PyCharm marks "ascii" as "unknown module"
So basically, it's not supposed to work as import app_root, but Django funkiness is masking that.

Django test not running specific app tests

I have an app named "sites" that runs normally through the built in server and I can interact with it without any issues.
I added tests in the standard tests.py file and ran "manage.py test sites"
I have two tests in my tests.py file all starting with "test".
When I run the manage.py command in verbose mode, I get:
test_get_current_site (django-contrib.sites.tests.SitesFrameworkTests) ... ok
test_save_another (django-contrib.sites.tests.SitesFrameworkTests) ... ok
etc.
It looks to me that I have a name conflict with an internal module.
Is there any way I can get manage.py to test my code or should I just bite the bullet and change my app name?
Rename your app. From the docs on the INSTALLED_APPS setting:
App names must be unique
The application names (that is, the final dotted part of the path to the module containing models.py) defined in INSTALLED_APPS must be unique. For example, you can’t include both django.contrib.auth and myproject.auth in INSTALLED_APPS.
In this case, your sites app clashes with the Django sites framework, django.contrib.sites.

Installing Pinax, where is my deployment folder?

I'm trying to set up Pinax and I'm new to everything involved (Django, Pinax, webservers, etc). I'm following http://pinax.readthedocs.org/en/latest/gettingstarted.html
When I generate a project using:
(mysite-env)$ pinax-admin setup_project -b basic mysite
The directory structure I get is:
apps __init__.py manage.py settings.pyc urls.py
dev.db __init__.pyc requirements static urls.pyc
fixtures locale settings.py templates wsgi.py
Which as far as I can tell is missing the deployment folder (when you compare to the directory structure shown here : http://pinax.readthedocs.org/en/latest/starterprojects.html). It doesn't seem to be effecting anything yet, but it makes me nervous. What is going on and is the fact I'm missing the deployment folder going to cause problems in the future?
I'm running Ubuntu and using python 2.7. I had the same behaviour with Windows 7, python 2.6
Thanks!
The new Django versions have made the old pinax pretty much useless. Now Django supports project templates and Pinax is separated into several smaller projects regarding starter projects (such as pinax-project-account) and apps (such as django-user-account).
The current way to use pinax is to choose a starter project, and then running something like:
$ django-admin.py startproject --template=https://github.com/pinax/pinax-project-account/zipball/master <project_name>
and then install requirements:
$ pip install -r requirements.txt
This will create a new Django project using the starter-project as a template, which already includes a few apps (like django-user-account) and templates (with bootstrap!). The project is ready to run, and already includes a bunch of functionality (like user registration, login and management).
Also, Django has changed the project directory structure a bit, so now it doesn't really look like that anymore.

Django custom commands not showing up on Heroku

I’m having a problem when using django custom commands on Heroku.
On my local machine, the custom command appears in help if I run ./manage.py help and running ./manage.py deletedphotos runs it too.
All the init.py files are there and the settings are also correct, i.e. there are not major config differences between my local and Heroku instances.
Now, when I put it on Heroku, it does not show up. All my other non-default commands are there: ping_google that comes from installing sitemap.xml support and commands for south migrations. But for some reason, my self written commands do not show up.
I’ve also sent a support request to Heroku, but haven’t heard back from them in a few days, so I thought I’d post here as well, maybe someone has had any similar problems.
The deletedphotos.py file contents are pretty much like this if that matters anything:
from django.core.management.base import BaseCommand, CommandError
from foo.app.models import *
class Command(BaseCommand):
help = 'Delete photos from S3'
def handle(self, *args, **options):
deleted_photos = Photo.objects.filter(deleted=True).exclude(large='', small='', thumb='')
self.stdout.write('Found %s photos\n' % str(len(deleted_photos)))
I’ve tried checking all the correct python paths etc, but not 100% if I’m not missing something obvious.
I was actually able to find a solution. The INSTALLED_APPS had my local app referenced, but for some reason it was not working as intended.
My app is in: /name/appname/ and having 'name.appname' in INSTALLED_APPS was working fine in local setup.
Yet, on Heroku, I had to change the reference to just 'appname' in INSTALLED_APPS and all started working magically.
Your home directory needs to be on your Python path. A quick and unobtrusive way to accomplish that is to add it to the PYTHONPATH environment variable (which is generally /app on the Heroku Cedar stack).
Add it via the heroku config command:
$ heroku config:add PYTHONPATH=/app
That should do it! For more details:
http://tomatohater.com/2012/01/17/custom-django-management-commands-on-heroku/
I had this problem too, found the answer here: Django Management Command ImportError
I was missing an __init__.py file in my management folder. After adding it everything worked fine.
Example:
qsl/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
news.py
jobs/
__init__.py
news.py
tests.py
views.py