I'm writing a test in Django 1.11 and trying to load some fixture data into my local sqlite database (retrieved from the real database via manage.py dumpdata) like so:
class MyTest(TestCase):
fixtures = [os.path.join(settings.BASE_DIR, 'myapp', 'tests', 'fixtures.json')]
Part of the fixture data is User models where we have a custom User with a different USERNAME_FIELD, so all of the username fields on each of our records is blank.
However, when I try and run my test using my fixture, I get the following error:
IntegrityError: Problem installing fixture '.../fixtures.json': Could not load myapp.CustomUser(pk=41): column username is not unique
pk 41 is the second CustomUser record in my fixtures.json. How can I tell Django's testing framework to ignore the constraint it thinks it needs to enforce, or otherwise get my fixture data loaded for testing?
Related
I tried to use postgres database with pytest-django and I've encountered a problem. I have a fixture named populate_db which creates some records in the database. To check if pytest actually creates records, I put a 60-seconds sleep after creating the model objects and checked the panel admin but none of the created objects were present there. I think the pytest can't connect to my database and doesn't create any records in the database. Below are the functions that I have in my conftest.py file and I have another test file which tries to retrieve a database record from the API.
Here is my code for the populate_db fixture:
#pytest.fixture(autouse=True)
def populate_db():
sport = Vertical.objects.create(name='sport')
bazar = Vertical.objects.create(name='bazar')
time.sleep(60)
yield
I'm running this with Django 2.2.5 and Postgres 11
It appears that the Django test framework's LiveServerTestCase reloads fixture data in-between each test without deleting the previous data. I come across this with a consistent error:
> ./manage.py test functional_tests
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.EE
======================================================================
The first test passes but the subsequent tests fail.
The error I get is:
django.db.utils.IntegrityError: Problem installing fixture '.../fixtures/unit_test.json': Could not load app.Configuration(pk=1): duplicate key value violates unique constraint "app_configuration_site_id_3124a87d_uniq"
DETAIL: Key (site_id)=(1) already exists.
If I comment out and don't load fixtures the 3 tests work perfectly fine.
There is only one record entry with the PK in question in the fixtures. This tells me that the Test reloads the data and fails because it finds an existing record with the same PK.
Is there a way to tell it to either overwrite the data with the same PKs or ignore (a-la get_or_create)?
Is there a better practice to follow with LiveServerTestCase?
It's frustrating because I can't seem to be able to use this test class with fixtures when I need to.
Any insight is appreciated.
RB
Here is the test setup:
from django.contrib.staticfiles.testing import LiveServerTestCase
from selenium.webdriver.chrome.webdriver import WebDriver
class TestHeaderNavigation(LiveServerTestCase):
fixtures = ['unit_test']
def setUp(self):
super().setUp()
self.selenium = WebDriver()
self.selenium.implicitly_wait(5)
self.selenium.get('%s' % (self.live_server_url))
def tearDown(self):
super().tearDown()
self.selenium.quit()
I need to do some unit tests in my Django project. The problem is that almost every use case depends on prepopulated database objects.
For example, I want to create a product and test, if there were all pre_save signals successful.
from django.contrib.auth.models import User
from django.test import TestCase
from .models import Product
class ProductTestCase(TestCase):
def setUp(self):
self.user = User.objects.create(username='test_user')
self.product = Product.objects.create(name='Test product',user=self.user)
def test_product_exists(self):
self.assertIsNotNone(self.product)
def product_is_active_by_default(self):
...
I can't do that because product has to have User object related. But I can't create a User object because User has to have related plan object. There are multiple plans in my production database from which one is default but there are no plans inside test database.
So to be able to do unit tests I need to prepopulate test database with multiple objects from multiple apps.
How can I do that?
you can simply use django fixtures for that :-)
first populate a sample db with data then export data with python manage.py dumpdata
then in one of your apps create a directory named fixtures and put exported json file there (named tests.json or something else)
in your test class load fixtures like this
class ProductTestCase(TestCase):
fixtures = ['tests.json', ]
checkout django docs
PS: checkout factory boy too (#Gabriel Muj) answer
I don't recommend using fixture since you will need to maintain them each time you make changes to the model. Here is a better approach on creating objects for tests by using this library https://factoryboy.readthedocs.io/en/latest/ which is more flexible.
I'm using django MPTT model.
I subclass MPTT model, but then try to add fixture to the custom model with supplied initial_data in JSON.
The parent TreeForeignKey is optional (blank=True, null=True)
When I apply a JSON fixture from initial_data, it asks to supply the fields "lft", "rght", "tree_id", "level".
ie: may not be NULL
...when running python manage.py syncdb
These are fields from MPTT.
Is there a way to exclude this or get around this from the fixture data?
Thanks
Did a dumpdata of my project, then in my new test I added it to fixtures.
from django.test import TestCase
class TestGoal(TestCase):
fixtures = ['test_data.json']
def test_goal(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
When running the test I get:
Problem installing fixture
'XXX/fixtures/test_data.json':
DoesNotExist: XXX matching query does
not exist.
But manually doing loaddata works fine does not when the db is empty.
I do a dropdb, createdb a simple syncdb the try loaddata and it fails, same error.
Any clue?
Python version 2.6.5, Django 1.1.1
Perhaps you have some foreign key troubles. If you have a model that contains a foreign key referring to another model but the other model doesn't exist, you'll get this error.
This can happen for a couple of reasons: if you are pointing to a model in another app that you didn't include in the test_data.json dump, you'll have trouble.
Also, if foreign keys change, this can break serialization -- this is especially problematic with automatically created fields like permissions or generic relations. Django 1.2 supports natural keys, which are a way to serialize using the "natural" representation of a model as a foreign key rather than an ID which might change.