diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ec51d9fd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,78 @@ +# Виртуальные окружения +venv/ +.venv/ +env/ +ENV/ +env.bak/ +venv.bak/ + +# Файлы кеша Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +*.pyc +*.pyo + +# Папки IDE и редакторов +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store +desktop.ini + +# Файлы с секретами и паролями +.env +*.pem +*.key +*.crt +*.p12 +secrets.py +config.py + +# Драйверы браузеров (если случайно положили в проект) +chromedriver.exe +chromedriver +geckodriver.exe +geckodriver +yandexdriver.exe +yandexdriver +msedgedriver.exe +msedgedriver +*.driver + +# Логи и временные файлы +*.log +*.tmp +*.temp +*.cache +*.pid + +# Отчеты о тестах и покрытии +htmlcov/ +.coverage +.coverage.* +.cache +.pytest_cache/ +.tox/ +*.xml +*.trx +allure-results/ +allure-report/ + +# Файлы сборок и дистрибутивов +dist/ +build/ +*.egg-info/ +*.egg +MANIFEST +site-packages/ +target/ + +# Файлы, создаваемые Selenium при работе +*.screenshot +*.har +*.png 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 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/bun_test.py b/tests/bun_test.py new file mode 100644 index 000000000..1efb8227c --- /dev/null +++ b/tests/bun_test.py @@ -0,0 +1,28 @@ +import pytest +from praktikum.bun import Bun + + +class TestBun: + + def test_bun_creation(self): + bun = Bun("black bun", 100) + assert bun.name == "black bun" + assert bun.price == 100 + + def test_get_name(self): + bun = Bun("white bun", 200) + assert bun.get_name() == "white bun" + + def test_get_price(self): + bun = Bun("red bun", 300) + assert bun.get_price() == 300 + + @pytest.mark.parametrize("name,price", [ + ("black bun", 100), + ("white bun", 200), + ("red bun", 300.5), + ]) + def test_bun_creation_parametrized(self, name, price): + bun = Bun(name, price) + assert bun.get_name() == name + assert bun.get_price() == price diff --git a/tests/burger_test.py b/tests/burger_test.py new file mode 100644 index 000000000..64b863466 --- /dev/null +++ b/tests/burger_test.py @@ -0,0 +1,106 @@ +import pytest +from unittest.mock import Mock +from praktikum.burger import Burger +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient + + +class TestBurger: + + @pytest.fixture + def burger(self): + return Burger() + + @pytest.fixture + def mock_bun(self): + bun = Mock(spec=Bun) + bun.get_price.return_value = 100.0 + bun.get_name.return_value = "hot bun" + return bun + + @pytest.fixture + def mock_ingredient_sauce(self): + ingredient = Mock(spec=Ingredient) + ingredient.get_price.return_value = 50.0 + ingredient.get_name.return_value = "hot sauce" + ingredient.get_type.return_value = "SAUCE" + return ingredient + + @pytest.fixture + def mock_ingredient_filling(self): + ingredient = Mock(spec=Ingredient) + ingredient.get_price.return_value = 75.0 + ingredient.get_name.return_value = "cutlet" + ingredient.get_type.return_value = "FILLING" + return ingredient + + def test_set_buns_success(self, burger, mock_bun): + burger.set_buns(mock_bun) + assert burger.bun == mock_bun + + def test_add_ingredient_success(self, burger, mock_ingredient_sauce): + burger.add_ingredient(mock_ingredient_sauce) + assert len(burger.ingredients) == 1 + assert burger.ingredients[0] == mock_ingredient_sauce + + def test_add_multiple_ingredients(self, burger, mock_ingredient_sauce, mock_ingredient_filling): + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + assert len(burger.ingredients) == 2 + assert burger.ingredients[0] == mock_ingredient_sauce + assert burger.ingredients[1] == mock_ingredient_filling + + def test_remove_ingredient_success(self, burger, mock_ingredient_sauce): + burger.add_ingredient(mock_ingredient_sauce) + burger.remove_ingredient(0) + assert len(burger.ingredients) == 0 + + def test_remove_ingredient_middle(self, burger, mock_ingredient_sauce, mock_ingredient_filling): + ingredient3 = Mock(spec=Ingredient) + ingredient3.get_price.return_value = 25.0 + ingredient3.get_name.return_value = "dinosaur" + ingredient3.get_type.return_value = "FILLING" + + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + burger.add_ingredient(ingredient3) + + burger.remove_ingredient(1) + + assert len(burger.ingredients) == 2 + assert burger.ingredients[0] == mock_ingredient_sauce + assert burger.ingredients[1] == ingredient3 + + def test_move_ingredient_success(self, burger, mock_ingredient_sauce, mock_ingredient_filling): + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + + burger.move_ingredient(0, 1) + + assert burger.ingredients[0] == mock_ingredient_filling + assert burger.ingredients[1] == mock_ingredient_sauce + + def test_move_ingredient_same_position(self, burger, mock_ingredient_sauce): + burger.add_ingredient(mock_ingredient_sauce) + burger.move_ingredient(0, 0) + assert burger.ingredients[0] == mock_ingredient_sauce + + def test_get_price_with_bun_and_ingredients(self, burger, mock_bun, mock_ingredient_sauce, mock_ingredient_filling): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + + expected_price = 100.0 * 2 + 50.0 + 75.0 + assert burger.get_price() == expected_price + + def test_get_receipt_full_burger(self, burger, mock_bun, mock_ingredient_sauce, mock_ingredient_filling): + burger.set_buns(mock_bun) + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + + receipt = burger.get_receipt() + + assert "(==== hot bun ====)" in receipt + assert "= sauce hot sauce =" in receipt + assert "= filling cutlet =" in receipt + assert "Price: 325.0" in receipt diff --git a/tests/database_test.py b/tests/database_test.py new file mode 100644 index 000000000..ef2999012 --- /dev/null +++ b/tests/database_test.py @@ -0,0 +1,41 @@ +import pytest +from praktikum.database import Database +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient + + +class TestDatabase: + + @pytest.fixture + def database(self): + return Database() + + def test_database_creation(self, database): + assert database is not None + + def test_available_buns(self, database): + buns = database.available_buns() + assert len(buns) == 3 + assert all(isinstance(bun, Bun) for bun in buns) + + def test_available_buns_names(self, database): + buns = database.available_buns() + bun_names = [bun.get_name() for bun in buns] + assert bun_names == ["black bun", "white bun", "red bun"] + + def test_available_buns_prices(self, database): + buns = database.available_buns() + bun_prices = [bun.get_price() for bun in buns] + assert bun_prices == [100, 200, 300] + + def test_available_ingredients(self, database): + ingredients = database.available_ingredients() + assert len(ingredients) == 6 + assert all(isinstance(ingredient, Ingredient) for ingredient in ingredients) + + def test_available_ingredients_types(self, database): + ingredients = database.available_ingredients() + sauce_count = sum(1 for ing in ingredients if ing.get_type() == 'SAUCE') + filling_count = sum(1 for ing in ingredients if ing.get_type() == 'FILLING') + assert sauce_count == 3 + assert filling_count == 3 diff --git a/tests/ingredient_test.py b/tests/ingredient_test.py new file mode 100644 index 000000000..98749cdd1 --- /dev/null +++ b/tests/ingredient_test.py @@ -0,0 +1,40 @@ +import pytest +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + + +class TestIngredient: + + def test_ingredient_creation(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100) + assert ingredient.type == INGREDIENT_TYPE_SAUCE + assert ingredient.name == "hot sauce" + assert ingredient.price == 100 + + def test_get_name(self): + ingredient = Ingredient(INGREDIENT_TYPE_FILLING, "cutlet", 100) + assert ingredient.get_name() == "cutlet" + + def test_get_price(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "sour cream", 200) + assert ingredient.get_price() == 200 + + def test_get_type_sauce(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "chili sauce", 300) + assert ingredient.get_type() == INGREDIENT_TYPE_SAUCE + + def test_get_type_filling(self): + ingredient = Ingredient(INGREDIENT_TYPE_FILLING, "dinosaur", 200) + assert ingredient.get_type() == INGREDIENT_TYPE_FILLING + + @pytest.mark.parametrize("ingredient_type,name,price", [ + (INGREDIENT_TYPE_SAUCE, "hot sauce", 100), + (INGREDIENT_TYPE_SAUCE, "sour cream", 200), + (INGREDIENT_TYPE_FILLING, "cutlet", 100), + (INGREDIENT_TYPE_FILLING, "dinosaur", 200), + ]) + def test_ingredient_creation_parametrized(self, ingredient_type, name, price): + ingredient = Ingredient(ingredient_type, name, price) + assert ingredient.get_type() == ingredient_type + assert ingredient.get_name() == name + assert ingredient.get_price() == price