From 8d75c082cfe4e8734d8e72914bd65009cd498d8a Mon Sep 17 00:00:00 2001 From: Dmitry Titenkov Date: Mon, 16 Feb 2026 12:51:43 +0300 Subject: [PATCH 1/2] pytest --- requirements.txt | 2 ++ tests/conftest.py | 54 ++++++++++++++++++++++++++++++++++++ tests/test_bot_storage.py | 37 ++++++++++++++++++++++++ tests/test_spider_storage.py | 10 +++++++ 4 files changed, 103 insertions(+) create mode 100644 tests/conftest.py create mode 100644 tests/test_bot_storage.py create mode 100644 tests/test_spider_storage.py diff --git a/requirements.txt b/requirements.txt index 9c4da35..278ff90 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +aiosqlite==0.22.1 anyio==4.12.1 APScheduler==3.11.2 asyncpg==0.31.0 @@ -45,6 +46,7 @@ pyflakes==3.4.0 Pygments==2.19.2 pyOpenSSL==25.3.0 pytest==9.0.2 +pytest-asyncio==1.3.0 python-dotenv==1.2.1 python-telegram-bot==22.6 pytokens==0.4.0 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..2699173 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,54 @@ +import pytest +import pytest_asyncio +from sqlalchemy import create_engine +from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker +from sqlalchemy.orm import sessionmaker + +from db.models import Base, News + + +DATABASE_SYNC_URL = "sqlite:///:memory:" +DATABASE_ASYNC_URL = "sqlite+aiosqlite:///:memory:" + + +@pytest.fixture +def session(): + engine = create_engine(DATABASE_SYNC_URL, echo=False) + Base.metadata.create_all(engine) + Session = sessionmaker(engine) + session = Session() + yield session + session.close() + + +@pytest_asyncio.fixture +async def async_session(): + engine = create_async_engine(DATABASE_ASYNC_URL, echo=False) + async with engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) + AsyncSession = async_sessionmaker(engine, expire_on_commit=False) + async with AsyncSession() as async_session: + yield async_session + await engine.dispose() + + +@pytest.fixture +def news(): + test_news = { + 'url': 'https://panorama.pub/test-news', + 'title': 'Test Title', + 'text': 'Test Text', + 'image': None + } + return test_news + + +@pytest_asyncio.fixture +async def news_list(async_session): + first_news = News(url="https://panorama.pub/test-news_1", title="Test Title 1", image=None, text="Ttest Text_1") + second_news = News(url="https://panorama.pub/test-news_2", title="Test Title 2", image=None, text="Ttest Text_2") + + async_session.add_all([first_news, second_news]) + await async_session.commit() + + return [first_news, second_news] diff --git a/tests/test_bot_storage.py b/tests/test_bot_storage.py new file mode 100644 index 0000000..9d13804 --- /dev/null +++ b/tests/test_bot_storage.py @@ -0,0 +1,37 @@ +import pytest + +from bot.bot_storage import get_last_sent_id, save_last_sent_news_id, get_news_after_id, get_all_users + + +@pytest.mark.asyncio +async def test_get_last_sent_id(async_session): + """Проверка id последней отправленой новости""" + chat_id = 100 + + last_id = await get_last_sent_id(chat_id, async_session) + assert last_id == 0, "id последней отпрвленной новости должен быть равен 0, если нет отправленных новостей" + + await save_last_sent_news_id(chat_id=chat_id, last_id=10, session=async_session) + last_id = await get_last_sent_id(chat_id, async_session) + assert last_id == 10, "id последней отпрвленной новости должен быть равен 10" + + +@pytest.mark.asyncio +async def test_get_news_after_id(async_session, news_list): + """Получение новостей""" + news = await get_news_after_id(last_id=0, session=async_session) + assert len(news) == 2, "Должно быть получено 2 новости" + assert news[0].title == "Test Title 1", "Заголовок первой новости должен быть 'Test Title 1'" + assert news[1].title == "Test Title 2", "Заголовок второй новости должен быть 'Test Title 2'" + + +@pytest.mark.asyncio +async def test_get_all_users(async_session): + """Получение пользователей""" + await save_last_sent_news_id(chat_id=111, last_id=11, session=async_session) + await save_last_sent_news_id(chat_id=222, last_id=22, session=async_session) + + users = await get_all_users(async_session) + assert len(users) == 2, "Должно быть 2 пользователя в базе" + assert users[0] == 111, "id первого юзера должен быть 111" + assert users[1] == 222, "id второго юзеера должен быть 222" diff --git a/tests/test_spider_storage.py b/tests/test_spider_storage.py new file mode 100644 index 0000000..6cff57c --- /dev/null +++ b/tests/test_spider_storage.py @@ -0,0 +1,10 @@ +from satire_pulp_parser.spider_storage import is_news_exists, save_news + + +def test_save_and_check_news(session, news): + """Проверяет что новостей нет в базе, + сохранение новости + и новость появилась в базе после сохранения.""" + assert not is_news_exists(news['url'], session), "Перед сохраением новой новости её не должно быть в базе" + save_news(news["url"], news["title"], news['image'], news["text"], session=session) + assert is_news_exists(news["url"], session), "Новость должна появиться в базе после сохранения" From 6ee7e1d4a47aacf0e35ebdba4089fc495918a174 Mon Sep 17 00:00:00 2001 From: Dmitry Titenkov Date: Mon, 16 Feb 2026 13:00:11 +0300 Subject: [PATCH 2/2] pytest --- tests/conftest.py | 28 ++++++++++++++++---------- tests/test_bot_storage.py | 38 ++++++++++++++++++++++++++---------- tests/test_spider_storage.py | 16 ++++++++++++--- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 2699173..158038b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,12 +1,10 @@ import pytest import pytest_asyncio +from db.models import Base, News from sqlalchemy import create_engine -from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker +from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine from sqlalchemy.orm import sessionmaker -from db.models import Base, News - - DATABASE_SYNC_URL = "sqlite:///:memory:" DATABASE_ASYNC_URL = "sqlite+aiosqlite:///:memory:" @@ -35,18 +33,28 @@ async def async_session(): @pytest.fixture def news(): test_news = { - 'url': 'https://panorama.pub/test-news', - 'title': 'Test Title', - 'text': 'Test Text', - 'image': None + "url": "https://panorama.pub/test-news", + "title": "Test Title", + "text": "Test Text", + "image": None, } return test_news @pytest_asyncio.fixture async def news_list(async_session): - first_news = News(url="https://panorama.pub/test-news_1", title="Test Title 1", image=None, text="Ttest Text_1") - second_news = News(url="https://panorama.pub/test-news_2", title="Test Title 2", image=None, text="Ttest Text_2") + first_news = News( + url="https://panorama.pub/test-news_1", + title="Test Title 1", + image=None, + text="Ttest Text_1", + ) + second_news = News( + url="https://panorama.pub/test-news_2", + title="Test Title 2", + image=None, + text="Ttest Text_2", + ) async_session.add_all([first_news, second_news]) await async_session.commit() diff --git a/tests/test_bot_storage.py b/tests/test_bot_storage.py index 9d13804..032ad6f 100644 --- a/tests/test_bot_storage.py +++ b/tests/test_bot_storage.py @@ -1,6 +1,10 @@ import pytest - -from bot.bot_storage import get_last_sent_id, save_last_sent_news_id, get_news_after_id, get_all_users +from bot.bot_storage import ( + get_all_users, + get_last_sent_id, + get_news_after_id, + save_last_sent_news_id, +) @pytest.mark.asyncio @@ -9,11 +13,17 @@ async def test_get_last_sent_id(async_session): chat_id = 100 last_id = await get_last_sent_id(chat_id, async_session) - assert last_id == 0, "id последней отпрвленной новости должен быть равен 0, если нет отправленных новостей" + assert ( + last_id == 0 + ), "id последней отпрвленной новости должен быть равен 0, если нет отправленных новостей" - await save_last_sent_news_id(chat_id=chat_id, last_id=10, session=async_session) + await save_last_sent_news_id( + chat_id=chat_id, last_id=10, session=async_session + ) last_id = await get_last_sent_id(chat_id, async_session) - assert last_id == 10, "id последней отпрвленной новости должен быть равен 10" + assert ( + last_id == 10 + ), "id последней отпрвленной новости должен быть равен 10" @pytest.mark.asyncio @@ -21,17 +31,25 @@ async def test_get_news_after_id(async_session, news_list): """Получение новостей""" news = await get_news_after_id(last_id=0, session=async_session) assert len(news) == 2, "Должно быть получено 2 новости" - assert news[0].title == "Test Title 1", "Заголовок первой новости должен быть 'Test Title 1'" - assert news[1].title == "Test Title 2", "Заголовок второй новости должен быть 'Test Title 2'" + assert ( + news[0].title == "Test Title 1" + ), "Заголовок первой новости должен быть 'Test Title 1'" + assert ( + news[1].title == "Test Title 2" + ), "Заголовок второй новости должен быть 'Test Title 2'" @pytest.mark.asyncio async def test_get_all_users(async_session): """Получение пользователей""" - await save_last_sent_news_id(chat_id=111, last_id=11, session=async_session) - await save_last_sent_news_id(chat_id=222, last_id=22, session=async_session) + await save_last_sent_news_id( + chat_id=111, last_id=11, session=async_session + ) + await save_last_sent_news_id( + chat_id=222, last_id=22, session=async_session + ) users = await get_all_users(async_session) assert len(users) == 2, "Должно быть 2 пользователя в базе" assert users[0] == 111, "id первого юзера должен быть 111" - assert users[1] == 222, "id второго юзеера должен быть 222" + assert users[1] == 222, "id второго юзеера должен быть 222" diff --git a/tests/test_spider_storage.py b/tests/test_spider_storage.py index 6cff57c..fa3817e 100644 --- a/tests/test_spider_storage.py +++ b/tests/test_spider_storage.py @@ -5,6 +5,16 @@ def test_save_and_check_news(session, news): """Проверяет что новостей нет в базе, сохранение новости и новость появилась в базе после сохранения.""" - assert not is_news_exists(news['url'], session), "Перед сохраением новой новости её не должно быть в базе" - save_news(news["url"], news["title"], news['image'], news["text"], session=session) - assert is_news_exists(news["url"], session), "Новость должна появиться в базе после сохранения" + assert not is_news_exists( + news["url"], session + ), "Перед сохраением новой новости её не должно быть в базе" + save_news( + news["url"], + news["title"], + news["image"], + news["text"], + session=session, + ) + assert is_news_exists( + news["url"], session + ), "Новость должна появиться в базе после сохранения"