Source code for django_test_tools.generators.model_test_gen

from ..utils import convert_to_snake_case

PRINT_IMPORTS = ['from django.forms.models import model_to_dict',
                 'from django.conf import settings',
                 'from django.test import TestCase',
                 'from django.db import IntegrityError'
                 ]
PRINT_TEST_CLASS = """
class TestCase{0}(TestCase):

    def test_create(self):
        \"\"\"
        Test the creation of a {0} model using a factory
        \"\"\"
        {1} = {0}Factory.create()
        self.assertEqual({0}.objects.count(), 1)

    def test_create_batch(self):
        \"\"\"
        Test the creation of 5 {0} models using a factory
        \"\"\"
        {1}s = {0}Factory.create_batch(5)
        self.assertEqual({0}.objects.count(), 5)
        self.assertEqual(len({1}s), 5)
"""

PRINT_TEST_ATTRIBUTE_COUNT = """
    def test_attribute_count(self):
        \"\"\"
        Test that all attributes of {0} server are counted. It will count the primary key and all editable attributes.
        This test should break if a new attribute is added.
        \"\"\"
        {1} = {0}Factory.create()
        {1}_dict = model_to_dict({1})
        self.assertEqual(len({1}_dict.keys()), {2})

"""

PRINT_TEST_ATTRIBUTE_CONTENT = """
    def test_attribute_content(self):
        \"\"\"
        Test that all attributes of {0} server have content. This test will break if an attributes name is changed.
        \"\"\"
        {1} = {0}Factory.create()
"""

PRINT_TEST_ATTRIBUTE_UNIQUE = """
    def test_{2}_is_unique(self):
        \"\"\"
        Tests attribute {2} of model {0} to see if the unique constraint works.
        This test should break if the unique attribute is changed.
        \"\"\"
        {1} = {0}Factory.create()
        {1}_02 = {0}Factory.create()
        {1}_02.{2} = {1}.{2}
        try:
            {1}_02.save()
            self.fail('Test should have raised and integrity error')
        except IntegrityError as e:
            self.assertEqual(str(e), '') #FIXME This test is incomplete
"""


# noinspection PyProtectedMember,PyProtectedMember
[docs]class ModelTestCaseGenerator(object): def __init__(self, model): self.model = model def _generate(self): model_test_case_content = list() model_test_case_content.append({'print': PRINT_TEST_CLASS, 'args': [self.model.__name__, convert_to_snake_case(self.model.__name__)]}) model_test_case_content.append({'print': PRINT_TEST_ATTRIBUTE_COUNT, 'args': [self.model.__name__, convert_to_snake_case(self.model.__name__), len(self.model._meta.fields)]}) content_text = PRINT_TEST_ATTRIBUTE_CONTENT.format(self.model.__name__, convert_to_snake_case(self.model.__name__)) PRINT_IMPORTS.append('from {} import {}'.format(self.model.__module__, self.model.__name__)) PRINT_IMPORTS.append('from ..factories import {}Factory'.format(self.model.__name__)) for field in self.model._meta.fields: field_type = type(field).__name__ field_data = dict() assertion = ' self.assertIsNotNone({0}.{1})\n'.format(convert_to_snake_case(self.model.__name__), field.name) content_text += assertion model_test_case_content.append({'print': content_text, 'args': None}) # Build unique tests add_integrity_error_to_imports = False for field in self.model._meta.fields: if field.unique and not field.primary_key: data = [self.model.__name__, convert_to_snake_case(self.model.__name__), field.name] unique_test = PRINT_TEST_ATTRIBUTE_UNIQUE.format(*data) model_test_case_content.append({'print': unique_test, 'args': None}) add_integrity_error_to_imports = True if add_integrity_error_to_imports: PRINT_IMPORTS.append('from django.db import IntegrityError') return model_test_case_content def __str__(self): printable = list() for print_data in self._generate(): try: if print_data['args'] is not None: printable.append(print_data['print'].format(*print_data['args'])) else: printable.append(print_data['print']) except IndexError as e: print('-' * 74) print('{print} {args}'.format(**print_data)) raise e return '\n'.join(printable)
[docs]class AppModelsTestCaseGenerator(object): def __init__(self, app): self.app = app def _generate(self): app_content = list() for model in self.app.get_models(): model_test_case = ModelTestCaseGenerator(model) app_content.append(model_test_case) return app_content def _get_imports(self): imports_to_print = list(set(PRINT_IMPORTS)) imports_to_print.sort(reverse=True) return '\n'.join(imports_to_print) def __str__(self): printable = list() printable.append(self._get_imports()) for model_test_cases in self._generate(): printable.append(str(model_test_cases)) return '\n'.join(printable)