From 68afade26620622cf63394abe5ab3fa5a304c32f Mon Sep 17 00:00:00 2001 From: Baik2222 Date: Mon, 17 Nov 2025 14:03:43 +0000 Subject: [PATCH 1/5] =?UTF-8?q?=D0=9D=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлены: .gitignore, requirements.txt - Обновлен: README.md --- .gitignore | 4 ++++ README.md | 24 +++++++++++++++++------- requirements.txt | 3 +++ 3 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 .gitignore create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..f52455ebb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +.venv/ +.vscode/ +__pycache__/ diff --git a/README.md b/README.md index 272081708..742b0f25c 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,34 @@ -## Задание 1: Юнит-тесты +# Задание 1: Юнит-тесты -### Автотесты для проверки программы, которая помогает заказать бургер в Stellar Burgers +--- -### Реализованные сценарии +## Описание: + +Автотесты для проверки программы, которая помогает заказать бургер в Stellar Burgers + +--- + +## Реализованные сценарии Созданы юнит-тесты, покрывающие классы `Bun`, `Burger`, `Ingredient`, `Database` Процент покрытия 100% (отчет: `htmlcov/index.html`) -### Структура проекта +--- + +## Структура проекта - `praktikum` - пакет, содержащий код программы - `tests` - пакет, содержащий тесты, разделенные по классам. Например, `bun_test.py`, `burger_test.py` и т.д. -### Запуск автотестов +--- + +## Запуск автотестов **Установка зависимостей** -> `$ pip install -r requirements.txt` +> `pip install -r requirements.txt` **Запуск автотестов и создание HTML-отчета о покрытии** -> `$ pytest --cov=praktikum --cov-report=html` +> `pytest --cov=praktikum --cov-report=html` diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..eae7d339a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +allure-pytest==2.15.0 +pytest==8.4.2 +pytest-cov==7.0.0 From e15e4d326343b17b40a2ecdc70b30aee1efc72ed Mon Sep 17 00:00:00 2001 From: Baik2222 Date: Mon, 17 Nov 2025 14:04:24 +0000 Subject: [PATCH 2/5] Core --- core/__init__.py | 0 core/utils/__init__.py | 4 ++++ core/utils/create_fake_bun.py | 16 ++++++++++++++++ core/utils/create_fake_ingredient.py | 12 ++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 core/__init__.py create mode 100644 core/utils/__init__.py create mode 100644 core/utils/create_fake_bun.py create mode 100644 core/utils/create_fake_ingredient.py diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/core/utils/__init__.py b/core/utils/__init__.py new file mode 100644 index 000000000..5c8104d4d --- /dev/null +++ b/core/utils/__init__.py @@ -0,0 +1,4 @@ +from .create_fake_bun import get_bun_mock +from .create_fake_ingredient import get_ingredient_mock + +__all__ = ["get_ingredient_mock", "get_bun_mock"] diff --git a/core/utils/create_fake_bun.py b/core/utils/create_fake_bun.py new file mode 100644 index 000000000..5591ea8a4 --- /dev/null +++ b/core/utils/create_fake_bun.py @@ -0,0 +1,16 @@ +import uuid +from unittest.mock import Mock + + +def get_bun_mock() -> Mock: + mock = Mock() + + mock.get_name.return_value = f"fake_bun_{uuid.uuid4()}" + mock.get_price.return_value = 1 + mock.get_type.return_value = "fake_bun_type" + + return mock + + +if __name__ == "__main__": + print(uuid.uuid4()) diff --git a/core/utils/create_fake_ingredient.py b/core/utils/create_fake_ingredient.py new file mode 100644 index 000000000..83255c971 --- /dev/null +++ b/core/utils/create_fake_ingredient.py @@ -0,0 +1,12 @@ +import uuid +from unittest.mock import Mock + + +def get_ingredient_mock() -> Mock: + mock = Mock() + + mock.get_name.return_value = f"fake_ingredient_{uuid.uuid4()}" + mock.get_price.return_value = 1 + mock.get_type.return_value = "fake_ingredient_type" + + return mock From 9dbd82c77c6ef46299b190a30fc7dda4197508bd Mon Sep 17 00:00:00 2001 From: Baik2222 Date: Mon, 17 Nov 2025 14:05:35 +0000 Subject: [PATCH 3/5] =?UTF-8?q?=D0=A1=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83?= =?UTF-8?q?=D1=80=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Тестируемые файлы перенесены в пакет praktikum - Удален файл praktikum.py --- praktikum.py | 41 ------------------- praktikum/__init__.py | 0 bun.py => praktikum/bun.py | 0 burger.py => praktikum/burger.py | 4 +- database.py => praktikum/database.py | 6 +-- ingredient.py => praktikum/ingredient.py | 0 .../ingredient_types.py | 0 7 files changed, 5 insertions(+), 46 deletions(-) delete mode 100644 praktikum.py create mode 100644 praktikum/__init__.py rename bun.py => praktikum/bun.py (100%) rename burger.py => praktikum/burger.py (95%) rename database.py => praktikum/database.py (86%) rename ingredient.py => praktikum/ingredient.py (100%) rename ingredient_types.py => praktikum/ingredient_types.py (100%) diff --git a/praktikum.py b/praktikum.py deleted file mode 100644 index ec522fa6d..000000000 --- a/praktikum.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import List - -from praktikum.bun import Bun -from praktikum.burger import Burger -from praktikum.database import Database -from praktikum.ingredient import Ingredient - - -def main(): - # Инициализируем базу данных - database: Database = Database() - - # Создадим новый бургер - burger: Burger = Burger() - - # Считаем список доступных булок из базы данных - buns: List[Bun] = database.available_buns() - - # Считаем список доступных ингредиентов из базы данных - ingredients: List[Ingredient] = database.available_ingredients() - - # Соберём бургер - burger.set_buns(buns[0]) - - burger.add_ingredient(ingredients[1]) - burger.add_ingredient(ingredients[4]) - burger.add_ingredient(ingredients[3]) - burger.add_ingredient(ingredients[5]) - - # Переместим слой с ингредиентом - burger.move_ingredient(2, 1) - - # Удалим ингредиент - burger.remove_ingredient(3) - - # Распечатаем рецепт бургера - print(burger.get_receipt()) - - -if __name__ == "__main__": - main() diff --git a/praktikum/__init__.py b/praktikum/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bun.py b/praktikum/bun.py similarity index 100% rename from bun.py rename to praktikum/bun.py diff --git a/burger.py b/praktikum/burger.py similarity index 95% rename from burger.py rename to praktikum/burger.py index 2b3b6a88b..a33cc7c4f 100644 --- a/burger.py +++ b/praktikum/burger.py @@ -1,7 +1,7 @@ from typing import List -from praktikum.bun import Bun -from praktikum.ingredient import Ingredient +from .bun import Bun +from .ingredient import Ingredient class Burger: diff --git a/database.py b/praktikum/database.py similarity index 86% rename from database.py rename to praktikum/database.py index 4c75baf71..b99c35512 100644 --- a/database.py +++ b/praktikum/database.py @@ -1,8 +1,8 @@ from typing import List -from praktikum.bun import Bun -from praktikum.ingredient import Ingredient -from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING +from .bun import Bun +from .ingredient import Ingredient +from .ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING class Database: diff --git a/ingredient.py b/praktikum/ingredient.py similarity index 100% rename from ingredient.py rename to praktikum/ingredient.py diff --git a/ingredient_types.py b/praktikum/ingredient_types.py similarity index 100% rename from ingredient_types.py rename to praktikum/ingredient_types.py From efe30f08c09f4b7c7794f6158ab0706b8f686952 Mon Sep 17 00:00:00 2001 From: Baik2222 Date: Mon, 17 Nov 2025 14:06:18 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=84=D0=B0=D0=B9=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f52455ebb..e4149ff4b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .venv/ .vscode/ __pycache__/ +.coverage From a13f9b30981130067d21dccd48e0695abe95b7f7 Mon Sep 17 00:00:00 2001 From: Baik2222 Date: Mon, 17 Nov 2025 14:10:34 +0000 Subject: [PATCH 5/5] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/__init__.py | 0 tests/conftest.py | 46 +++++++++++++++++++++ tests/test_bun.py | 20 +++++++++ tests/test_burger.py | 87 +++++++++++++++++++++++++++++++++++++++ tests/test_database.py | 24 +++++++++++ tests/test_ingredients.py | 27 ++++++++++++ 6 files changed, 204 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_bun.py create mode 100644 tests/test_burger.py create mode 100644 tests/test_database.py create mode 100644 tests/test_ingredients.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..6f8dbebb3 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,46 @@ +from typing import Callable +from unittest.mock import Mock + +import pytest + +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import * +from core.utils import get_bun_mock, get_ingredient_mock + + +@pytest.fixture +def get_fake_bun() -> Callable: + def _inner(count: int = 1) -> list[Mock]: + return [get_bun_mock() for _ in range(count)] + + return _inner + + +@pytest.fixture +def get_fake_ingredient() -> Callable: + def _inner(count: int = 1) -> list[Mock]: + return [get_ingredient_mock() for _ in range(count)] + + return _inner + + +@pytest.fixture +def get_buns_from_db() -> list[Bun]: + return [ + Bun("black bun", 100), + Bun("white bun", 200), + Bun("red bun", 300), + ] + + +@pytest.fixture +def get_ingredients_from_db() -> list[Ingredient]: + return [ + Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100), + Ingredient(INGREDIENT_TYPE_SAUCE, "sour cream", 200), + Ingredient(INGREDIENT_TYPE_SAUCE, "chili sauce", 300), + Ingredient(INGREDIENT_TYPE_FILLING, "cutlet", 100), + Ingredient(INGREDIENT_TYPE_FILLING, "dinosaur", 200), + Ingredient(INGREDIENT_TYPE_FILLING, "sausage", 300), + ] diff --git a/tests/test_bun.py b/tests/test_bun.py new file mode 100644 index 000000000..9fcfcfdbe --- /dev/null +++ b/tests/test_bun.py @@ -0,0 +1,20 @@ +import pytest + +from praktikum.bun import Bun + + +class TestBun: + + @pytest.mark.parametrize("name", ["Бриошь", "Рисовая", " ", ""]) + def test_return_correct_name_when_bun_is_created(self, name): + bun = Bun(name, 1.5) + + assert bun.get_name() == name + assert bun.name == name + + @pytest.mark.parametrize("price", [5, -5, 0.0, 1.5]) + def test_return_correct_price_when_bun_is_created(self, price): + bun = Bun("fake_bun", price) + + assert bun.get_price() == price + assert bun.price == price diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..f1aad3f48 --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,87 @@ +from praktikum.burger import Burger + + +class TestBurger: + + def test_set_correct_bun_when_burger_is_created(self, get_fake_bun): + burger = Burger() + fake_bun, *_ = get_fake_bun() + + burger.set_buns(fake_bun) + assert burger.bun.get_name() == fake_bun.get_name() + + def test_add_ingredient_to_burger(self, get_fake_ingredient): + burger = Burger() + ingredient, *_ = get_fake_ingredient() + + burger.add_ingredient(ingredient) + assert burger.ingredients[0] == ingredient + + def test_add_multiple_ingredients_to_burger(self, get_fake_ingredient): + burger = Burger() + ingredient, *_ = get_fake_ingredient() + n = 5 + + for _ in range(n): + burger.add_ingredient(ingredient) + + assert len(burger.ingredients) == n + + def test_remove_ingredient_from_burger(self, get_fake_ingredient): + burger = Burger() + ingredient, *_ = get_fake_ingredient() + + burger.add_ingredient(ingredient) + burger.remove_ingredient(0) + + assert len(burger.ingredients) == 0 + + def test_swap_ingredient_in_burger(self, get_fake_ingredient): + burger = Burger() + n = 3 + + first, second, third = get_fake_ingredient(n) + + burger.add_ingredient(first) + burger.add_ingredient(second) + burger.add_ingredient(third) + + burger.move_ingredient(1, 2) + + assert burger.ingredients == [first, third, second] + + def test_return_correct_price_when_burger_is_created(self, get_fake_bun, get_fake_ingredient): + burger = Burger() + n = 3 + price = 5 + fake_bun, *_ = get_fake_bun() + + burger.set_buns(fake_bun) + first, second, third = get_fake_ingredient(n) + + burger.add_ingredient(first) + burger.add_ingredient(second) + burger.add_ingredient(third) + + assert burger.get_price() == price + + def test_return_correct_receipt_when_burger_is_created(self, get_fake_bun, get_fake_ingredient): + burger = Burger() + n = 3 + fake_bun, *_ = get_fake_bun() + + burger.set_buns(fake_bun) + first, second, third = get_fake_ingredient(n) + + burger.add_ingredient(first) + burger.add_ingredient(second) + burger.add_ingredient(third) + + assert burger.get_receipt() == ( + f"(==== {fake_bun.get_name()} ====)\n" + f"= {first.get_type()} {first.get_name()} =\n" + f"= {second.get_type()} {second.get_name()} =\n" + f"= {third.get_type()} {third.get_name()} =\n" + f"(==== {fake_bun.get_name()} ====)\n\n" + "Price: 5" + ) diff --git a/tests/test_database.py b/tests/test_database.py new file mode 100644 index 000000000..1ecc7e110 --- /dev/null +++ b/tests/test_database.py @@ -0,0 +1,24 @@ +from praktikum.database import Database + + +class TestDatabase: + + def test_return_correct_buns_from_db(self, get_buns_from_db): + db = Database() + available_buns = db.available_buns() + n = 3 + + assert len(available_buns) == n + + for available_bun, bun_from_db in zip(available_buns, get_buns_from_db): + assert available_bun.get_name() == bun_from_db.get_name() + + def test_return_correct_ingredients_from_db(self, get_ingredients_from_db): + db = Database() + available_ingredients = db.available_ingredients() + n = 6 + + assert len(available_ingredients) == n + + for available_ingredient, ingredient_from_db in zip(available_ingredients, get_ingredients_from_db): + assert available_ingredient.get_name() == ingredient_from_db.get_name() diff --git a/tests/test_ingredients.py b/tests/test_ingredients.py new file mode 100644 index 000000000..dcf7b5703 --- /dev/null +++ b/tests/test_ingredients.py @@ -0,0 +1,27 @@ +import pytest + +from praktikum.ingredient import Ingredient + + +class TestIngredient: + + @pytest.mark.parametrize("name", ["чесночный", "кетчуп", ""]) + def test_return_correct_name_when_ingredient_is_created(self, name): + ingredient = Ingredient("соус", name, 1.0) + + assert ingredient.get_name() == name + assert ingredient.name == name + + @pytest.mark.parametrize("curr_type", ["соус", "начинка", ""]) + def test_return_correct_type_when_ingredient_is_created(self, curr_type): + ingredient = Ingredient(curr_type, "fake_ingredient", 1.5) + + assert ingredient.get_type() == curr_type + assert ingredient.type == curr_type + + @pytest.mark.parametrize("price", [5, -5, 0.0, 1.5]) + def test_return_correct_price_when_ingredient_is_created(self, price): + ingredient = Ingredient("fake_type", "fake_ingredient", price) + + assert ingredient.get_price() == price + assert ingredient.price == price