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..4586b2c33 --- /dev/null +++ b/tests/bun_test.py @@ -0,0 +1,40 @@ +import pytest +from praktikum.bun import Bun + + +class TestBun: + + def test_bun_creation_name(self): + bun = Bun("black bun", 100) + assert bun.name == "black bun" + + def test_bun_creation_price(self): + bun = Bun("black bun", 100) + 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_get_name_parametrized(self, name, price): + bun = Bun(name, price) + assert bun.get_name() == name + + @pytest.mark.parametrize("name,price", [ + ("black bun", 100), + ("white bun", 200), + ("red bun", 300.5), + ]) + def test_bun_get_price_parametrized(self, name, price): + bun = Bun(name, price) + assert bun.get_price() == price + \ No newline at end of file diff --git a/tests/burger_test.py b/tests/burger_test.py new file mode 100644 index 000000000..94323e93f --- /dev/null +++ b/tests/burger_test.py @@ -0,0 +1,174 @@ +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_increases_count(self, burger, mock_ingredient_sauce): + burger.add_ingredient(mock_ingredient_sauce) + assert len(burger.ingredients) == 1 + + def test_add_ingredient_adds_correct_ingredient(self, burger, mock_ingredient_sauce): + burger.add_ingredient(mock_ingredient_sauce) + assert burger.ingredients[0] == mock_ingredient_sauce + + def test_add_multiple_ingredients_count(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 + + def test_add_multiple_ingredients_first(self, burger, mock_ingredient_sauce, mock_ingredient_filling): + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + assert burger.ingredients[0] == mock_ingredient_sauce + + def test_add_multiple_ingredients_second(self, burger, mock_ingredient_sauce, mock_ingredient_filling): + burger.add_ingredient(mock_ingredient_sauce) + burger.add_ingredient(mock_ingredient_filling) + 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_count(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 + + def test_remove_ingredient_middle_first(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 burger.ingredients[0] == mock_ingredient_sauce + + def test_remove_ingredient_middle_last(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 burger.ingredients[1] == ingredient3 + + def test_move_ingredient_first_position(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 + + def test_move_ingredient_second_position(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[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_contains_bun_name(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 + + def test_get_receipt_contains_sauce(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 "= sauce hot sauce =" in receipt + + def test_get_receipt_contains_filling(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 "= filling cutlet =" in receipt + + def test_get_receipt_contains_price(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 "Price: 325.0" in receipt diff --git a/tests/database_test.py b/tests/database_test.py new file mode 100644 index 000000000..6b5571fe5 --- /dev/null +++ b/tests/database_test.py @@ -0,0 +1,51 @@ +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_count(self, database): + buns = database.available_buns() + assert len(buns) == 3 + + def test_available_buns_are_buns(self, database): + buns = database.available_buns() + 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_count(self, database): + ingredients = database.available_ingredients() + assert len(ingredients) == 6 + + def test_available_ingredients_are_ingredients(self, database): + ingredients = database.available_ingredients() + assert all(isinstance(ingredient, Ingredient) for ingredient in ingredients) + + def test_available_sauce_count(self, database): + ingredients = database.available_ingredients() + sauce_count = sum(1 for ing in ingredients if ing.get_type() == 'SAUCE') + assert sauce_count == 3 + + def test_available_filling_count(self, database): + ingredients = database.available_ingredients() + filling_count = sum(1 for ing in ingredients if ing.get_type() == 'FILLING') + assert filling_count == 3 + \ No newline at end of file diff --git a/tests/ingredient_test.py b/tests/ingredient_test.py new file mode 100644 index 000000000..de83e04a9 --- /dev/null +++ b/tests/ingredient_test.py @@ -0,0 +1,65 @@ +import pytest +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING + + +class TestIngredient: + + def test_ingredient_creation_type(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100) + assert ingredient.type == INGREDIENT_TYPE_SAUCE + + def test_ingredient_creation_name(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100) + assert ingredient.name == "hot sauce" + + def test_ingredient_creation_price(self): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100) + 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_get_type_parametrized(self, ingredient_type, name, price): + ingredient = Ingredient(ingredient_type, name, price) + assert ingredient.get_type() == ingredient_type + + @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_get_name_parametrized(self, ingredient_type, name, price): + ingredient = Ingredient(ingredient_type, name, price) + assert ingredient.get_name() == name + + @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_get_price_parametrized(self, ingredient_type, name, price): + ingredient = Ingredient(ingredient_type, name, price) + assert ingredient.get_price() == price + \ No newline at end of file