From bba8b2bb6b1b316b9196b0af1e0748fa9bf8cc91 Mon Sep 17 00:00:00 2001 From: Uliana Trifonova Date: Tue, 5 May 2026 10:58:10 +0200 Subject: [PATCH 1/2] add unit tests --- .gitignore | 19 +++++ conftest.py | 44 +++++++++++ data/bun_data.py | 2 + data/ingredient_data.py | 6 ++ helpers.py | 2 + __init__.py => 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 | Bin 0 -> 276 bytes tests/test_bun.py | 8 ++ tests/test_burger.py | 72 ++++++++++++++++++ tests/test_database.py | 42 ++++++++++ tests/test_ingredient.py | 19 +++++ 16 files changed, 214 insertions(+) create mode 100644 .gitignore create mode 100644 conftest.py create mode 100644 data/bun_data.py create mode 100644 data/ingredient_data.py create mode 100644 helpers.py rename __init__.py => praktikum/__init__.py (100%) 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/test_bun.py create mode 100644 tests/test_burger.py create mode 100644 tests/test_database.py create mode 100644 tests/test_ingredient.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..f119b0f73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +__pycache__/ +*.py[cod] +*.pyo +*.pyd + +venv/ +.env + +.vscode/ +.idea/ + +.pytest_cache/ + +*.log + +allure-results/ + +htmlcov/ +.coverage \ No newline at end of file diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..0a11a00a4 --- /dev/null +++ b/conftest.py @@ -0,0 +1,44 @@ +from praktikum.bun import Bun +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE +from praktikum.ingredient import Ingredient +from data.ingredient_data import INGREDIENT_NAME_SAUCE, INGREDIENT_PRICE_SAUCE +from praktikum.database import Database +from praktikum.burger import Burger +from data.bun_data import BUN_NAME, BUN_PRICE +from unittest.mock import Mock +import pytest + +@pytest.fixture() +def bun(): + return Bun(BUN_NAME, BUN_PRICE) + +@pytest.fixture() +def ingredient(): + return Ingredient(INGREDIENT_TYPE_SAUCE, INGREDIENT_NAME_SAUCE, INGREDIENT_PRICE_SAUCE) + +@pytest.fixture() +def burger(): + burger = Burger() + return burger + +@pytest.fixture() +def mock_bun(): + mock_bun = Mock() + mock_bun.get_price.return_value = BUN_PRICE + mock_bun.get_name.return_value = BUN_NAME + return mock_bun + +@pytest.fixture() +def database(): + database = Database() + return database + +@pytest.fixture() +def make_ingredient(): + def create_mock(name=INGREDIENT_NAME_SAUCE, price=INGREDIENT_PRICE_SAUCE, type=INGREDIENT_TYPE_SAUCE): + mock = Mock() + mock.get_name.return_value = name + mock.get_price.return_value = price + mock.get_type.return_value = type + return mock + return create_mock diff --git a/data/bun_data.py b/data/bun_data.py new file mode 100644 index 000000000..b880c1e91 --- /dev/null +++ b/data/bun_data.py @@ -0,0 +1,2 @@ +BUN_NAME = "burger test_1" +BUN_PRICE = 10 \ No newline at end of file diff --git a/data/ingredient_data.py b/data/ingredient_data.py new file mode 100644 index 000000000..2a8260c49 --- /dev/null +++ b/data/ingredient_data.py @@ -0,0 +1,6 @@ +INGREDIENT_NAME_SAUCE = "test sause" +INGREDIENT_NAME_FILLING = "test filling" + +INGREDIENT_PRICE_SAUCE = 2 +INGREDIENT_PRICE_FILLING = 5 + diff --git a/helpers.py b/helpers.py new file mode 100644 index 000000000..6598cce83 --- /dev/null +++ b/helpers.py @@ -0,0 +1,2 @@ +def calculate_expected_price(bun_price, ingredient_prices): + return (bun_price * 2) + sum(ingredient_prices) \ No newline at end of file diff --git a/__init__.py b/praktikum/__init__.py similarity index 100% rename from __init__.py rename to praktikum/__init__.py 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 0000000000000000000000000000000000000000..5516567fc7351a2aba6a190030206a1271cc1e5a GIT binary patch literal 276 zcmYL^TMEK35Jm5|;8K(}YQ+!t;1;CBP^__ND|GYf$=FoFBw_Bk^Z2}L-PIBgopmFQ zoI-1DiAqZ?l!%wS5rH=md(=`J?wv7>q8cNkF8qQ~4m~l2F&))wUAY59oS6#3O+>4K xe9&nA5+$iW|A}m1Mvu4GbMD}5-rQqE^QgV)2Xm(>(k2}hvbvh~`fro_d;!bJDGLAq literal 0 HcmV?d00001 diff --git a/tests/test_bun.py b/tests/test_bun.py new file mode 100644 index 000000000..2b56f1398 --- /dev/null +++ b/tests/test_bun.py @@ -0,0 +1,8 @@ +from data.bun_data import BUN_NAME, BUN_PRICE + +class TestBun: + def test_get_name_returns_correct_name(self, bun): + assert bun.get_name() == BUN_NAME + + def test_get_price_returns_correct_price(self, bun): + assert bun.get_price() == BUN_PRICE diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..74c3cc854 --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,72 @@ +from data.bun_data import BUN_NAME +from helpers import calculate_expected_price +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING +from data.ingredient_data import INGREDIENT_NAME_FILLING, INGREDIENT_NAME_SAUCE, INGREDIENT_PRICE_SAUCE, INGREDIENT_PRICE_FILLING +import pytest + +class TestBurger: + def test_set_buns_sets_correct_bun(self, burger, mock_bun): + burger.set_buns(mock_bun) + assert burger.bun == mock_bun + + @pytest.mark.parametrize("count", [1, 2]) + def test_add_ingredient_successfully(self, burger, make_ingredient, count): + ingredients = [] + for _ in range(count): + mock_ingredient = make_ingredient() + burger.add_ingredient(mock_ingredient) + ingredients.append(mock_ingredient) + + assert len(burger.ingredients) == count + assert burger.ingredients == ingredients + + def test_remove_ingredient_successfully(self, burger, make_ingredient): + burger.add_ingredient(make_ingredient()) + burger.remove_ingredient(0) + assert burger.ingredients == [] + + def test_move_ingredient_successfully(self, burger, make_ingredient): + mock_ingredient1 = make_ingredient() + mock_ingredient2 = make_ingredient() + + burger.add_ingredient(mock_ingredient1) + burger.add_ingredient(mock_ingredient2) + + burger.move_ingredient(0, 1) + + assert burger.ingredients == [mock_ingredient2, mock_ingredient1] + + def test_get_price_returns_correct_value(self, burger, mock_bun, make_ingredient): + mock_ingredient1 = make_ingredient(INGREDIENT_NAME_SAUCE, INGREDIENT_PRICE_SAUCE, INGREDIENT_TYPE_SAUCE) + mock_ingredient2 = make_ingredient(INGREDIENT_NAME_FILLING, INGREDIENT_PRICE_FILLING, INGREDIENT_TYPE_FILLING) + + burger.set_buns(mock_bun) + + burger.add_ingredient(mock_ingredient1) + burger.add_ingredient(mock_ingredient2) + + ingredient_prices = [mock_ingredient1.get_price(), mock_ingredient2.get_price()] + expected_price = calculate_expected_price(mock_bun.get_price(), ingredient_prices) + + assert burger.get_price() == expected_price + + + def test_get_receipt_format_is_correct(self, burger, mock_bun, make_ingredient): + mock_ingredient1 = make_ingredient(INGREDIENT_NAME_SAUCE, INGREDIENT_PRICE_SAUCE, INGREDIENT_TYPE_SAUCE) + mock_ingredient2 = make_ingredient(INGREDIENT_NAME_FILLING, INGREDIENT_PRICE_FILLING, INGREDIENT_TYPE_FILLING) + + burger.set_buns(mock_bun) + + burger.add_ingredient(mock_ingredient1) + burger.add_ingredient(mock_ingredient2) + + receipt = burger.get_receipt() + ingredient_prices = [mock_ingredient1.get_price(), mock_ingredient2.get_price()] + + expected_price = calculate_expected_price(mock_bun.get_price(), ingredient_prices) + + assert BUN_NAME in receipt + assert INGREDIENT_NAME_SAUCE in receipt + assert INGREDIENT_NAME_FILLING in receipt + assert f"Price: {str(expected_price)}" in receipt + \ No newline at end of file diff --git a/tests/test_database.py b/tests/test_database.py new file mode 100644 index 000000000..026b5b506 --- /dev/null +++ b/tests/test_database.py @@ -0,0 +1,42 @@ +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient + +class TestDatabase: + def test_available_buns(self, database): + assert len(database.available_buns()) == 3 + + def test_available_ingredients(self, database): + assert len(database.available_ingredients()) == 6 + + def test_database_buns_contains_expected_items(self, database): + buns = database.available_buns() + names = [] + for bun in buns: + names.append(bun.get_name()) + + assert "black bun" in names + assert "white bun" in names + assert "red bun" in names + + def test_database_ingredients_contains_expected_items(self, database): + ingredients = database.available_ingredients() + names = [] + for ingredient in ingredients: + names.append(ingredient.get_name()) + + assert "cutlet" in names + assert "dinosaur" in names + assert "sausage" in names + + def test_available_buns_returns_buns(self, database): + buns = database.available_buns() + + for bun in buns: + assert isinstance(bun, Bun) + + def test_available_ingredients_returns_ingredients(self, database): + ingredients = database.available_ingredients() + + for ingredient in ingredients: + assert isinstance(ingredient, Ingredient) + diff --git a/tests/test_ingredient.py b/tests/test_ingredient.py new file mode 100644 index 000000000..238d1ee05 --- /dev/null +++ b/tests/test_ingredient.py @@ -0,0 +1,19 @@ +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING +from praktikum.ingredient import Ingredient +from data.ingredient_data import INGREDIENT_PRICE_SAUCE, INGREDIENT_NAME_SAUCE, INGREDIENT_NAME_FILLING, INGREDIENT_PRICE_FILLING +import pytest + +class TestIngredient: + def test_get_price_returns_correct_price(self, ingredient): + assert ingredient.get_price() == INGREDIENT_PRICE_SAUCE + + def test_get_name_returns_correct_name(self, ingredient): + assert ingredient.get_name() == INGREDIENT_NAME_SAUCE + + @pytest.mark.parametrize("ingredient_obj,expected_type", [ + (Ingredient(INGREDIENT_TYPE_SAUCE, INGREDIENT_NAME_SAUCE, INGREDIENT_PRICE_SAUCE), INGREDIENT_TYPE_SAUCE), + (Ingredient(INGREDIENT_TYPE_FILLING, INGREDIENT_NAME_FILLING, INGREDIENT_PRICE_FILLING), INGREDIENT_TYPE_FILLING) + ]) + def test_get_type_returns_correct_type(self, ingredient_obj, expected_type): + assert ingredient_obj.get_type() == expected_type + \ No newline at end of file From 652ef687a77586bb6b3bfe009cd158efa3f2eae1 Mon Sep 17 00:00:00 2001 From: Uliana Trifonova Date: Wed, 6 May 2026 16:05:42 +0200 Subject: [PATCH 2/2] Fix review comments --- tests/test_database.py | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/tests/test_database.py b/tests/test_database.py index 026b5b506..d9cdac2cf 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -2,41 +2,14 @@ from praktikum.ingredient import Ingredient class TestDatabase: - def test_available_buns(self, database): - assert len(database.available_buns()) == 3 - - def test_available_ingredients(self, database): - assert len(database.available_ingredients()) == 6 - - def test_database_buns_contains_expected_items(self, database): - buns = database.available_buns() - names = [] - for bun in buns: - names.append(bun.get_name()) - - assert "black bun" in names - assert "white bun" in names - assert "red bun" in names - - def test_database_ingredients_contains_expected_items(self, database): - ingredients = database.available_ingredients() - names = [] - for ingredient in ingredients: - names.append(ingredient.get_name()) - - assert "cutlet" in names - assert "dinosaur" in names - assert "sausage" in names - def test_available_buns_returns_buns(self, database): buns = database.available_buns() - for bun in buns: - assert isinstance(bun, Bun) + assert isinstance(buns, list) + assert all(isinstance(bun, Bun) for bun in buns) def test_available_ingredients_returns_ingredients(self, database): ingredients = database.available_ingredients() - for ingredient in ingredients: - assert isinstance(ingredient, Ingredient) - + assert isinstance(ingredients, list) + assert all(isinstance(ingredient, Ingredient) for ingredient in ingredients)