why django SimpleTestCase create test database - django

as explained in this question and in django docs, when using SimpleTestCase in unit testing, django should not create test database (which takes too long).
Inside one of my applications which is called "search, I have some unit test inherited from SimpleTestCase. this is tests.py inside search application:
class TokenizerTestCase(SimpleTestCase):
def test_one(self):
self.assertItemsEqual(1, 1)
When I call python manage.py test search.tests.TokenizerTestCase it takes too long to build default database. does anybody know why it is creating database for test?

By default SimpleTestCase creates a test database. You can extend the class for your own functionality. If you do not want to create a database of your own in each and every setup setup your own test environment extending the classes.
Override the _pre_setup and _post_teardown methods. For more information read the source code for TransactionTestCase to see how it creates the test database structure.
Read the source code here

Related

django unittest to use "real" database

I am currently writing test cases for views, Which eventually uses database also.
By default a test database is being created and removed after test are run.
As the database itself is development database, I don't want my test to create a separate db but use exciting only.
Also I will like to bring to your notice, that in my environment, database are created and provided and django can't run migration or create database.
How can I create unittest which uses real database ?
I think the primary reason for this question is because your django database user is not provided with the create/drop database permission.
Django needs to create and drop a test database for the purpose of unit testing. It cannot use an existing database for this purpose. Why we are not allowed to use an existing database in the unit test is because, the data can be modified by anyone who has the same database permission and django may not have control over the updates they make, This might end up in an unsuccessful unit test.
This is clearly explained in another question's answer
If your DB Admin can provide your Django user the required access for the Test module to work as expected, You can make use of the Fixtures. Fixtures are like data files, can be created from your development environment and then can be used in the Unit test Setup to import the data from Fixtures to the test database created by Django.
The ultimate purpose of any Unit test framework will be to test the functionality of the Back end code logic with a data which is not likely to change. As mentioned in the above links, The Functional testing and Regression Testing is there to cover the real database.
For more details on Fixtures visit Using Fixtures with Django Test Cases

How to access django database with pytest

I am wanting to use pytest with django to test api queries. Is there any way to do this in pytest without resorting to creating a test database? Pytest keeps throwing an error that database access is not allowed. I end up having to do this at the top of my pytest files:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE","MyProject.settings")
import django
django.setup()
I tried using the pytest-django library, but it doesn't have a mark for accessing the db that I can use.
It always helps to rtfd:
https://pytest-django.readthedocs.io/en/latest/database.html
pytest-django takes a conservative approach to enabling database access. By default your tests will fail if they try to access the database. Only if you explicitly request database access will this be allowed. This encourages you to keep database-needing tests to a minimum which makes it very clear what code uses the database.

what is the best way to test modules in views?

I have gone through this post, but it didn't contain any relevant answer.
I am using Django 1.11 , and my views.py is modular (not class based).
I want to test views modules (functions) in the shell, in django's python shell.
>>> python manage.py shell
By directly importing views like:
>>> from my_app import views
It works, but this doesn't seem to be preferred way to me.
Is there any preferred way or shall I import views from django in shell or copy the function directly ? What is the best practice for this?
So your going to be much better off just writing Django tests for your views instead of trying to run them from the shell since it will be the same code, but you will be able to easily run the test multiple times.
So to create a test for a single view you would create a tests.py in your django app and write test for the view using django's test client. This test client is a dummy web browser that can be used to make http requests. A simple tests.py would look like this:
from django.tests import TestCase, Client
class MyViewsTestCase(TestCase):
def setUp(self):
self.client = Client() #This sets up the test client
def test_my_view(self):
# A simple test that the view returns a 200 status code
# In reality your test needs to check more than this depending on what your view is doing
response = self.client.get('the/view/url')
self.assertEqual(response.status_code, 200)
you would then run this with the commands python manage.py test or django-admin test from your terminal
Again you could do this from the shell, but it's going to be better in the long run to use the test framework
Django has some good docs on writing and running tests here: https://docs.djangoproject.com/en/2.0/topics/testing/overview/
and info on the test client along with some other testing tools here: https://docs.djangoproject.com/en/2.0/topics/testing/tools/

preventing Selenium test database from being deleted in Django between tests

Using Selenium within Django I'm trying to run 2 acceptance tests on my django app. The first test registers a new user of my app, the second one logs that user in to the system and tries to perform an action. However, when running the tests, between the first and second tests, the user is erased from the database. It seems the database is wiped between each test. All the documentation I have seen indicates this isn't supposed to be happening.
How can I prevent this from occurring?
Note: Both the setUpClass and tearDownClass methods of my Test Class have #classmethod decorators. Also, the browser doesn't close between the two tests running.

django - specify database for TestCase fixtures

I have two databases that my site uses and I have an app that uses both of them. I need to write a TestCase that loads fixtures for both databases. I use a DB router, which works fine in production, but in the testing framework, Django insists on using the 'default' database for all fixtures, even for models that specify the other database. How do I tell Django to run a fixture against another database?
My TestCase is defined list:
class VerifierTestCase(TestCase):
fixtures = ['zipcodes_test.json', 'all_states.json', 'wtf.json']
multi_db = True
There is actually a bug in Django that causes it to ignore the name-based db-specific pointers if you specify the entire fixture name.
so if you do fixtures = ["mydata.default.yaml", "mydata.myotherdatabase.yaml"]
It will load both fixtures into the default database.
But if you do fixtures = ['mydata']
It will load correctly. This is also true for dbengine specific filenames (e.g. mydata.default.postgresql.sql) as well.
Fixtures are targeted at specific databases by filename. This is true in TestCase instances as well, as they just call the loaddata command.
See https://docs.djangoproject.com/en/dev/ref/django-admin/#database-specific-fixtures
If you have a multi-db setup with models exclusive to each database. You need to save a fixture file for each database (with the non-applicable database files being empty).
If your code defines fixtures = ["sample"] and you have two databases default and other.
You need two files: sample.default.json and sample.other.json. If sample contains only models from db default, sample.other.json will be an empty file ([]) and vice-versa.
Tried with Django 3.2