diff --git a/.coverage b/.coverage new file mode 100644 index 000000000..65a74b9a0 Binary files /dev/null and b/.coverage differ diff --git a/README.md b/README.md index 272081708..4f63b4e21 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,15 @@ ### Структура проекта -- `praktikum` - пакет, содержащий код программы -- `tests` - пакет, содержащий тесты, разделенные по классам. Например, `bun_test.py`, `burger_test.py` и т.д. +`praktikum` - пакет, содержащий код программы +`tests` - пакет, содержащий тесты, разделенные по классам. Например, `bun_test.py`, `burger_test.py` и т.д. ### Запуск автотестов **Установка зависимостей** -> `$ pip install -r requirements.txt` +`$ pip install -r requirements.txt` **Запуск автотестов и создание HTML-отчета о покрытии** -> `$ pytest --cov=praktikum --cov-report=html` +`$ pytest --cov=praktikum --cov-report=html` diff --git a/__pycache__/__init__.cpython-314.pyc b/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 000000000..64ebc3567 Binary files /dev/null and b/__pycache__/__init__.cpython-314.pyc differ diff --git a/__pycache__/bun.cpython-314.pyc b/__pycache__/bun.cpython-314.pyc new file mode 100644 index 000000000..49bb0ace9 Binary files /dev/null and b/__pycache__/bun.cpython-314.pyc differ diff --git a/__pycache__/burger.cpython-314.pyc b/__pycache__/burger.cpython-314.pyc new file mode 100644 index 000000000..66bc125d2 Binary files /dev/null and b/__pycache__/burger.cpython-314.pyc differ diff --git a/__pycache__/database.cpython-314.pyc b/__pycache__/database.cpython-314.pyc new file mode 100644 index 000000000..ef2be022c Binary files /dev/null and b/__pycache__/database.cpython-314.pyc differ diff --git a/__pycache__/ingredient.cpython-314.pyc b/__pycache__/ingredient.cpython-314.pyc new file mode 100644 index 000000000..ce084de71 Binary files /dev/null and b/__pycache__/ingredient.cpython-314.pyc differ diff --git a/__pycache__/ingredient_types.cpython-314.pyc b/__pycache__/ingredient_types.cpython-314.pyc new file mode 100644 index 000000000..2e67fc3a4 Binary files /dev/null and b/__pycache__/ingredient_types.cpython-314.pyc differ diff --git a/__pycache__/praktikum.cpython-314.pyc b/__pycache__/praktikum.cpython-314.pyc new file mode 100644 index 000000000..269ef23cf Binary files /dev/null and b/__pycache__/praktikum.cpython-314.pyc differ diff --git a/burger.py b/burger.py index 2b3b6a88b..3f71aaa29 100644 --- a/burger.py +++ b/burger.py @@ -1,7 +1,7 @@ from typing import List -from praktikum.bun import Bun -from praktikum.ingredient import Ingredient +from bun import Bun +from ingredient import Ingredient class Burger: diff --git a/coverage.xml b/coverage.xml new file mode 100644 index 000000000..d8e12c649 --- /dev/null +++ b/coverage.xml @@ -0,0 +1,133 @@ + + + + + + /Users/tim/Diplom/qa-python-project + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/database.py b/database.py index 4c75baf71..84d3685d0 100644 --- a/database.py +++ b/database.py @@ -1,8 +1,8 @@ from typing import List -from praktikum.bun import Bun -from praktikum.ingredient import Ingredient -from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING +from bun import Bun +from ingredient import Ingredient +from ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING class Database: diff --git a/praktikum.py b/praktikum.py index ec522fa6d..88b77abd1 100644 --- a/praktikum.py +++ b/praktikum.py @@ -1,9 +1,9 @@ from typing import List -from praktikum.bun import Bun -from praktikum.burger import Burger -from praktikum.database import Database -from praktikum.ingredient import Ingredient +from bun import Bun +from burger import Burger +from database import Database +from ingredient import Ingredient def main(): diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..a3a8dabe0 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +addopts = --cov=bun --cov=burger --cov=database --cov=ingredient --cov=ingredient_types --cov=praktikum --cov-report=term-missing --cov-report=xml +python_files = tests/test_*.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..772247572 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pytest>=8.0 +pytest-cov>=4.0 diff --git a/tests/__pycache__/test_burger.cpython-314-pytest-9.0.3.pyc b/tests/__pycache__/test_burger.cpython-314-pytest-9.0.3.pyc new file mode 100644 index 000000000..95bcfd71a Binary files /dev/null and b/tests/__pycache__/test_burger.cpython-314-pytest-9.0.3.pyc differ diff --git a/tests/__pycache__/test_database.cpython-314-pytest-9.0.3.pyc b/tests/__pycache__/test_database.cpython-314-pytest-9.0.3.pyc new file mode 100644 index 000000000..2a0948826 Binary files /dev/null and b/tests/__pycache__/test_database.cpython-314-pytest-9.0.3.pyc differ diff --git a/tests/__pycache__/test_models.cpython-314-pytest-9.0.3.pyc b/tests/__pycache__/test_models.cpython-314-pytest-9.0.3.pyc new file mode 100644 index 000000000..472544150 Binary files /dev/null and b/tests/__pycache__/test_models.cpython-314-pytest-9.0.3.pyc differ diff --git a/tests/__pycache__/test_praktikum.cpython-314-pytest-9.0.3.pyc b/tests/__pycache__/test_praktikum.cpython-314-pytest-9.0.3.pyc new file mode 100644 index 000000000..b42e32053 Binary files /dev/null and b/tests/__pycache__/test_praktikum.cpython-314-pytest-9.0.3.pyc differ diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..1a453ff3f --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,67 @@ +import pytest +from unittest.mock import Mock + +from burger import Burger +from ingredient import Ingredient + + +@pytest.mark.parametrize( + "ingredient_prices,expected_total", + [ + ([100.0], 300.0), + ([10.0, 20.0], 230.0), + ([5.0, 15.0, 25.0], 245.0), + ], +) +def test_get_price_includes_bun_twice_and_all_ingredient_prices( + ingredient_prices, expected_total +): + # Мокаем булочку и ингредиенты, чтобы тест был независим от реализации Ingredient. + bun = Mock(get_name=Mock(return_value="mock bun"), get_price=Mock(return_value=100.0)) + burger = Burger() + burger.set_buns(bun) + + for price in ingredient_prices: + ingredient = Mock(get_price=Mock(return_value=price)) + burger.add_ingredient(ingredient) + + assert burger.get_price() == expected_total + + +@pytest.mark.parametrize( + "initial_names,move_from,move_to,expected_names", + [ + (["hot sauce", "cutlet", "sausage"], 2, 0, ["sausage", "hot sauce", "cutlet"]), + (["sour cream", "dinosaur", "cutlet"], 0, 2, ["dinosaur", "cutlet", "sour cream"]), + ], +) +def test_move_ingredient_reorders_list_correctly( + initial_names, move_from, move_to, expected_names +): + bun = Mock(get_name=Mock(return_value="plain bun"), get_price=Mock(return_value=100.0)) + burger = Burger() + burger.set_buns(bun) + + for name in initial_names: + burger.add_ingredient(Ingredient("FILLING", name, 1.0)) + + burger.move_ingredient(move_from, move_to) + assert [ingredient.get_name() for ingredient in burger.ingredients] == expected_names + + +def test_get_receipt_outputs_bun_and_ingredient_lines(): + bun = Mock(get_name=Mock(return_value="test bun"), get_price=Mock(return_value=50.0)) + ingredient = Mock( + get_type=Mock(return_value="SAUCE"), + get_name=Mock(return_value="hot sauce"), + get_price=Mock(return_value=10.0), + ) + burger = Burger() + burger.set_buns(bun) + burger.add_ingredient(ingredient) + + receipt = burger.get_receipt() + + assert "(==== test bun ====)" in receipt + assert "= sauce hot sauce =" in receipt + assert "Price: 110.0" in receipt diff --git a/tests/test_database.py b/tests/test_database.py new file mode 100644 index 000000000..b909e5d9f --- /dev/null +++ b/tests/test_database.py @@ -0,0 +1,19 @@ +from database import Database + + +def test_available_buns_returns_three_buns(): + database = Database() + buns = database.available_buns() + + assert len(buns) == 3 + assert buns[0].get_name() == "black bun" + assert buns[1].get_price() == 200 + + +def test_available_ingredients_returns_sauce_and_filling(): + database = Database() + ingredients = database.available_ingredients() + + assert len(ingredients) == 6 + assert {ingredient.get_type() for ingredient in ingredients} == {"SAUCE", "FILLING"} + assert any(ingredient.get_name() == "cutlet" for ingredient in ingredients) diff --git a/tests/test_models.py b/tests/test_models.py new file mode 100644 index 000000000..077de1556 --- /dev/null +++ b/tests/test_models.py @@ -0,0 +1,36 @@ +import pytest + +from bun import Bun +from ingredient import Ingredient +from ingredient_types import INGREDIENT_TYPE_FILLING, INGREDIENT_TYPE_SAUCE + + +@pytest.mark.parametrize( + "name,price", + [ + ("sesame bun", 45.0), + ("plain bun", 80.5), + ], +) +def test_bun_exposes_name_and_price(name: str, price: float): + bun = Bun(name, price) + + assert bun.get_name() == name + assert bun.get_price() == price + + +@pytest.mark.parametrize( + "ingredient_type,name,price", + [ + (INGREDIENT_TYPE_SAUCE, "hot sauce", 10.0), + (INGREDIENT_TYPE_FILLING, "cutlet", 35.5), + ], +) +def test_ingredient_exposes_type_name_and_price( + ingredient_type: str, name: str, price: float +): + ingredient = Ingredient(ingredient_type, name, price) + + assert ingredient.get_type() == ingredient_type + assert ingredient.get_name() == name + assert ingredient.get_price() == price diff --git a/tests/test_praktikum.py b/tests/test_praktikum.py new file mode 100644 index 000000000..cda2deb67 --- /dev/null +++ b/tests/test_praktikum.py @@ -0,0 +1,34 @@ +import builtins +from unittest.mock import Mock + +import pytest + +import praktikum + + +def test_main_builds_burger_using_database_and_prints_receipt(monkeypatch): + fake_bun = Mock(get_name=Mock(return_value="dummy bun"), get_price=Mock(return_value=10.0)) + fake_ingredient = Mock( + get_type=Mock(return_value="FILLING"), + get_name=Mock(return_value="dummy filling"), + get_price=Mock(return_value=5.0), + ) + fake_database = Mock( + available_buns=Mock(return_value=[fake_bun]), + available_ingredients=Mock(return_value=[fake_ingredient] * 6), + ) + + monkeypatch.setattr(praktikum, "Database", Mock(return_value=fake_database)) + + printed_lines = [] + + def fake_print(*args, **kwargs): + printed_lines.append(" ".join(str(item) for item in args)) + + monkeypatch.setattr(builtins, "print", fake_print) + + praktikum.main() + + assert any("dummy bun" in line for line in printed_lines) + assert any("dummy filling" in line for line in printed_lines) + assert any("Price:" in line for line in printed_lines)