diff --git a/.coverage b/.coverage new file mode 100644 index 000000000..a12a9f547 Binary files /dev/null and b/.coverage differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..85776222b --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +venv/ +env/ +ENV/ +.venv/ + +*.pyc +*.pyo +*.pyd +*.pyc +__pycache__/ +.python-version + + +.cache/ +*.swp +*.swo +.idea/ + +.pytest_cache \ No newline at end of file diff --git a/README.md b/README.md index 272081708..1843aa87b 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,14 @@ ### Реализованные сценарии -Созданы юнит-тесты, покрывающие классы `Bun`, `Burger`, `Ingredient`, `Database` +Созданы юнит-тесты, покрывающие класс `Burger` Процент покрытия 100% (отчет: `htmlcov/index.html`) ### Структура проекта - `praktikum` - пакет, содержащий код программы -- `tests` - пакет, содержащий тесты, разделенные по классам. Например, `bun_test.py`, `burger_test.py` и т.д. +- `tests` - пакет, содержащий тесты ### Запуск автотестов diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..9c9372aef --- /dev/null +++ b/conftest.py @@ -0,0 +1,37 @@ +import pytest +from unittest.mock import Mock +from data import TEST_BUN, TEST_SAUCE, TEST_FILLING + + +@pytest.fixture +def mock_bun(): + mock = Mock() + mock.get_name.return_value = TEST_BUN["name"] + mock.get_price.return_value = TEST_BUN["price"] + return mock + + +@pytest.fixture +def mock_sauce(): + mock = Mock() + mock.get_type.return_value = TEST_SAUCE["type"] + mock.get_name.return_value = TEST_SAUCE["name"] + mock.get_price.return_value = TEST_SAUCE["price"] + return mock + + +@pytest.fixture +def mock_filling(): + mock = Mock() + mock.get_type.return_value = TEST_FILLING["type"] + mock.get_name.return_value = TEST_FILLING["name"] + mock.get_price.return_value = TEST_FILLING["price"] + return mock + + +@pytest.fixture +def mock_ingredients(mock_sauce, mock_filling): + return { + TEST_SAUCE["type"]: mock_sauce, + TEST_FILLING["type"]: mock_filling + } \ No newline at end of file diff --git a/data.py b/data.py new file mode 100644 index 000000000..023730a4d --- /dev/null +++ b/data.py @@ -0,0 +1,7 @@ +# Общие тестовые данные +TEST_BUN = {"name": "black bun", "price": 100} +TEST_SAUCE = {"type": "SAUCE", "name": "hot souce", "price": 100} +TEST_FILLING = {"type": "FILLING", "name": "cutlet", "price": 100} + +# Расчёт цены +PRICE_TEST_CASE = [(100, 100, 100, 400)] \ 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/praktikum.py b/praktikum/praktikum.py similarity index 100% rename from praktikum.py rename to praktikum/praktikum.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..e68f20d74 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +pytest==8.2.2 +pytest-cov==5.0.0 +allure-pytest==2.13.5 +coverage==7.5.3 \ No newline at end of file diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..f6c1501fb --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,74 @@ +import pytest +from unittest.mock import Mock + +from praktikum.burger import Burger + +from data import TEST_BUN, TEST_SAUCE, TEST_FILLING, PRICE_TEST_CASE + + +class TestBurger: + def test_set_buns(self, mock_bun): + burger = Burger() + burger.set_buns(mock_bun) + assert burger.bun == mock_bun + + @pytest.mark.parametrize("ingredient_type", [TEST_SAUCE["type"], TEST_FILLING["type"]]) + def test_add_ingredient(self, ingredient_type, mock_ingredients): + burger = Burger() + ingredient = mock_ingredients[ingredient_type] + + burger.add_ingredient(ingredient) + + assert len(burger.ingredients) == 1 + assert burger.ingredients[0] == ingredient + + def test_remove_ingredient(self, mock_sauce, mock_filling): + burger = Burger() + burger.add_ingredient(mock_sauce) + burger.add_ingredient(mock_filling) + burger.remove_ingredient(0) + assert burger.ingredients == [mock_filling] + + def test_move_ingredient(self, mock_sauce, mock_filling): + burger = Burger() + burger.add_ingredient(mock_sauce) + burger.add_ingredient(mock_filling) + burger.move_ingredient(0, 1) + assert burger.ingredients == [mock_filling, mock_sauce] + + @pytest.mark.parametrize( + "bun_price, ing1_price, ing2_price, expected_price", + PRICE_TEST_CASE + ) + def test_get_price(self, bun_price, ing1_price, ing2_price, expected_price, mock_bun): + mock_bun.get_price.return_value = bun_price + + ingredient_1 = Mock() + ingredient_1.get_price.return_value = ing1_price + + ingredient_2 = Mock() + ingredient_2.get_price.return_value = ing2_price + + burger = Burger() + burger.set_buns(mock_bun) + burger.add_ingredient(ingredient_1) + burger.add_ingredient(ingredient_2) + + assert burger.get_price() == expected_price + + def test_get_receipt(self, mock_bun, mock_sauce, mock_filling): + burger = Burger() + burger.set_buns(mock_bun) + burger.add_ingredient(mock_sauce) + burger.add_ingredient(mock_filling) + + expected_receipt = ( + f"(==== {TEST_BUN['name']} ====)\n" + f"= {TEST_SAUCE['type'].lower()} {TEST_SAUCE['name']} =\n" + f"= {TEST_FILLING['type'].lower()} {TEST_FILLING['name']} =\n" + f"(==== {TEST_BUN['name']} ====)\n" + f"\n" + f"Price: {burger.get_price()}" + ) + + assert burger.get_receipt() == expected_receipt \ No newline at end of file