mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2024-11-10 21:56:34 +03:00
added better test fixtures
This commit is contained in:
parent
1fc003636b
commit
b59c8fbf8b
|
@ -1,14 +1,122 @@
|
|||
import pytest
|
||||
import io
|
||||
import logging
|
||||
import re
|
||||
|
||||
from akarpov.users.models import User
|
||||
from akarpov.users.tests.factories import UserFactory
|
||||
import factory
|
||||
import pytest
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from pytest_django.lazy_django import skip_if_no_django
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from akarpov.utils.config import build_redis_uri
|
||||
from akarpov.utils.faker import configure_factory_faker, configure_faker
|
||||
from akarpov.utils.pytest_factoryboy import autodiscover_factories
|
||||
|
||||
configure_factory_faker(factory.Faker)
|
||||
|
||||
autodiscover_factories()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def media_storage(settings, tmpdir):
|
||||
settings.MEDIA_ROOT = tmpdir.strpath
|
||||
def activate_django_db(db):
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def update_config():
|
||||
from django.conf import settings
|
||||
|
||||
settings.DEBUG = True
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user(db) -> User:
|
||||
return UserFactory()
|
||||
def api_client():
|
||||
return APIClient()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def admin_client(client, user_factory):
|
||||
admin_user = user_factory(is_superuser=True, is_staff=True)
|
||||
client.force_login(admin_user)
|
||||
return client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def api_user_client(api_client, user):
|
||||
api_client.force_authenticate(user)
|
||||
return api_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def image_factory():
|
||||
def factory(filename="test.jpg", **params):
|
||||
from PIL import Image
|
||||
|
||||
width = params.get("width", 520)
|
||||
height = params.get("height", width)
|
||||
color = params.get("color", "blue")
|
||||
image_format = params.get("format", "JPEG")
|
||||
image_palette = params.get("palette", "RGB")
|
||||
|
||||
thumb_io = io.BytesIO()
|
||||
with Image.new(image_palette, (width, height), color) as thumb:
|
||||
thumb.save(thumb_io, format=image_format)
|
||||
return SimpleUploadedFile(filename, thumb_io.getvalue())
|
||||
|
||||
return factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def image(image_factory):
|
||||
return image_factory()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def uploaded_photo(image):
|
||||
return SimpleUploadedFile("test.png", image.read())
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def plain_file():
|
||||
return io.BytesIO(b"plain_text")
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def faker_session_locale():
|
||||
return ["en"]
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def add_faker_providers(faker):
|
||||
configure_faker(faker)
|
||||
return faker
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def set_test_redis_databases(request):
|
||||
from django.conf import settings
|
||||
|
||||
skip_if_no_django()
|
||||
xdist_worker = getattr(request.config, "workerinput", {}).get("workerid")
|
||||
if xdist_worker is None:
|
||||
return
|
||||
worker_number_search = re.search(r"\d+", xdist_worker)
|
||||
if not worker_number_search:
|
||||
return
|
||||
max_db_number = worker_number_search[0]
|
||||
max_db_number = int(max_db_number) * 3 + 2
|
||||
channels_redis_url = build_redis_uri(
|
||||
settings.CHANNELS_REDIS_HOST,
|
||||
settings.CHANNELS_REDIS_PORT,
|
||||
settings.CHANNELS_REDIS_USER,
|
||||
settings.CHANNELS_REDIS_PASSWORD,
|
||||
max_db_number,
|
||||
)
|
||||
settings.CHANNEL_LAYERS["default"]["CONFIG"]["hosts"][0][
|
||||
"address"
|
||||
] = channels_redis_url
|
||||
settings.CHANNELS_REDIS_DB = max_db_number
|
||||
settings.CLICKHOUSE_REDIS_CONFIG["db"] = max_db_number - 1
|
||||
settings.CELERY_REDIS_DB = max_db_number - 2
|
||||
|
|
|
@ -1,45 +1,20 @@
|
|||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from factory import Faker, post_generation
|
||||
import factory.fuzzy
|
||||
from factory.django import DjangoModelFactory
|
||||
|
||||
from akarpov.utils.faker import django_image
|
||||
from akarpov.utils.pytest_factoryboy import global_register
|
||||
|
||||
|
||||
@global_register
|
||||
class UserFactory(DjangoModelFactory):
|
||||
username = Faker("user_name")
|
||||
email = Faker("email")
|
||||
name = Faker("name")
|
||||
about = Faker("text")
|
||||
|
||||
@post_generation
|
||||
def password(self, create: bool, extracted: Sequence[Any], **kwargs):
|
||||
password = (
|
||||
extracted
|
||||
if extracted
|
||||
else Faker(
|
||||
"password",
|
||||
length=42,
|
||||
special_chars=True,
|
||||
digits=True,
|
||||
upper_case=True,
|
||||
lower_case=True,
|
||||
).evaluate(None, None, extra={"locale": None})
|
||||
)
|
||||
self.set_password(password)
|
||||
|
||||
@post_generation
|
||||
def image(self, create, extracted, **kwargs):
|
||||
if extracted:
|
||||
image_name, image = extracted
|
||||
else:
|
||||
image_name = "test.jpg"
|
||||
image = django_image(image_name, **kwargs)
|
||||
self.image.save(image_name, image)
|
||||
email = factory.Sequence(lambda i: f"user_{i}@akarpov.ru")
|
||||
username = factory.Faker("word")
|
||||
image = factory.fuzzy.FuzzyText(prefix="https://img")
|
||||
password = "P@ssw0rd"
|
||||
|
||||
class Meta:
|
||||
model = get_user_model()
|
||||
skip_postgeneration_save = False
|
||||
django_get_or_create = ["username"]
|
||||
model = "users.User"
|
||||
|
||||
@classmethod
|
||||
def _create(cls, model_class, *args, **kwargs):
|
||||
manager = cls._get_manager(model_class)
|
||||
return manager.create_user(*args, **kwargs)
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
from akarpov.files.consts import USER_INITIAL_FILE_UPLOAD
|
||||
from akarpov.users.models import User
|
||||
|
||||
|
||||
def test_user_create(user: User):
|
||||
def test_user_create(user_factory):
|
||||
user = user_factory()
|
||||
password = "123"
|
||||
user.set_password(password)
|
||||
assert user.check_password(password)
|
||||
|
||||
|
||||
def test_auto_file_upload_size(user: User):
|
||||
def test_auto_file_upload_size(user_factory):
|
||||
user = user_factory()
|
||||
size = USER_INITIAL_FILE_UPLOAD
|
||||
assert user.left_file_upload == size
|
||||
|
||||
|
||||
def test_user_image_create(user: User):
|
||||
def test_user_image_create(user_factory):
|
||||
user = user_factory()
|
||||
assert user.image
|
||||
|
|
|
@ -15,9 +15,9 @@ def money(self):
|
|||
|
||||
|
||||
def configure_factory_faker(factory_faker):
|
||||
factory_faker._DEFAULT_LOCALE = "ru_RU"
|
||||
factory_faker._DEFAULT_LOCALE = "en"
|
||||
for provider in additional_providers:
|
||||
factory_faker.add_provider(provider, locale="ru_RU")
|
||||
factory_faker.add_provider(provider, locale="en")
|
||||
|
||||
|
||||
def configure_faker(faker):
|
||||
|
|
47
akarpov/utils/pytest_factoryboy.py
Normal file
47
akarpov/utils/pytest_factoryboy.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
from django.utils.module_loading import autodiscover_modules
|
||||
from pytest_factoryboy.fixture import get_caller_locals, register
|
||||
|
||||
|
||||
class RegisteredFactory:
|
||||
def __init__(self, factory_class, args, kwargs):
|
||||
self.factory_class = factory_class
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
|
||||
factory_registry = set() # set of registered factories
|
||||
|
||||
|
||||
def global_register(factory_class=None, *args, **kwargs):
|
||||
if factory_class is None:
|
||||
|
||||
def _global_register(factory_class):
|
||||
return global_register(factory_class, *args, **kwargs)
|
||||
|
||||
return _global_register
|
||||
|
||||
factory_registry.add(RegisteredFactory(factory_class, args, kwargs))
|
||||
|
||||
return factory_class
|
||||
|
||||
|
||||
def autodiscover_factories():
|
||||
assert (
|
||||
not factory_registry
|
||||
), "You've already called `autodiscover_factories` function"
|
||||
|
||||
caller_locals = get_caller_locals()
|
||||
|
||||
assert caller_locals["__name__"].endswith(
|
||||
"conftest"
|
||||
), "You must call `autodiscover_factories` from `conftest.py` file"
|
||||
|
||||
autodiscover_modules("tests.factories")
|
||||
|
||||
for registered_factory in factory_registry:
|
||||
register(
|
||||
registered_factory.factory_class,
|
||||
*registered_factory.args,
|
||||
_caller_locals=caller_locals,
|
||||
**registered_factory.kwargs,
|
||||
)
|
143
poetry.lock
generated
143
poetry.lock
generated
|
@ -213,6 +213,18 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)"]
|
|||
test = ["anyio[trio]", "coverage[toml] (>=7)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
||||
trio = ["trio (>=0.22)"]
|
||||
|
||||
[[package]]
|
||||
name = "appdirs"
|
||||
version = "1.4.4"
|
||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
|
||||
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "appnope"
|
||||
version = "0.1.3"
|
||||
|
@ -2213,6 +2225,21 @@ files = [
|
|||
dnspython = ">=2.0.0"
|
||||
idna = ">=2.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "execnet"
|
||||
version = "2.0.2"
|
||||
description = "execnet: rapid multi-Python deployment"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"},
|
||||
{file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
testing = ["hatch", "pre-commit", "pytest", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "executing"
|
||||
version = "1.2.0"
|
||||
|
@ -3589,6 +3616,26 @@ html5 = ["html5lib"]
|
|||
htmlsoup = ["BeautifulSoup4"]
|
||||
source = ["Cython (>=0.29.35)"]
|
||||
|
||||
[[package]]
|
||||
name = "mako"
|
||||
version = "1.2.4"
|
||||
description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "Mako-1.2.4-py3-none-any.whl", hash = "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818"},
|
||||
{file = "Mako-1.2.4.tar.gz", hash = "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=0.9.2"
|
||||
|
||||
[package.extras]
|
||||
babel = ["Babel"]
|
||||
lingua = ["lingua"]
|
||||
testing = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "markdown"
|
||||
version = "3.4.4"
|
||||
|
@ -5202,6 +5249,25 @@ pluggy = ">=0.12,<2.0"
|
|||
[package.extras]
|
||||
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-asyncio"
|
||||
version = "0.21.1"
|
||||
description = "Pytest support for asyncio"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-asyncio-0.21.1.tar.gz", hash = "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d"},
|
||||
{file = "pytest_asyncio-0.21.1-py3-none-any.whl", hash = "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=7.0.0"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
|
||||
testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-django"
|
||||
version = "4.5.2"
|
||||
|
@ -5221,6 +5287,60 @@ pytest = ">=5.4.0"
|
|||
docs = ["sphinx", "sphinx-rtd-theme"]
|
||||
testing = ["Django", "django-configurations (>=2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-factoryboy"
|
||||
version = "2.3.1"
|
||||
description = "Factory Boy support for pytest."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-factoryboy-2.3.1.tar.gz", hash = "sha256:5102ce8597d1d8db2436f1fcfe96635f212801e18e14c2f04327a9343b9b56d7"},
|
||||
{file = "pytest_factoryboy-2.3.1-py3-none-any.whl", hash = "sha256:e8c249c8c5c195ecd46f86377dbe92451372295a9485d42060e3f82ee23b1ff6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
appdirs = "*"
|
||||
factory-boy = ">=2.10.0"
|
||||
inflection = "*"
|
||||
mako = "*"
|
||||
pytest = ">=5.0.0"
|
||||
typing-extensions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pytest-lambda"
|
||||
version = "2.2.0"
|
||||
description = "Define pytest fixtures with lambda functions."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0,<4.0.0"
|
||||
files = [
|
||||
{file = "pytest-lambda-2.2.0.tar.gz", hash = "sha256:f8af7b011980b04499d906161b69e7df984a8b16285a17ca97eb133a0775dd58"},
|
||||
{file = "pytest_lambda-2.2.0-py3-none-any.whl", hash = "sha256:ad77ff48a514379bfccb404ba9d3f5871c2a0817b47ccc8abbad430d6d450ef4"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=3.6,<8"
|
||||
wrapt = ">=1.11.0,<2.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "pytest-mock"
|
||||
version = "3.11.1"
|
||||
description = "Thin-wrapper around the mock package for easier use with pytest"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-mock-3.11.1.tar.gz", hash = "sha256:7f6b125602ac6d743e523ae0bfa71e1a697a2f5534064528c6ff84c2f7c2fc7f"},
|
||||
{file = "pytest_mock-3.11.1-py3-none-any.whl", hash = "sha256:21c279fff83d70763b05f8874cc9cfb3fcacd6d354247a976f9529d19f9acf39"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=5.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "pytest-asyncio", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-sugar"
|
||||
version = "0.9.7"
|
||||
|
@ -5241,6 +5361,27 @@ termcolor = ">=2.1.0"
|
|||
[package.extras]
|
||||
dev = ["black", "flake8", "pre-commit"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-xdist"
|
||||
version = "3.3.1"
|
||||
description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pytest-xdist-3.3.1.tar.gz", hash = "sha256:d5ee0520eb1b7bcca50a60a518ab7a7707992812c578198f8b44fdfac78e8c93"},
|
||||
{file = "pytest_xdist-3.3.1-py3-none-any.whl", hash = "sha256:ff9daa7793569e6a68544850fd3927cd257cc03a7ef76c95e86915355e82b5f2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
execnet = ">=1.1"
|
||||
pytest = ">=6.2.0"
|
||||
|
||||
[package.extras]
|
||||
psutil = ["psutil (>=3.0)"]
|
||||
setproctitle = ["setproctitle"]
|
||||
testing = ["filelock"]
|
||||
|
||||
[[package]]
|
||||
name = "python-crontab"
|
||||
version = "3.0.0"
|
||||
|
@ -8043,4 +8184,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "78a5ef3c902cae4b5e808da8eed517b8b649800ca567d67a7c004eb1b5de8147"
|
||||
content-hash = "07c6933d3ce4f4d081cffbe7b7ad4e3561a0353e1f8157961916ca7502549914"
|
||||
|
|
|
@ -102,6 +102,11 @@ requests = ">=2.25"
|
|||
spacy = {extras = ["lookups"], version = "^3.6.1"}
|
||||
spacy-transformers = "^1.2.5"
|
||||
extract-msg = "0.28.7"
|
||||
pytest-factoryboy = "2.3.1"
|
||||
pytest-xdist = "^3.3.1"
|
||||
pytest-mock = "^3.11.1"
|
||||
pytest-asyncio = "^0.21.1"
|
||||
pytest-lambda = "^2.2.0"
|
||||
|
||||
|
||||
[build-system]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
[pytest]
|
||||
addopts = --ds=config.settings.test --reuse-db
|
||||
python_files = tests.py test_*.py
|
||||
DJANGO_SETTINGS_MODULE = config.settings.test
|
||||
python_files = tests.py test_*.py *_tests.py
|
||||
addopts = --reuse-db
|
||||
|
|
Loading…
Reference in New Issue
Block a user