3

I have a simple abstract class and I want to write a unit test for this. I am using Django 1.10 and the most answers I have found are out there for years and maybe are outdated. I have tried the solution from Vinod Kurup:

# tests/test_foo.py
from django.db import models
from django.test import TestCase

from ..models import MyAbstractModel

class MyTestModel(MyAbstractModel):
    name = models.CharField(max_length=20)

    class Meta:
        app_label = 'myappname'

class AbstractTest(TestCase):
    def test_my_test_model(self):
        self.assertTrue(MyTestModel.objects.create(name='foo'))

Are there any simple modern approaches to test an abstract model that work with Django 1.10 like the one from Vinod Kurup?

Edit:

Code for my Abstract Model:

class FlagsModel(models.Model):

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    reported = models.BooleanField(default=False)
    deleted = models.BooleanField(default=False)

    class Meta:
        abstract = True

And this is my test file:

from ..models import RecipeModel, FlagsModel

class FlagsTestModel(FlagsModel):

    class Meta:
        app_label = 'recipes'


class FlagsModelAbstractTest(TestCase):

    def test_my_test_model(self):
        self.assertTrue(FlagsTestModel.objects.create())

The error I get is:

Traceback (most recent call last):
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: relation "recipes_flagstestmodel" does not exist
LINE 1: ...eported", "recipes_flagstestmodel"."deleted" FROM "recipes_f...
                                                             ^


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/management/commands/test.py", line 29, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/management/base.py", line 305, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/management/base.py", line 356, in execute
    output = self.handle(*args, **options)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/management/commands/test.py", line 72, in handle
    failures = test_runner.run_tests(test_labels)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/test/runner.py", line 549, in run_tests
    old_config = self.setup_databases()
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/test/runner.py", line 499, in setup_databases
    self.parallel, **kwargs
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/test/runner.py", line 743, in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/backends/base/creation.py", line 78, in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/backends/base/creation.py", line 122, in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/serializers/__init__.py", line 129, in serialize
    s.serialize(queryset, **options)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/core/serializers/base.py", line 79, in serialize
    for count, obj in enumerate(queryset, start=1):
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/backends/base/creation.py", line 118, in get_objects
    for obj in queryset.iterator():
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/models/query.py", line 54, in __iter__
    results = compiler.execute_sql()
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 835, in execute_sql
    cursor.execute(sql, params)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/arch/.environments/djanveg_dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "recipes_flagstestmodel" does not exist
LINE 1: ...eported", "recipes_flagstestmodel"."deleted" FROM "recipes_f...
Greeneco
  • 691
  • 2
  • 8
  • 23

1 Answers1

1

The problem is that you haven't migrated that model to your database, and that's because you created the model inside the tests file, Django only checks for models inside the models.py file, so move the next code to the models.py file:

class FlagsTestModel(FlagsModel):

    class Meta:
        app_label = 'recipes'

Then run python manage.py makemigrations and python manage.py mgirate to create the table inside your database and everything will work as expected.

Victor Castillo Torres
  • 10,581
  • 7
  • 40
  • 50
  • 1
    I could do this, but I dont want to have my abstract model in my development database I just want to test it and want that Django only does it for my test db – Greeneco Sep 09 '16 at 16:20
  • 1
    @Con Maybe you could create the table first in that database and then add a Meta to your model, so it knows where to look :D – Victor Castillo Torres Oct 03 '16 at 19:44