1

I am writing a Django test inheriting from django.test.TestCase. Everywhere, in the docs, this tutorial and even in this accepted SO accepted answer is stated that when using Django TestCase, a test db will be automatically created. Previously I have worked with DRF APITestCases and all worked well. Here I am using the very standard approach but the setUpTestData class method is using my production db.

What do I do wrong and what has to be done so a test db is spawned and used for the test? Please see my code bellow.

from django.test import TestCase
from agregator.models import AgregatorProduct
from django.db.models import signals
def sample_product_one():
 sample_product_one = {
 # "id": 1,
 "name": "testProdOne",
 "dph": 21,
 "updated": datetime.now(),
 "active": True,
 "updatedinstore": False,
 "imagechanged": False,
 "isVirtualProduct": False,
 }
 return sample_product_one
class TestCreateProdToCategory(TestCase):
 """
 Test for correct creation of records
 """
 @classmethod
 @factory.django.mute_signals(signals.pre_save, signals.post_save)
 def setUpTestData(cls):
 AgregatorProduct.objects.create(
 **sample_product_one()
 )
 def test_create_prod_to_cat(self):
 product = AgregatorProduct.objects.get(id=1)
 self.assertEqual(product.id, 1)

DB set up:

DATABASES = {
 'agregator': {
 'NAME': 'name',
 'ENGINE': 'sql_server.pyodbc',
 'HOST': 'my_ip',
 'USER': 'my_user',
 'PASSWORD': 'my_pwd',
 'OPTIONS': {
 'driver': 'ODBC Driver 17 for SQL Server',
 'isolation_level': 'READ UNCOMMITTED',
 },
 }
}

The test results in

----------------------------------------------------------------------
Traceback (most recent call last):
 File "C:\xevos\xevosadmin\agregator\tests\test_admin_actions\test_products_to_categories_admin_action.py", line 64, in test_create_prod_to_cat
 product = AgregatorProduct.objects.get(id=1)
 File "C:\xevos\xevosadmin\.venv\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
 return getattr(self.get_queryset(), name)(*args, **kwargs)
 File "C:\xevos\xevosadmin\.venv\lib\site-packages\django\db\models\query.py", line 397, in get
 raise self.model.DoesNotExist(
agregator.models.AgregatorProduct.DoesNotExist: AgregatorProduct matching query does not exist.
----------------------------------------------------------------------

which is a result of id being autoincrementing and given there are products in the production db already, it gets id of eg 151545 (AgregatorProduct matching query does not exist. is a result of the fact that the product which used to have id=1 was deleted a long time ago in the production db.)

So the test writes to the existing database and the data persist there even after the test is finished.

asked Mar 30, 2021 at 11:03
6
  • Can you show your database configuration from Django project settings? Also, what is happening right now? Is there an error being thrown or are tests writing to your non-test database? Commented Mar 30, 2021 at 11:09
  • @GwynBleidD edit added Commented Mar 30, 2021 at 11:14
  • As the MSSQL server integration is a 3rd party addon, it may not support test database creation. I have no way of checking that for sure as there are many packages providing such support, using the same engine name, so you'll have to check it by yourself. Make sure to check it for the exact version of the integration you are using. Commented Mar 30, 2021 at 11:24
  • Also, how are you running your tests? If you're not using ./manage.py test, additional care may be needed for all the test preparation in Django to work properly Commented Mar 30, 2021 at 11:26
  • 1
    If the database engine is lacking support for creating a test database for you or it is not informing you about the failure, there is nothing that Django can do about it. As I said, I'm not sure this is the case, but nobody but you can check it either without information which exact implementation of MSSQL engine are you using. Commented Mar 30, 2021 at 11:44

1 Answer 1

0

To create a test database, use the setUp method inside TestCase and run it using python manage.py test

from django.test import TestCase
from myapp.models import Animal
class AnimalTestCase(TestCase):
 def setUp(self):
 Animal.objects.create(name="lion", sound="roar")
 Animal.objects.create(name="cat", sound="meow")
 def test_animals_can_speak(self):
 """Animals that can speak are correctly identified"""
 lion = Animal.objects.get(name="lion")
 cat = Animal.objects.get(name="cat")
 self.assertEqual(lion.speak(), 'The lion says "roar"')
 self.assertEqual(cat.speak(), 'The cat says "meow"')

The database will be created and deleted automatically after tests are done https://docs.djangoproject.com/en/3.1/topics/testing/overview/#writing-tests

answered Mar 30, 2021 at 12:26
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the suggestion, but the setUp method does the same as setUpTestData method except for that setUpTestData runs only once to set up the scene, not for each subtest so results in the same error

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.