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