Working factories
This commit is contained in:
43
poetry.lock
generated
43
poetry.lock
generated
@ -31,6 +31,23 @@ 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)"]
|
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)"]
|
trio = ["trio (>=0.22)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-factory-boy"
|
||||||
|
version = "1.0.1"
|
||||||
|
description = "factory_boy extension with asynchronous ORM support"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "async_factory_boy-1.0.1-py2.py3-none-any.whl", hash = "sha256:a0a652776ee164b60a45be06aca44a18781710447de1c534dda82d6cfe23f026"},
|
||||||
|
{file = "async_factory_boy-1.0.1.tar.gz", hash = "sha256:af3a42d9c26b86cc427faf5159ac2e8541b5564bf30424282eb866620af4e143"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
factory-boy = ">=3.0.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["SQLAlchemy", "coverage", "flake8", "isort", "tortoise-orm (>=0.18.1)", "tox", "wheel (>=0.32.0)", "zest.releaser[recommended]"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asyncpg"
|
name = "asyncpg"
|
||||||
version = "0.28.0"
|
version = "0.28.0"
|
||||||
@ -120,15 +137,33 @@ files = [
|
|||||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "factory-boy"
|
||||||
|
version = "3.3.0"
|
||||||
|
description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "factory_boy-3.3.0-py2.py3-none-any.whl", hash = "sha256:a2cdbdb63228177aa4f1c52f4b6d83fab2b8623bf602c7dedd7eb83c0f69c04c"},
|
||||||
|
{file = "factory_boy-3.3.0.tar.gz", hash = "sha256:bc76d97d1a65bbd9842a6d722882098eb549ec8ee1081f9fb2e8ff29f0c300f1"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
Faker = ">=0.7.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["Django", "Pillow", "SQLAlchemy", "coverage", "flake8", "isort", "mongoengine", "sqlalchemy-utils", "tox", "wheel (>=0.32.0)", "zest.releaser[recommended]"]
|
||||||
|
doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "faker"
|
name = "faker"
|
||||||
version = "19.6.1"
|
version = "19.6.2"
|
||||||
description = "Faker is a Python package that generates fake data for you."
|
description = "Faker is a Python package that generates fake data for you."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "Faker-19.6.1-py3-none-any.whl", hash = "sha256:64c8513c53c3a809075ee527b323a0ba61517814123f3137e4912f5d43350139"},
|
{file = "Faker-19.6.2-py3-none-any.whl", hash = "sha256:8fba91068dc26e3159c1ac9f22444a2338704b0991d86605322e454bda420092"},
|
||||||
{file = "Faker-19.6.1.tar.gz", hash = "sha256:5d6b7880b3bea708075ddf91938424453f07053a59f8fa0453c1870df6ff3292"},
|
{file = "Faker-19.6.2.tar.gz", hash = "sha256:d5d5953556b0fb428a46019e03fc2d40eab2980135ddef5a9eb3d054947fdf83"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -974,4 +1009,4 @@ anyio = ">=3.0.0"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.11"
|
python-versions = "^3.11"
|
||||||
content-hash = "2f47c374edfb8ee537dd4eeb7406bd443bdf0ed3bdd760e764a363ffd1b4650f"
|
content-hash = "553608e41acc31171494d556b327cd6a0f0b5f78846a9a888485f53baa46bee4"
|
||||||
|
|||||||
@ -19,6 +19,9 @@ pydantic-settings = "^2.0.3"
|
|||||||
pytest = "^7.4.2"
|
pytest = "^7.4.2"
|
||||||
watchfiles = "^0.20.0"
|
watchfiles = "^0.20.0"
|
||||||
pytest-asyncio = "^0.21.1"
|
pytest-asyncio = "^0.21.1"
|
||||||
|
async-factory-boy = "^1.0.1"
|
||||||
|
factory-boy = "^3.3.0"
|
||||||
|
faker = "^19.6.2"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|||||||
0
tests/endpoints/__init__.py
Normal file
0
tests/endpoints/__init__.py
Normal file
0
tests/factories/__init__.py
Normal file
0
tests/factories/__init__.py
Normal file
15
tests/factories/city_factory.py
Normal file
15
tests/factories/city_factory.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import factory
|
||||||
|
from faker import Faker
|
||||||
|
|
||||||
|
from app.domain.city import City
|
||||||
|
from tests.factories.factory_base import FactoryBase
|
||||||
|
|
||||||
|
fake = Faker()
|
||||||
|
|
||||||
|
|
||||||
|
class CityFactory(FactoryBase):
|
||||||
|
name = factory.Faker("city")
|
||||||
|
postal_code = factory.Faker("postcode")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = City
|
||||||
11
tests/factories/factory_base.py
Normal file
11
tests/factories/factory_base.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from async_factory_boy.factory.sqlalchemy import AsyncSQLAlchemyFactory
|
||||||
|
from sqlalchemy.orm import scoped_session
|
||||||
|
|
||||||
|
from tests.conftest import async_session_factory
|
||||||
|
|
||||||
|
session = scoped_session(async_session_factory)
|
||||||
|
|
||||||
|
|
||||||
|
class FactoryBase(AsyncSQLAlchemyFactory):
|
||||||
|
class Meta:
|
||||||
|
sqlalchemy_session = session
|
||||||
28
tests/test_cities.py
Normal file
28
tests/test_cities.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import pytest
|
||||||
|
from litestar.status_codes import HTTP_200_OK
|
||||||
|
from litestar.testing import AsyncTestClient
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from main import app
|
||||||
|
from tests.factories.city_factory import CityFactory
|
||||||
|
|
||||||
|
|
||||||
|
class TestCitiesEndpoints:
|
||||||
|
@pytest.fixture(scope="function", autouse=True)
|
||||||
|
def setup_class(self, db_session: AsyncSession):
|
||||||
|
self.db_session = db_session
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_get(self):
|
||||||
|
city_1 = await CityFactory.create()
|
||||||
|
city_2 = await CityFactory.create()
|
||||||
|
city_3 = await CityFactory.create()
|
||||||
|
city_4 = await CityFactory.create()
|
||||||
|
city_5 = await CityFactory.create()
|
||||||
|
|
||||||
|
async with AsyncTestClient(app=app) as client:
|
||||||
|
response = await client.get("/v1/cities")
|
||||||
|
print("#" * 100)
|
||||||
|
print(response.content)
|
||||||
|
print("#" * 100)
|
||||||
|
assert response.status_code == HTTP_200_OK
|
||||||
@ -2,35 +2,25 @@
|
|||||||
# https://coderpad.io/blog/development/a-guide-to-database-unit-testing-with-pytest-and-sqlalchemy/
|
# https://coderpad.io/blog/development/a-guide-to-database-unit-testing-with-pytest-and-sqlalchemy/
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from sqlalchemy import text, event
|
from sqlalchemy import text
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from app.domain.city import City
|
from tests.factories.city_factory import CityFactory
|
||||||
from app.lib import settings
|
|
||||||
from app.lib.sqlalchemy_plugin import engine
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
import pytest_asyncio
|
|
||||||
import sqlalchemy
|
|
||||||
from sqlalchemy.ext.asyncio import (
|
|
||||||
AsyncSession,
|
|
||||||
create_async_engine,
|
|
||||||
async_scoped_session,
|
|
||||||
AsyncConnection,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestGeneral:
|
class TestGeneral:
|
||||||
@pytest.fixture(scope="function", autouse=True)
|
@pytest.fixture(scope="function", autouse=True)
|
||||||
def setup_class(self, db_session):
|
def setup_class(self, db_session: AsyncSession):
|
||||||
self.db_session = db_session
|
self.db_session = db_session
|
||||||
|
|
||||||
# async def teardown_class(self):
|
|
||||||
# await self.session.rollback()
|
|
||||||
# await self.session.close()
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_bla(self):
|
async def test_get_cities(self):
|
||||||
|
city_1 = await CityFactory.create()
|
||||||
|
city_2 = await CityFactory.create()
|
||||||
|
city_3 = await CityFactory.create()
|
||||||
|
city_4 = await CityFactory.create()
|
||||||
|
city_5 = await CityFactory.create()
|
||||||
|
|
||||||
stmt = text("select * from cities")
|
stmt = text("select * from cities")
|
||||||
result = await self.db_session.execute(stmt)
|
result = await self.db_session.execute(stmt)
|
||||||
print("#" * 100)
|
print("#" * 100)
|
||||||
|
|||||||
Reference in New Issue
Block a user