0

I have written some tests for model, views and serializer. All tests are running fine except for the serializer tests.

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
........E
======================================================================
ERROR: testapp.tests.test_serializers (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: testapp.tests.test_serializers
Traceback (most recent call last):
  File "C:\Python310\lib\unittest\loader.py", line 436, in _find_test_path
    module = self._get_module_from_name(name)
  File "C:\Python310\lib\unittest\loader.py", line 377, in _get_module_from_name
    __import__(name)
  File "F:\Python\django-advanced\testproj\testapp\tests\test_serializers.py", line 19, in <module>
    AutoSlugField(), from_field(SlugField())
  File "C:\Python310\lib\site-packages\django_extensions\db\fields\__init__.py", line 155, in __init__
    raise ValueError("missing 'populate_from' argument")
ValueError: missing 'populate_from' argument


----------------------------------------------------------------------
Ran 9 tests in 0.034s

FAILED (errors=1)
Destroying test database for alias 'default'...

I am getting the above error when I run

python manage.py test

Here is my file tree - My project name - testproj My app name - testapp

    testproj/
┣ .hypothesis/
┃ ┣ examples/
┃ ┃ ┣ 89906a9970b0f6fa/
┃ ┃ ┃ ┗ 7210af19145ec2a8
┃ ┃ ┗ f79909d6c0990774/
┃ ┃   ┗ 7210af19145ec2a8
┃ ┗ unicode_data/
┃   ┗ 13.0.0/
┃ ┃   ┗ charmap.json.gz
┣ testapp/
┃ ┣ migrations/
┃ ┃ ┣ __pycache__/
┃ ┃ ┃ ┣ 0001_initial.cpython-310.pyc
┃ ┃ ┃ ┣ 0002_alter_tag_name.cpython-310.pyc
┃ ┃ ┃ ┣ __init__.cpython-310.pyc
┃ ┃ ┃ ┗ __init__.cpython-38.pyc
┃ ┃ ┣ 0001_initial.py
┃ ┃ ┣ 0002_alter_tag_name.py
┃ ┃ ┗ __init__.py
┃ ┣ templates/
┃ ┃ ┣ testapp/
┃ ┃ ┃ ┣ base.html
┃ ┃ ┃ ┗ status.html
┃ ┃ ┗ base.html
┃ ┣ tests/
┃ ┃ ┣ __pycache__/
┃ ┃ ┃ ┣ test_models.cpython-310.pyc
┃ ┃ ┃ ┣ test_serializers.cpython-310.pyc
┃ ┃ ┃ ┣ test_views.cpython-310.pyc
┃ ┃ ┃ ┗ __init__.cpython-310.pyc
┃ ┃ ┣ test_models.py
┃ ┃ ┣ test_serializers.py
┃ ┃ ┣ test_views.py
┃ ┃ ┗ __init__.py
┃ ┣ __pycache__/
┃ ┃ ┣ admin.cpython-310.pyc
┃ ┃ ┣ apps.cpython-310.pyc
┃ ┃ ┣ models.cpython-310.pyc
┃ ┃ ┣ serializer.cpython-310.pyc
┃ ┃ ┣ tests.cpython-310.pyc
┃ ┃ ┣ tests.cpython-38.pyc
┃ ┃ ┣ urls.cpython-310.pyc
┃ ┃ ┣ views.cpython-310.pyc
┃ ┃ ┣ __init__.cpython-310.pyc
┃ ┃ ┗ __init__.cpython-38.pyc
┃ ┣ admin.py
┃ ┣ apps.py
┃ ┣ models.py
┃ ┣ serializer.py
┃ ┣ urls.py
┃ ┣ views.py
┃ ┣ viewsets.py
┃ ┗ __init__.py
┣ testproj/
┃ ┣ __pycache__/
┃ ┃ ┣ settings.cpython-310.pyc
┃ ┃ ┣ settings.cpython-38.pyc
┃ ┃ ┣ urls.cpython-310.pyc
┃ ┃ ┣ urls.cpython-38.pyc
┃ ┃ ┣ wsgi.cpython-310.pyc
┃ ┃ ┣ __init__.cpython-310.pyc
┃ ┃ ┗ __init__.cpython-38.pyc
┃ ┣ asgi.py
┃ ┣ checks.py
┃ ┣ settings.py
┃ ┣ urls.py
┃ ┣ wsgi.py
┃ ┗ __init__.py
┣ db.sqlite3
┣ manage.py
┗ requirements.txt

It is running 9 tests as shown.

My test_serializers.py file

from django.db.models import SlugField
from django_extensions.db.fields import AutoSlugField

from hypothesis import assume, given
from hypothesis.extra.django import (
    TestCase,
    from_model,
    from_field,
    register_field_strategy
)

from hypothesis.strategies import text

from ..models import Tag
from ..serializer import TagSerializer


register_field_strategy(
    AutoSlugField(), from_field(SlugField())
)

class TagSerializerTests(TestCase):

    @given(
        text(
            min_size=1,
            max_size=Tag._meta.get_field("name").max_length
        )
    )
    def test_data_serialization(self, name):
        assume(name.strip() == name)
        s1_tag = TagSerializer(data={name: "name"})
        self.assertTrue(s1_tag.is_valid(), s1_tag.errors)
        tag = s1_tag.save()
        s2_tag = TagSerializer(tag)
        self.assertTrue(s2_tag.data[name], "name")
    
    @given(from_model(Tag))
    def test_model_serialization(self, tag):
        assume(tag.name.strip() == tag.name)
        s1_tag = TagSerializer(tag)
        self.assertTrue(tag.name, s1_tag.data["name"])
        self.assertTrue(tag.slug, s1_tag.data["slug"])
        tag.delete()
        s2_tag = TagSerializer(data=s1_tag.data)
        self.assertTrue(s2_tag.is_valid(), s2_tag.errors)
        new_tag = s2_tag.save()
        self.assertTrue(tag.name, new_tag.name)
        self.assertTrue(tag.slug, new_tag.slug)

I do not know why it is running test_models and test_views tests but not serializers.

My settings.py file for reference -

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-@j#vm2#s=c*r+uijybeq)&ym&j1puy*i41mi2dy!pu7dn*3t_t'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'testapp.apps.TestappConfig',
    'django_extensions',
    'rest_framework'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'testproj.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'testproj.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': str(os.path.join(BASE_DIR, "db.sqlite3"))
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Edit: Included models.py field because of the ValueError mentioned in the log.

from django.db import models
from django_extensions.db.fields import AutoSlugField
from django.urls import reverse

class Tag(models.Model):

    name =  models.CharField(max_length=31, unique=True)
    slug = AutoSlugField(
        max_length=31,
        populate_from=["name"]
        )
    
    class Meta:
        ordering = ["name"]
    
    def get_absolute_url(self):
        url = reverse("tag_detail", kwargs={"slug": self.slug})
        return url
    
    def __str__(self) -> str:
        return self.name
Innomight
  • 556
  • 3
  • 15

1 Answers1

0

Line 19 of your test module is register_field_strategy(AutoSlugField(), from_field(SlugField())). You try to create an instance of AutoSlugField with no argument, but a populate_from named parameter is mandatory. See the implementation: https://github.com/django-extensions/django-extensions/blob/main/django_extensions/db/fields/__init__.py#L155

Nielk
  • 760
  • 1
  • 6
  • 22
  • Thanks for the reply. I provided the parameter AutoSlugField(populate_from=["name"]). Now I am getting this error - TypeError: issubclass() arg 1 must be a class. So the error is clear but it is showing error in the hypothesis site package file. So, I dont know where I have to provide class as a parameter. – Innomight Feb 04 '22 at 06:33