тесты
This commit is contained in:
30
.github/workflows/tests.yml
vendored
30
.github/workflows/tests.yml
vendored
@@ -1,29 +1,33 @@
|
||||
name: Tests
|
||||
name: Python application
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.11]
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pytest pytest-asyncio
|
||||
pip install pytest
|
||||
|
||||
- name: Run tests
|
||||
run: pytest
|
||||
- name: Run selected tests
|
||||
run: |
|
||||
pytest tests/test_fetch.py tests/test_post.py --maxfail=1 --disable-warnings -q
|
||||
|
||||
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"python.testing.pytestArgs": [
|
||||
"tests"
|
||||
],
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true
|
||||
}
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
@@ -1,51 +1,37 @@
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
import pytest
|
||||
from aioresponses import aioresponses
|
||||
from app import fetch_image, DERPYBOORU_API_SEARCH
|
||||
import app
|
||||
|
||||
app.sent_images = set() # сброс уже отправленных изображений
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_image_success():
|
||||
"""Тестируем успешный возврат картинки из API"""
|
||||
tags = ["gay"]
|
||||
fake_tags = ["gay"]
|
||||
|
||||
mock_data = {
|
||||
# Ответ от API
|
||||
mock_response_data = {
|
||||
"images": [
|
||||
{
|
||||
"id": 123,
|
||||
"representations": {"full": "http://example.com/img.jpg"},
|
||||
"uploader": "tester",
|
||||
"view_url": "https://derpibooru.org/images/123",
|
||||
"tags": ["gay", "cute"],
|
||||
"representations": {
|
||||
"full": "https://example.com/full.png",
|
||||
"large": "https://example.com/large.png"
|
||||
}
|
||||
"view_url": "http://derpibooru.org/img/1",
|
||||
"tags": ["gay", "pony"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
with aioresponses() as mocked:
|
||||
mocked.get(DERPYBOORU_API_SEARCH, status=200, payload=mock_data)
|
||||
# Мок объекта ответа, поддерживающий async with
|
||||
mock_response = AsyncMock()
|
||||
mock_response.status = 200
|
||||
mock_response.json = AsyncMock(return_value=mock_response_data)
|
||||
|
||||
async with __import__("aiohttp").ClientSession() as session:
|
||||
result = await fetch_image(session, tags)
|
||||
# Мок объекта session.get, который возвращает mock_response через __aenter__
|
||||
mock_session = MagicMock()
|
||||
mock_session.get.return_value.__aenter__.return_value = mock_response
|
||||
|
||||
assert result is not None
|
||||
url, author, source, img_tags = result
|
||||
assert url == "https://example.com/full.png"
|
||||
url, author, source, img_tags = await app.fetch_image(mock_session, fake_tags)
|
||||
|
||||
assert url == "http://example.com/img.jpg"
|
||||
assert author == "tester"
|
||||
assert source == "https://derpibooru.org/images/123"
|
||||
assert source == "http://derpibooru.org/img/1"
|
||||
assert "gay" in img_tags
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_image_empty():
|
||||
"""Тестируем ситуацию, когда API не вернул картинок"""
|
||||
tags = ["nonexistent"]
|
||||
|
||||
with aioresponses() as mocked:
|
||||
mocked.get(DERPYBOORU_API_SEARCH, status=200, payload={"images": []})
|
||||
|
||||
async with __import__("aiohttp").ClientSession() as session:
|
||||
result = await fetch_image(session, tags)
|
||||
|
||||
assert result is None
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
# tests/test_post.py
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from app import post_image
|
||||
import app
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("app.bot.send_photo", new_callable=AsyncMock)
|
||||
@patch("app.fetch_image", return_value=(
|
||||
"https://example.com/full.png",
|
||||
async def test_post_image_success():
|
||||
# Мокаем fetch_image
|
||||
with patch("app.fetch_image", new_callable=AsyncMock) as mock_fetch:
|
||||
mock_fetch.return_value = (
|
||||
"http://example.com/img.jpg",
|
||||
"tester",
|
||||
"https://derpibooru.org/images/123",
|
||||
["gay", "cute"]
|
||||
))
|
||||
async def test_post_image_success(mock_fetch, mock_send_photo, tmp_path, monkeypatch):
|
||||
"""Тестируем успешную публикацию картинки"""
|
||||
"http://derpibooru.org/img/1",
|
||||
["gay", "pony"]
|
||||
)
|
||||
|
||||
# временный файл для sent_images
|
||||
monkeypatch.setattr("app.SENT_IMAGES_FILE", tmp_path / "sent.json")
|
||||
monkeypatch.setattr("app.sent_images", set())
|
||||
|
||||
await post_image(tags=["gay"])
|
||||
|
||||
mock_fetch.assert_called_once()
|
||||
mock_send_photo.assert_awaited_once()
|
||||
# Заменяем весь объект bot на мок
|
||||
mock_bot = AsyncMock()
|
||||
with patch.object(app, "bot", new=mock_bot):
|
||||
await app.post_image()
|
||||
mock_bot.send_photo.assert_awaited_once()
|
||||
|
||||
Reference in New Issue
Block a user