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