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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
__pycache__/
.pytest_cache/
.coverage
htmlcov/
*.pyc
28 changes: 21 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,35 @@

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

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

Процент покрытия 100% (отчет: `htmlcov/index.html`)
- создание бургера;
- установка булочки;
- добавление и удаление ингредиента;
- перемещение ингредиента;
- расчёт цены;
- формирование чека.

Покрытие файла `burger.py` — 100%.

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

- `praktikum` - пакет, содержащий код программы
- `tests` - пакет, содержащий тесты, разделенные по классам. Например, `bun_test.py`, `burger_test.py` и т.д.
- `burger.py` — тестируемый класс `Burger`;
- `bun.py`, `ingredient.py` — модели, используемые классом `Burger`;
- `tests/test_burger.py` — unit-тесты;
- `requirements.txt` — зависимости проекта;
- `pytest.ini` — настройки pytest.

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

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

> `$ pip install -r requirements.txt`
> `$ python -m pip install -r requirements.txt`

**Запуск автотестов с проверкой обязательного покрытия 100%**

> `$ pytest tests --cov=burger --cov-report=term-missing --cov-fail-under=100`

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

> `$ pytest --cov=praktikum --cov-report=html`
> `$ pytest tests --cov=burger --cov-report=html --cov-fail-under=100`
4 changes: 2 additions & 2 deletions burger.py
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
6 changes: 6 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -ra
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest==9.1.1
pytest-cov==7.1.0
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

94 changes: 94 additions & 0 deletions tests/test_burger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from unittest.mock import Mock

import pytest

from bun import Bun
from burger import Burger
from ingredient import Ingredient


@pytest.fixture
def burger():
return Burger()


class TestBurger:
def test_init_creates_burger_without_bun_and_ingredients(self):
burger = Burger()

assert burger.bun is None and burger.ingredients == []

def test_set_buns_sets_bun(self, burger):
bun = Mock(spec=Bun)

burger.set_buns(bun)

assert burger.bun is bun

def test_add_ingredient_appends_ingredient(self, burger):
ingredient = Mock(spec=Ingredient)

burger.add_ingredient(ingredient)

assert burger.ingredients == [ingredient]

@pytest.mark.parametrize("index, expected_indexes",
[(0, [1, 2]),(1, [0, 2]),(2, [0, 1]),],)
def test_remove_ingredient_removes_item_by_index(
self, burger, index, expected_indexes):
ingredients = [Mock(spec=Ingredient) for _ in range(3)]
burger.ingredients = ingredients.copy()

burger.remove_ingredient(index)

assert burger.ingredients == [ingredients[i] for i in expected_indexes]

@pytest.mark.parametrize("index, new_index, expected_indexes",
[(0, 2, [1, 2, 0]),(2, 0, [2, 0, 1]),(1, 1, [0, 1, 2]),],)
def test_move_ingredient_moves_item_to_new_index(
self, burger, index, new_index, expected_indexes):
ingredients = [Mock(spec=Ingredient) for _ in range(3)]
burger.ingredients = ingredients.copy()

burger.move_ingredient(index, new_index)

assert burger.ingredients == [ingredients[i] for i in expected_indexes]

@pytest.mark.parametrize("bun_price, ingredient_prices, expected_price",
[(100, [], 200),(125.5, [10, 20.5], 281.5),],)
def test_get_price_returns_price_of_two_buns_and_all_ingredients(
self, burger, bun_price, ingredient_prices, expected_price):
bun = Mock(spec=Bun)
bun.get_price.return_value = bun_price
ingredients = [Mock(spec=Ingredient) for _ in ingredient_prices]
for ingredient, price in zip(ingredients, ingredient_prices):
ingredient.get_price.return_value = price
burger.set_buns(bun)
burger.ingredients = ingredients

result = burger.get_price()

assert result == expected_price

@pytest.mark.parametrize(
"ingredient_type, expected_type",
[("SAUCE", "sauce"),("FILLING", "filling"),],)
def test_get_receipt_returns_formatted_receipt(
self, burger, ingredient_type, expected_type):
bun = Mock(spec=Bun)
bun.get_name.return_value = "space bun"
bun.get_price.return_value = 100
ingredient = Mock(spec=Ingredient)
ingredient.get_type.return_value = ingredient_type
ingredient.get_name.return_value = "meteor"
ingredient.get_price.return_value = 25
burger.set_buns(bun)
burger.add_ingredient(ingredient)

result = burger.get_receipt()

assert result == (
"(==== space bun ====)\n"
f"= {expected_type} meteor =\n"
"(==== space bun ====)\n\n"
"Price: 225")