Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Виртуальное окружение
.venv/
venv/
env/

# Кэш Python
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
.ipynb_checkpoints

# Coverage
.coverage
htmlcov/

# IDE
.vscode/
.idea/
*.swp
*.swo

# ОС
.DS_Store
Thumbs.db

# pytest
.pytest_cache/
74 changes: 53 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,56 @@
## Задание 1: Юнит-тесты

### Автотесты для проверки программы, которая помогает заказать бургер в Stellar Burgers

### Реализованные сценарии

Созданы юнит-тесты, покрывающие классы `Bun`, `Burger`, `Ingredient`, `Database`

Процент покрытия 100% (отчет: `htmlcov/index.html`)

### Структура проекта

- `praktikum` - пакет, содержащий код программы
- `tests` - пакет, содержащий тесты, разделенные по классам. Например, `bun_test.py`, `burger_test.py` и т.д.

### Запуск автотестов

**Установка зависимостей**

Задание 1: Юнит-тесты
Автотесты для проверки программы, которая помогает заказать бургер в Stellar Burgers

Реализованные сценарии

Созданы юнит-тесты, покрывающие классы `Burger`
Класс `Burger` покрыт на 100% — согласно отчёту `htmlcov/index.html`.
Name Stmts Miss Cover
---------------------------------------------------
praktikum\bun.py 8 1 88%
praktikum\burger.py 27 0 100%
praktikum\database.py 21 21 0%
praktikum\ingredient.py 11 2 82%
praktikum\ingredient_types.py 2 0 100%
praktikum\praktikum.py 20 20 0%
---------------------------------------------------
TOTAL 89 44 51%


Проверены:

Установка булочки (set_buns)
Добавление ингредиентов (add_ingredient)
Удаление ингредиентов по индексу (remove_ingredient)
Перемещение ингредиентов (move_ingredient)
Расчёт итоговой стоимости (get_price)
Формирование чека (get_receipt) — здесь использован unittest.mock.Mock

DIPLOM_1/
├── htmlcov/ # Отчет о покрытии
├── praktikum/ # Основной код приложения
│ ├── __init__.py
│ ├── bun.py
│ ├── burger.py
│ ├── database.py
│ ├── ingredient.py
│ ├── ingredient_types.py
│ └── praktikum.py
├── tests/ # Тесты
│ ├── __init__.py
│ └── test_burger.py
├── .gitignore
├── README.md # описание проекта
└── requirements.txt # Зависимости



Установка зависимостей
> `$ pip install -r requirements.txt`

**Запуск автотестов и создание HTML-отчета о покрытии**

Запуск автотестов и создание HTML-отчета о покрытии
> `$ pytest --cov=praktikum --cov-report=html`

Примечание
Bun и Ingredient — простые объекты данных без побочных эффектов, поэтому в большинстве тестов они используются «как есть».
Мок применяется только в тесте get_receipt(), чтобы изолировать форматирование чека от реализации других классов и гарантировать, что тест проверяет именно логику вывода, а не работу зависимостей.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added requirements.txt
Binary file not shown.
File renamed without changes.
99 changes: 99 additions & 0 deletions tests/test_burger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import pytest
from unittest.mock import Mock

from praktikum.burger import Burger
from praktikum.bun import Bun
from praktikum.ingredient import Ingredient
from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING


class TestBurger:

@pytest.mark.parametrize("name, price", [("black bun", 100),("white bun", 200),])
def test_set_buns_sets_bun_successfully(self, name, price):
burger = Burger()
bun = Bun(name, price)
burger.set_buns(bun)
assert burger.bun is bun

@pytest.mark.parametrize("type, name, price", [(INGREDIENT_TYPE_SAUCE, "hot sauce", 100),(INGREDIENT_TYPE_FILLING, "cutlet", 100),(INGREDIENT_TYPE_SAUCE, "chili sauce", 300),])
def test_add_ingredient_successfully(self, type, name, price):
burger = Burger()
ingredient = Ingredient(type, name, price)
burger.add_ingredient(ingredient)
assert ingredient in burger.ingredients

def test_remove_ingredient_removes_ingredient_by_index_successfully(self):
burger = Burger()
cutlet = Ingredient(INGREDIENT_TYPE_FILLING, "cutlet", 100)
dinosaur = Ingredient(INGREDIENT_TYPE_FILLING, "dinosaur", 200)
sauce = Ingredient(INGREDIENT_TYPE_SAUCE, "chili sauce", 300)
burger.add_ingredient(cutlet)
burger.add_ingredient(dinosaur)
burger.add_ingredient(sauce)
burger.remove_ingredient(1)
assert len(burger.ingredients) == 2
assert cutlet in burger.ingredients
assert sauce in burger.ingredients
assert dinosaur not in burger.ingredients

def test_move_ingredient_moves_ingredient_by_index_successfully(self):
burger = Burger()
sauce = Ingredient(INGREDIENT_TYPE_SAUCE, "chili sauce", 300)
cutlet = Ingredient(INGREDIENT_TYPE_FILLING, "cutlet", 100)
dinosaur = Ingredient(INGREDIENT_TYPE_FILLING, "dinosaur", 200)
hot_sauce = Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100)
burger.add_ingredient(sauce)
burger.add_ingredient(cutlet)
burger.add_ingredient(dinosaur)
burger.add_ingredient(hot_sauce)
burger.move_ingredient(2,3)
assert len(burger.ingredients) == 4
assert burger.ingredients[0] is sauce
assert burger.ingredients[1] is cutlet
assert burger.ingredients[2] is hot_sauce
assert burger.ingredients[3] is dinosaur


@pytest.mark.parametrize('bun_name, bun_price, ingredients_data, expected_price',
[("black bun", 100, [(INGREDIENT_TYPE_FILLING, "cutlet", 100)], 300),
("black bun", 100, [], 200),
("white bun", 200, [(INGREDIENT_TYPE_FILLING, "dinosaur", 200), (INGREDIENT_TYPE_SAUCE, "hot sauce", 100)], 700)])
def test_get_price_cost_of_a_ready_made_burger(self, bun_name, bun_price, ingredients_data, expected_price ):
burger = Burger()
bun = Bun(bun_name, bun_price)
burger.set_buns(bun)

for type, name, price in ingredients_data:
ingredient = Ingredient(type, name, price)
burger.add_ingredient(ingredient)

price = burger.get_price()
assert price == expected_price


def test_get_receipt_uses_mocked_bun_and_ingredient(self):
bun="red bun"
bun_price=300

ingredient_type=INGREDIENT_TYPE_FILLING
ingredient_name="cutlet"
ingredient_price=200

mock_bun = Mock()
mock_bun.get_name.return_value = bun
mock_bun.get_price.return_value = bun_price

mock_ingredient = Mock()
mock_ingredient.get_type.return_value = ingredient_type
mock_ingredient.get_name.return_value = ingredient_name
mock_ingredient.get_price.return_value = ingredient_price

burger = Burger()
burger.set_buns(mock_bun)
burger.add_ingredient(mock_ingredient)

receipt = burger.get_receipt()

expected = f"(==== {bun} ====)\n= {ingredient_type.lower()} {ingredient_name} =\n(==== {bun} ====)\n\nPrice: {bun_price*2 + ingredient_price}"
assert receipt == expected