From ad7b00b4d37fdfb61525a7122f79a45b172ff15c Mon Sep 17 00:00:00 2001 From: Kirill Pahamovich Date: Sat, 15 Aug 2026 14:47:38 +0300 Subject: [PATCH 1/3] =?UTF-8?q?1=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20-=20=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 18 +++ praktikum/__init__.py | 0 bun.py => praktikum/bun.py | 0 burger.py => praktikum/burger.py | 0 database.py => praktikum/database.py | 0 ingredient.py => praktikum/ingredient.py | 0 .../ingredient_types.py | 0 requirements.txt | 2 + tests/__init__.py | 0 tests/burger_test.py | 136 ++++++++++++++++++ 10 files changed, 156 insertions(+) create mode 100644 .gitignore create mode 100644 praktikum/__init__.py rename bun.py => praktikum/bun.py (100%) rename burger.py => praktikum/burger.py (100%) rename database.py => praktikum/database.py (100%) rename ingredient.py => praktikum/ingredient.py (100%) rename ingredient_types.py => praktikum/ingredient_types.py (100%) create mode 100644 requirements.txt create mode 100644 tests/__init__.py create mode 100644 tests/burger_test.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..96229d8e1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +.venv/ +venv/ +env/ + +__pycache__/ +*.py[cod] +*.egg-info/ + +.pytest_cache/ +.coverage +.coverage.* +htmlcov/ +coverage.xml + +.idea/ +.vscode/ +.DS_Store +Thumbs.db 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 100% rename from burger.py rename to praktikum/burger.py diff --git a/database.py b/praktikum/database.py similarity index 100% rename from database.py rename to praktikum/database.py 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 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..9955deccd --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pytest +pytest-cov diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/burger_test.py b/tests/burger_test.py new file mode 100644 index 000000000..66a147993 --- /dev/null +++ b/tests/burger_test.py @@ -0,0 +1,136 @@ +import pytest +from unittest.mock import Mock + +from praktikum.burger import Burger +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + + +class TestBurger: + """Класс с юнит-тестами для модели бургера Burger.""" + + def test_init_default_values(self): + """Проверяем, что при инициализации булочка пустая, а список ингредиентов пуст.""" + burger = Burger() + assert burger.bun is None + assert burger.ingredients == [] + + def test_set_buns(self): + """Проверяем корректность установки булочки в бургер.""" + burger = Burger() + mock_bun = Mock(spec=Bun) + + burger.set_buns(mock_bun) + + assert burger.bun == mock_bun + + def test_add_ingredient(self): + """Проверяем добавление ингредиента в бургер.""" + burger = Burger() + mock_ingredient = Mock(spec=Ingredient) + + burger.add_ingredient(mock_ingredient) + + assert mock_ingredient in burger.ingredients + assert len(burger.ingredients) == 1 + + def test_remove_ingredient(self): + """Проверяем удаление ингредиента по индексу.""" + burger = Burger() + mock_ingredient1 = Mock(spec=Ingredient) + mock_ingredient2 = Mock(spec=Ingredient) + burger.add_ingredient(mock_ingredient1) + burger.add_ingredient(mock_ingredient2) + + burger.remove_ingredient(0) + + assert mock_ingredient1 not in burger.ingredients + assert burger.ingredients == [mock_ingredient2] + + def test_move_ingredient(self): + """Проверяем перемещение ингредиента с одной позиции на другую.""" + burger = Burger() + mock_ingredient1 = Mock(spec=Ingredient) + mock_ingredient2 = Mock(spec=Ingredient) + mock_ingredient3 = Mock(spec=Ingredient) + + burger.add_ingredient(mock_ingredient1) + burger.add_ingredient(mock_ingredient2) + burger.add_ingredient(mock_ingredient3) + + # Перемещаем ингредиент с индекса 2 на индекс 0 + burger.move_ingredient(2, 0) + + assert burger.ingredients == [mock_ingredient3, mock_ingredient1, mock_ingredient2] + + @pytest.mark.parametrize( + "bun_price, ingredient_prices, expected_price", + [ + (100, [50, 75], 325), # Булочка (100*2) + два ингредиента + (200, [], 400), # Только булочка (200*2), без ингредиентов + (50, [10, 20, 30], 160) # Булочка (50*2) + три ингредиента + ] + ) + def test_get_price(self, bun_price, ingredient_prices, expected_price): + """Проверяем корректность подсчета стоимости бургера (с параметризацией).""" + burger = Burger() + + mock_bun = Mock(spec=Bun) + mock_bun.get_price.return_value = bun_price + burger.set_buns(mock_bun) + + for price in ingredient_prices: + mock_ing = Mock(spec=Ingredient) + mock_ing.get_price.return_value = price + burger.add_ingredient(mock_ing) + + assert burger.get_price() == expected_price + + @pytest.mark.parametrize("ing_type, expected_type_str", [ + (INGREDIENT_TYPE_SAUCE, "sauce"), + (INGREDIENT_TYPE_FILLING, "filling") + ]) + def test_get_receipt_with_one_ingredient(self, ing_type, expected_type_str): + """Проверяем генерацию чека с одним ингредиентом (параметризация типов).""" + burger = Burger() + + mock_bun = Mock(spec=Bun) + mock_bun.get_name.return_value = "black bun" + mock_bun.get_price.return_value = 100 + + mock_ing = Mock(spec=Ingredient) + mock_ing.get_type.return_value = ing_type + mock_ing.get_name.return_value = "test ingredient" + mock_ing.get_price.return_value = 50 + + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ing) + + # Ожидаемая строка чека (обрати внимание на переносы строк \n) + expected_receipt = ( + "(==== black bun ====)\n" + f"= {expected_type_str} test ingredient =\n" + "(==== black bun ====)\n" + "\n" + "Price: 250" + ) + assert burger.get_receipt() == expected_receipt + + def test_get_receipt_without_ingredients(self): + """Проверяем генерацию чека без ингредиентов (покрываем пустой цикл for).""" + burger = Burger() + + mock_bun = Mock(spec=Bun) + mock_bun.get_name.return_value = "white bun" + mock_bun.get_price.return_value = 200 + + burger.set_buns(mock_bun) + + expected_receipt = ( + "(==== white bun ====)\n" + "(==== white bun ====)\n" + "\n" + "Price: 400" + ) + assert burger.get_receipt() == expected_receipt \ No newline at end of file From 59823ff9ac6b2cd29998ef6ab43f696f7490bf4b Mon Sep 17 00:00:00 2001 From: Kirill Pahamovich Date: Sat, 15 Aug 2026 15:01:34 +0300 Subject: [PATCH 2/3] =?UTF-8?q?1=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20-=20=D0=9F=D0=BE=D0=BB=D0=BD=D0=BE=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0,=20=D0=BD=D0=BE=20=D0=BD=D1=83=D0=B6=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=BF=D0=B8=D0=BB=D0=B8=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/bun_test.py | 18 ++++++++++++++++++ tests/database_test.py | 35 +++++++++++++++++++++++++++++++++++ tests/ingredient_test.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 tests/bun_test.py create mode 100644 tests/database_test.py create mode 100644 tests/ingredient_test.py diff --git a/tests/bun_test.py b/tests/bun_test.py new file mode 100644 index 000000000..7e664240c --- /dev/null +++ b/tests/bun_test.py @@ -0,0 +1,18 @@ +import pytest +from praktikum.bun import Bun + + +class TestBun: + + def test_bun_creation(self): + bun = Bun("white bun", 150.5) + assert bun.name == "white bun" + assert bun.price == 150.5 + + def test_get_name(self): + bun = Bun("black bun", 100) + assert bun.get_name() == "black bun" + + def test_get_price(self): + bun = Bun("red bun", 200) + assert bun.get_price() == 200 diff --git a/tests/database_test.py b/tests/database_test.py new file mode 100644 index 000000000..a1f34673c --- /dev/null +++ b/tests/database_test.py @@ -0,0 +1,35 @@ +import pytest +from praktikum.database import Database +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + + +class TestDatabase: + + def test_database_initialization(self): + db = Database() + # Проверяем, что булочки созданы (их 3) + assert len(db.buns) == 3 + # Проверяем, что ингредиенты созданы (их 6) + assert len(db.ingredients) == 6 + + def test_available_buns(self): + db = Database() + buns = db.available_buns() + assert len(buns) == 3 + assert buns[0].get_name() == "black bun" + assert buns[0].get_price() == 100 + assert buns[1].get_name() == "white bun" + assert buns[2].get_name() == "red bun" + + def test_available_ingredients(self): + db = Database() + ingredients = db.available_ingredients() + assert len(ingredients) == 6 + # Проверим первые три соуса + assert ingredients[0].get_type() == INGREDIENT_TYPE_SAUCE + assert ingredients[0].get_name() == "hot sauce" + assert ingredients[0].get_price() == 100 + # Проверим первые три начинки (индексы 3,4,5) + assert ingredients[3].get_type() == INGREDIENT_TYPE_FILLING + assert ingredients[3].get_name() == "cutlet" + assert ingredients[3].get_price() == 100 diff --git a/tests/ingredient_test.py b/tests/ingredient_test.py new file mode 100644 index 000000000..14576f0bf --- /dev/null +++ b/tests/ingredient_test.py @@ -0,0 +1,28 @@ +import pytest +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + + +class TestIngredient: + + @pytest.mark.parametrize("ing_type, name, price", [ + (INGREDIENT_TYPE_SAUCE, "chili sauce", 50.0), + (INGREDIENT_TYPE_FILLING, "cutlet", 120.0), + ]) + def test_ingredient_creation(self, ing_type, name, price): + ingredient = Ingredient(ing_type, name, price) + assert ingredient.type == ing_type + assert ingredient.name == name + assert ingredient.price == price + + def test_get_price(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "sour cream", 75.5) + assert ingredient.get_price() == 75.5 + + def test_get_name(self): + ingredient = Ingredient(INGREDIENT_TYPE_FILLING, "dinosaur", 200) + assert ingredient.get_name() == "dinosaur" + + def test_get_type(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100) + assert ingredient.get_type() == INGREDIENT_TYPE_SAUCE From 9e2bc75f9421dfe932f91079b4853ee164385ba1 Mon Sep 17 00:00:00 2001 From: Kirill Pahamovich Date: Sat, 15 Aug 2026 15:16:04 +0300 Subject: [PATCH 3/3] =?UTF-8?q?1=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20-=20=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- praktikum.py | 19 +++------------ tests/bun_test.py | 2 -- tests/burger_test.py | 51 ++++++++++++---------------------------- tests/database_test.py | 14 +++++------ tests/ingredient_test.py | 6 ++--- 5 files changed, 26 insertions(+), 66 deletions(-) diff --git a/praktikum.py b/praktikum.py index ec522fa6d..0d2826829 100644 --- a/praktikum.py +++ b/praktikum.py @@ -5,37 +5,24 @@ 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() + 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/tests/bun_test.py b/tests/bun_test.py index 7e664240c..c0e797bae 100644 --- a/tests/bun_test.py +++ b/tests/bun_test.py @@ -1,7 +1,5 @@ -import pytest from praktikum.bun import Bun - class TestBun: def test_bun_creation(self): diff --git a/tests/burger_test.py b/tests/burger_test.py index 66a147993..b242344ab 100644 --- a/tests/burger_test.py +++ b/tests/burger_test.py @@ -1,23 +1,18 @@ import pytest from unittest.mock import Mock - from praktikum.burger import Burger from praktikum.bun import Bun from praktikum.ingredient import Ingredient from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING - class TestBurger: - """Класс с юнит-тестами для модели бургера Burger.""" - def test_init_default_values(self): - """Проверяем, что при инициализации булочка пустая, а список ингредиентов пуст.""" + def test_init_default_values(self): # Проверка того, что при инициализации булочка и список ингредиентов пустые burger = Burger() assert burger.bun is None assert burger.ingredients == [] - def test_set_buns(self): - """Проверяем корректность установки булочки в бургер.""" + def test_set_buns(self): # Проверка корректности установки булочки в бургер burger = Burger() mock_bun = Mock(spec=Bun) @@ -25,31 +20,25 @@ def test_set_buns(self): assert burger.bun == mock_bun - def test_add_ingredient(self): - """Проверяем добавление ингредиента в бургер.""" + def test_add_ingredient(self): # Проверка добавления ингредиента в бургер burger = Burger() mock_ingredient = Mock(spec=Ingredient) - burger.add_ingredient(mock_ingredient) - assert mock_ingredient in burger.ingredients assert len(burger.ingredients) == 1 - def test_remove_ingredient(self): - """Проверяем удаление ингредиента по индексу.""" + def test_remove_ingredient(self): # Проверка удаления ингредиента по индексу burger = Burger() mock_ingredient1 = Mock(spec=Ingredient) mock_ingredient2 = Mock(spec=Ingredient) burger.add_ingredient(mock_ingredient1) burger.add_ingredient(mock_ingredient2) - burger.remove_ingredient(0) assert mock_ingredient1 not in burger.ingredients assert burger.ingredients == [mock_ingredient2] - def test_move_ingredient(self): - """Проверяем перемещение ингредиента с одной позиции на другую.""" + def test_move_ingredient(self): # Проверка перемещения ингредиента с одной позиции на другую burger = Burger() mock_ingredient1 = Mock(spec=Ingredient) mock_ingredient2 = Mock(spec=Ingredient) @@ -58,9 +47,7 @@ def test_move_ingredient(self): burger.add_ingredient(mock_ingredient1) burger.add_ingredient(mock_ingredient2) burger.add_ingredient(mock_ingredient3) - - # Перемещаем ингредиент с индекса 2 на индекс 0 - burger.move_ingredient(2, 0) + burger.move_ingredient(2, 0) # Перемещение ингредиента с индекса 2 на индекс 0 assert burger.ingredients == [mock_ingredient3, mock_ingredient1, mock_ingredient2] @@ -72,10 +59,8 @@ def test_move_ingredient(self): (50, [10, 20, 30], 160) # Булочка (50*2) + три ингредиента ] ) - def test_get_price(self, bun_price, ingredient_prices, expected_price): - """Проверяем корректность подсчета стоимости бургера (с параметризацией).""" + def test_get_price(self, bun_price, ingredient_prices, expected_price): # Проверка корректности подсчета стоимости бургера + параметризация burger = Burger() - mock_bun = Mock(spec=Bun) mock_bun.get_price.return_value = bun_price burger.set_buns(mock_bun) @@ -89,12 +74,10 @@ def test_get_price(self, bun_price, ingredient_prices, expected_price): @pytest.mark.parametrize("ing_type, expected_type_str", [ (INGREDIENT_TYPE_SAUCE, "sauce"), - (INGREDIENT_TYPE_FILLING, "filling") - ]) - def test_get_receipt_with_one_ingredient(self, ing_type, expected_type_str): - """Проверяем генерацию чека с одним ингредиентом (параметризация типов).""" + (INGREDIENT_TYPE_FILLING, "filling")]) + + def test_get_receipt_with_one_ingredient(self, ing_type, expected_type_str): # Проверка генерации чека с одним ингредиентом + параметриз. burger = Burger() - mock_bun = Mock(spec=Bun) mock_bun.get_name.return_value = "black bun" mock_bun.get_price.return_value = 100 @@ -107,20 +90,17 @@ def test_get_receipt_with_one_ingredient(self, ing_type, expected_type_str): burger.set_buns(mock_bun) burger.add_ingredient(mock_ing) - # Ожидаемая строка чека (обрати внимание на переносы строк \n) + # Ожидаемая строка чека expected_receipt = ( "(==== black bun ====)\n" f"= {expected_type_str} test ingredient =\n" "(==== black bun ====)\n" "\n" - "Price: 250" - ) + "Price: 250") assert burger.get_receipt() == expected_receipt - def test_get_receipt_without_ingredients(self): - """Проверяем генерацию чека без ингредиентов (покрываем пустой цикл for).""" + def test_get_receipt_without_ingredients(self): # Проверка генерации чека без ингредиентов burger = Burger() - mock_bun = Mock(spec=Bun) mock_bun.get_name.return_value = "white bun" mock_bun.get_price.return_value = 200 @@ -131,6 +111,5 @@ def test_get_receipt_without_ingredients(self): "(==== white bun ====)\n" "(==== white bun ====)\n" "\n" - "Price: 400" - ) - assert burger.get_receipt() == expected_receipt \ No newline at end of file + "Price: 400") + assert burger.get_receipt() == expected_receipt diff --git a/tests/database_test.py b/tests/database_test.py index a1f34673c..44e8f9942 100644 --- a/tests/database_test.py +++ b/tests/database_test.py @@ -1,16 +1,12 @@ -import pytest from praktikum.database import Database from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING - class TestDatabase: def test_database_initialization(self): db = Database() - # Проверяем, что булочки созданы (их 3) - assert len(db.buns) == 3 - # Проверяем, что ингредиенты созданы (их 6) - assert len(db.ingredients) == 6 + assert len(db.buns) == 3 # Проверка того, что булочки созданы (3 шт.) + assert len(db.ingredients) == 6 # Проверка того, что ингредиенты созданы (6 шт.) def test_available_buns(self): db = Database() @@ -25,11 +21,13 @@ def test_available_ingredients(self): db = Database() ingredients = db.available_ingredients() assert len(ingredients) == 6 - # Проверим первые три соуса + + # Проверка первых трех соусов assert ingredients[0].get_type() == INGREDIENT_TYPE_SAUCE assert ingredients[0].get_name() == "hot sauce" assert ingredients[0].get_price() == 100 - # Проверим первые три начинки (индексы 3,4,5) + + # Проверка первых трех начинок (индексы 3,4,5) assert ingredients[3].get_type() == INGREDIENT_TYPE_FILLING assert ingredients[3].get_name() == "cutlet" assert ingredients[3].get_price() == 100 diff --git a/tests/ingredient_test.py b/tests/ingredient_test.py index 14576f0bf..bf8d15b4c 100644 --- a/tests/ingredient_test.py +++ b/tests/ingredient_test.py @@ -2,13 +2,11 @@ from praktikum.ingredient import Ingredient from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING - class TestIngredient: - @pytest.mark.parametrize("ing_type, name, price", [ (INGREDIENT_TYPE_SAUCE, "chili sauce", 50.0), - (INGREDIENT_TYPE_FILLING, "cutlet", 120.0), - ]) + (INGREDIENT_TYPE_FILLING, "cutlet", 120.0),]) + def test_ingredient_creation(self, ing_type, name, price): ingredient = Ingredient(ing_type, name, price) assert ingredient.type == ing_type