Right now, if I want to run tests from all my apps, I go:
python manage.py test app1 app2 app3
If I run:
python manage.py test
The test of all apps in INSTALLED_APPS are run, including the django ones. Is there a simple command to run the tests of all the apps that I have created?
Sadly there is no such command. Django has no way of telling which apps are "yours" versus which are someone else's.
What I would suggest is writing a new management command, call it mytest. Then create a new setting MY_INSTALLED_APPS. The mytest command will just run the test for every app in MY_INSTALLED_APPS. You'll want the mytest command to subclass django.core.management.base.AppCommand. django.core.management.call_command will also be helpful.
The only problem with this method is that you will have to constantly maintain the MY_INSTALLED_APPS setting to make sure it is correct.
You could create an management/commands/testmyapps.py for one of your app which has:
from django.core.management.base import BaseCommand, CommandError
import django.core.management.commands.test
from django.core import management
from django.conf import settings
class Command(django.core.management.commands.test.Command):
args = ''
help = 'Test all of MY_INSTALLED_APPS'
def handle(self, *args, **options):
super(Command, self).handle(*(settings.MY_INSTALLED_APPS + args), **options)
This works better in Django 1.6+: when you run python manage.py test, only your tests will run (assuming you have the default settings for TEST_RUNNER)
Use nose django test runner, it takes care of this.
Reference:
Django nose to run only project tests
Related
Now, to run the bot through Django, I first use the python manage.py runserver command and then follow the link to launch a view with my bot. Can you tell me if there is an easier way to start my bot automatically when starting a Django project?
Actually, you can use a management command to run your bot with something like
python manage.py runbot
All Django context, including DB and settings, will be available
Reference to management command page:
https://simpleisbetterthancomplex.com/tutorial/2018/08/27/how-to-create-custom-django-management-commands.html
Maybe is a little late but you can do the following:
create the bot.py file in the same folder where manage.py is.
inside the bot.py make sure you import the following:
import django
import os
os.environ['DJANGO_SETTINGS_MODULE'] = '{Folder where your settings are}.settings'
django.setup()
and in order to run you just type python bot.py
In my django project i have to check if a database/table exist before starting application, i don't know how is better insert the code for check.
I try to add in views.py into login function a try except block but i was try to find an elegant and more effective solution.
Thanks in advance
To check before the app starts then you can use the AppConfig.ready() function. This gets called before the application starts, but after your project has started. If you want to check before the project starts then you will have to hook into the method you use to start your project, eg within wsgi.py or even manage.py
AppConfig.ready() docs Note that the docs specifically say
avoid interacting with the database in your ready() implementation.
But your use case may justify doing this.
The ready function is called when you run the commands from manage.py eg
manage.py shell / manage.py migrate / etc
It won't get called when your site is visited of course. If you want to run a DB check in response to a visitor action then that code should go into your view
You put the ready() function in your apps.py:
from django.apps import AppConfig
from django.db import connection
class MyAppConfig(AppConfig):
name = 'MyApp'
def ready(self):
print("i am the ready function and the database test code goes here")
# put your test code here, eg you could read all the tables from sqlite
with connection.cursor() as cursor:
cursor.execute("SELECT name FROM sqlite_master;")
rows=cursor.fetchall()
print (rows)
You can write your custom django admin commands and run it by using python manage.py your_command right before calling python manage.py runserver. There are detailed examples at the official documentation.
One of the advantages of using commands is that testing commands are fairly easy. Django has a package for calling commands django.core.management.call_command which enables funtionally test your command.
I have a Django project. Everytime I deploy, I need to run a series of manage.py command (such as syncdb, south migiration, fixture update).
I am getting tired of type the command line by line and therefore I wrote a python script to do these:
import subprocess
subprocess.call(['python', 'manage.py', 'syncdb'])
#Skip the detail
subprocess.call(['python', 'manage.py', 'loaddata', 'setup/fixture.xml'])
I am wondering if there is a better way to do this?
Thanks.
You can use fabric, a Python library that allows you to script remote actions. This question has some links in the accepted answer for more information on fabric and django.
You can also call management commands directly:
from django.core.management import call_command
call_command('syncdb')
call_command('loaddata', 'setup/fixture.xml')
Save that as a normal python file and execute it from your shell or as part of your deployment scripts.
I have finally decided to create unit test for all my code. That is I'm trying to create fixtures based on my models to test my function against them.
I have create a json fixture using dumpdata command and placed it under fixtures directory on my app. The following is the code on my test:
import unittest
from mysite.myapp.models import Post
class RatingTestCase(unittest.TestCase):
fixtures = [
'posts.json',
]
def test_me(self):
p = Post.objects.all()
self.assertTrue(p)
I run my test using the following command on my Arch Linux machine:
python2.7 manage.py test myapp
It creates a sqlite database and installs all the tables and indeces, however at the end it says no fixtures found and it says my test failed since it didn't find any data.
I'm running the latest revision of development version of Django and noticed that based on the documentation I am supposed to import unittest using:
from django.utils import unittest
However, when I do this, it complains that unittest cannot be imported. That's why I import
unittest directly from my python path which worked.
I've tried to mock django model objects before, but I think it's better to test Django apps using fixtures than using mock libraries. Any idea how to load the fixtures?
Thanks in advance.
EDIT: If I change my fixture name to initial_data.json, it will load it every time I run my test. However, I still need to have multiple fixture names for running different tests.
EDIT: I got it working by importing TestCase from the following:
from django.test import TestCase
There are a couple things that could help:
You can run the test with --verbosity=2 to see which directories django looks in for fixtures.
django TestCase is what django recommends to use, opposed to unittest.
Where is your fixture directory/file located? If it's not in your app you have to specify a fixture directory in your settings file.
Have you checked if the path where the fixture is present is available in:
settings.FIXTURE_DIRS = ('/path/to/proj_folder/fixtures/',)
I had the name problem. The code below would not work even though I had the file in my fixture directory under the app folder.
fixtures = ['initial_data2.json']
I then changed the import statement to below an it just worked.
from django.test import TestCase
I had the same problem, and the reason it didnt work for me was that I had no extension on my initial-data-file.
I did:
manage.py dumpdata > initial_data
manage.py loaddata initial_data
Which doesnt work, since there's no extension on initial_data, however, this does work:
mv initial_data initial_data.json
manage.py loaddata --verbosity=2 initial_data.json
Just to confirm the import statement for TestCase that breaks finding any fixtures
but works in all other ways, so just throws no errors since it attempts no fixture loading is
from django.utils.unittest import TestCase
... DONT USE IT ... as suggested use
from django.test import TestCase
In django is there way to import all modules
ex: from project.models import *
ex: from project1.models import *
Can this be done with one statement
If you just want to do this when testing things in the shell, look into the shell_plus command provided by the django-extensions project.
This is a really neat extension, which starts a shell and automatically loads all the models in your project when you do ./manage.py shell_plus from the command line.