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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.coverage
__pycache__
.pytest_cache

24 changes: 1 addition & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,2 @@
## Задание 1: Юнит-тесты
# Task_1 #

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

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

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

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

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

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

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

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

> `$ pip install -r requirements.txt`

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

> `$ pytest --cov=praktikum --cov-report=html`
Empty file removed __init__.py
Empty file.
21 changes: 21 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pytest
from unittest.mock import Mock
from praktikum.bun import Bun
from praktikum.ingredient import Ingredient
from praktikum.ingredient_types import INGREDIENT_TYPE_FILLING


@pytest.fixture
def mock_bun():
bun = Mock(spec=Bun)
bun.get_name.return_value = "mock bun"
bun.get_price.return_value = 50
return bun

@pytest.fixture
def mock_ingredient():
ing = Mock(spec=Ingredient)
ing.get_name.return_value = "mock ingredient"
ing.get_price.return_value = 20
ing.get_type.return_value = INGREDIENT_TYPE_FILLING
return ing
19 changes: 19 additions & 0 deletions data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING

BunData = [
('black bun', 100),
('white bun', 200),
('red bun', 300)]

IngredientData = [
("hot sauce", INGREDIENT_TYPE_SAUCE, 100),
("sour cream", INGREDIENT_TYPE_SAUCE, 200),
("chili sauce", INGREDIENT_TYPE_SAUCE, 300),
("cutlet", INGREDIENT_TYPE_FILLING, 100),
("dinosaur", INGREDIENT_TYPE_FILLING, 200),
("sausage", INGREDIENT_TYPE_FILLING, 300)]





144 changes: 144 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Coverage report</title>
<link rel="icon" sizes="32x32" href="favicon_32_cb_58284776.png">
<link rel="stylesheet" href="style_cb_ed8d5379.css" type="text/css">
<script src="coverage_html_cb_513c77fd.js" defer></script>
</head>
<body class="indexfile">
<header>
<div class="content">
<h1>Coverage report:
<span class="pc_cov">100%</span>
</h1>
<aside id="help_panel_wrapper">
<input id="help_panel_state" type="checkbox">
<label for="help_panel_state">
<img id="keyboard_icon" src="keybd_closed_cb_ce680311.png" alt="Show/hide keyboard shortcuts">
</label>
<div id="help_panel">
<p class="legend">Shortcuts on this page</p>
<div class="keyhelp">
<p>
<kbd>f</kbd>
<kbd>s</kbd>
<kbd>m</kbd>
<kbd>x</kbd>
<kbd>c</kbd>
&nbsp; change column sorting
</p>
<p>
<kbd>[</kbd>
<kbd>]</kbd>
&nbsp; prev/next file
</p>
<p>
<kbd>?</kbd> &nbsp; show/hide this help
</p>
</div>
</div>
</aside>
<form id="filter_container">
<input id="filter" type="text" value="" placeholder="filter...">
<div>
<input id="hide100" type="checkbox" >
<label for="hide100">hide covered</label>
</div>
</form>
<h2>
<a class="button current">Files</a>
<a class="button" href="function_index.html">Functions</a>
<a class="button" href="class_index.html">Classes</a>
</h2>
<p class="text">
<a class="nav" href="https://coverage.readthedocs.io/en/7.12.0">coverage.py v7.12.0</a>,
created at 2026-01-06 16:27 +0300
</p>
</div>
</header>
<main id="index">
<table class="index" data-sortable>
<thead>
<tr class="tablehead" title="Click to sort">
<th id="file" class="name" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
<th class="spacer">&nbsp;</th>
<th id="statements" aria-sort="none" data-default-sort-order="descending" data-shortcut="s">statements<span class="arrows"></span></th>
<th id="missing" aria-sort="none" data-default-sort-order="descending" data-shortcut="m">missing<span class="arrows"></span></th>
<th id="excluded" aria-sort="none" data-default-sort-order="descending" data-shortcut="x">excluded<span class="arrows"></span></th>
<th class="spacer">&nbsp;</th>
<th id="coverage" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
</tr>
</thead>
<tbody>
<tr class="region">
<td class="name"><a href="z_a44f0ac069e85531_test_bun_py.html">tests&#8201;\&#8201;test_bun.py</a></td>
<td class="spacer">&nbsp;</td>
<td>17</td>
<td>0</td>
<td>0</td>
<td class="spacer">&nbsp;</td>
<td data-ratio="17 17">100%</td>
</tr>
<tr class="region">
<td class="name"><a href="z_a44f0ac069e85531_test_burger_py.html">tests&#8201;\&#8201;test_burger.py</a></td>
<td class="spacer">&nbsp;</td>
<td>58</td>
<td>0</td>
<td>0</td>
<td class="spacer">&nbsp;</td>
<td data-ratio="58 58">100%</td>
</tr>
<tr class="region">
<td class="name"><a href="z_a44f0ac069e85531_test_database_py.html">tests&#8201;\&#8201;test_database.py</a></td>
<td class="spacer">&nbsp;</td>
<td>34</td>
<td>0</td>
<td>0</td>
<td class="spacer">&nbsp;</td>
<td data-ratio="34 34">100%</td>
</tr>
<tr class="region">
<td class="name"><a href="z_a44f0ac069e85531_test_ingredient_py.html">tests&#8201;\&#8201;test_ingredient.py</a></td>
<td class="spacer">&nbsp;</td>
<td>16</td>
<td>0</td>
<td>0</td>
<td class="spacer">&nbsp;</td>
<td data-ratio="16 16">100%</td>
</tr>
</tbody>
<tfoot>
<tr class="total">
<td class="name">Total</td>
<td class="spacer">&nbsp;</td>
<td>125</td>
<td>0</td>
<td>0</td>
<td class="spacer">&nbsp;</td>
<td data-ratio="125 125">100%</td>
</tr>
</tfoot>
</table>
<p id="no_rows">
No items found using the specified filter.
</p>
</main>
<footer>
<div class="content">
<p>
<a class="nav" href="https://coverage.readthedocs.io/en/7.12.0">coverage.py v7.12.0</a>,
created at 2026-01-06 16:27 +0300
</p>
</div>
<aside class="hidden">
<a id="prevFileLink" class="nav" href="z_a44f0ac069e85531_test_ingredient_py.html"></a>
<a id="nextFileLink" class="nav" href="z_a44f0ac069e85531_test_bun_py.html"></a>
<button type="button" class="button_prev_file" data-shortcut="["></button>
<button type="button" class="button_next_file" data-shortcut="]"></button>
<button type="button" class="button_show_hide_help" data-shortcut="?"></button>
</aside>
</footer>
</body>
</html>
File renamed without changes.
1 change: 0 additions & 1 deletion burger.py → praktikum/burger.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from praktikum.bun import Bun
from praktikum.ingredient import Ingredient


class Burger:
"""
Модель бургера.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

pytest 9.0.1
pytest-cov 7.0.0
22 changes: 22 additions & 0 deletions tests/test_bun.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest
from praktikum.bun import Bun
from data import BunData


class TestBun:
@pytest.mark.parametrize('name, price', BunData)
def test_bun_constructor(self, name, price):
bun = Bun(name, price)

assert bun.name == name
assert bun.price == price

@pytest.mark.parametrize('name, price', BunData)
def test_get_name(self, name, price):
bun = Bun(name, price)
assert bun.get_name() == name

@pytest.mark.parametrize('name, price', BunData)
def test_get_price(self, name, price):
bun = Bun(name, price)
assert bun.get_price() == price
69 changes: 69 additions & 0 deletions tests/test_burger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import pytest
from unittest.mock import Mock
from praktikum.bun import Bun
from praktikum.burger import Burger
from praktikum.ingredient import Ingredient
from data import BunData, IngredientData


class TestBurger:

def test_burger_initial_state(self):
burger = Burger()
assert burger.bun is None
assert burger.ingredients == []

@pytest.mark.parametrize("bun_name, bun_price", BunData)
def test_set_bun(self, bun_name, bun_price):
burger = Burger()
mock_bun = Mock(spec=Bun)
mock_bun.get_name.return_value = bun_name
mock_bun.get_price.return_value = bun_price
burger.set_buns(mock_bun)
assert burger.bun == mock_bun
assert burger.bun.get_name() == bun_name
assert burger.bun.get_price() == bun_price

@pytest.mark.parametrize("name, type_i, price", IngredientData)
def test_add_ingredient(self, name, type_i, price):
burger = Burger()
mock_ingredient = Mock(spec=Ingredient)
mock_ingredient.get_name.return_value = name
mock_ingredient.get_type.return_value = type_i
mock_ingredient.get_price.return_value = price

burger.add_ingredient(mock_ingredient)
assert mock_ingredient in burger.ingredients

def test_remove_ingredient(self, mock_ingredient):
burger = Burger()
burger.add_ingredient(mock_ingredient)
burger.remove_ingredient(0)
assert len(burger.ingredients) == 0

def test_move_ingredient(self):
burger = Burger()
ing1 = Mock(spec=Ingredient)
ing2 = Mock(spec=Ingredient)
burger.add_ingredient(ing1)
burger.add_ingredient(ing2)

burger.move_ingredient(0, 1)
assert burger.ingredients[0] == ing2
assert burger.ingredients[1] == ing1

def test_get_price(self, mock_bun, mock_ingredient):
burger = Burger()
burger.set_buns(mock_bun)
burger.add_ingredient(mock_ingredient)
expected_price = mock_bun.get_price() * 2 + mock_ingredient.get_price()
assert burger.get_price() == expected_price

def test_get_receipt(self, mock_bun, mock_ingredient):
burger = Burger()
burger.set_buns(mock_bun)
burger.add_ingredient(mock_ingredient)
receipt = burger.get_receipt()
assert "mock bun" in receipt
assert "mock ingredient" in receipt
assert str(mock_bun.get_price() * 2 + mock_ingredient.get_price()) in receipt
47 changes: 47 additions & 0 deletions tests/test_database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import pytest
from unittest.mock import patch

from praktikum.database import Database
from praktikum.bun import Bun
from praktikum.ingredient import Ingredient


class TestDatabase:

def test_buns_count(self):
db = Database()
buns = db.available_buns()
assert len(buns) == 3

def test_buns_type(self):
db = Database()
buns = db.available_buns()
assert all(isinstance(b, Bun) for b in buns)

def test_ingredients_count(self):
db = Database()
ingredients = db.available_ingredients()
assert len(ingredients) == 6

def test_ingredients_type(self):
db = Database()
ingredients = db.available_ingredients()
assert all(isinstance(i, Ingredient) for i in ingredients)

@pytest.mark.parametrize("ingredient_name", [
"hot sauce", "sour cream", "chili sauce",
"cutlet", "dinosaur", "sausage"])
def test_ingredient_exists(self, ingredient_name):
db = Database()
ingredient = next(
(i for i in db.available_ingredients() if i.get_name() == ingredient_name),
None)
assert ingredient is not None
assert isinstance(ingredient, Ingredient)

@pytest.mark.parametrize("bun_name", ["black bun", "white bun", "red bun"])
def test_bun_exists(self, bun_name):
db = Database()
bun = next((b for b in db.available_buns() if b.get_name() == bun_name), None)
assert bun is not None
assert isinstance(bun, Bun)
22 changes: 22 additions & 0 deletions tests/test_ingredient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest
from praktikum.ingredient import Ingredient
from data import IngredientData



class TestForIngredient:

@pytest.mark.parametrize('ingredient_type, name, price', IngredientData)
def test_get_type(self, ingredient_type, name, price):
ingredient = Ingredient(ingredient_type, name, price)
assert ingredient.get_type() == ingredient_type

@pytest.mark.parametrize('ingredient_type, name, price', IngredientData)
def test_get_name(self, ingredient_type, name, price):
ingredient = Ingredient(ingredient_type, name, price)
assert ingredient.get_name() == name

@pytest.mark.parametrize('ingredient_type, name, price', IngredientData)
def test_get_price(self, ingredient_type, name, price):
ingredient = Ingredient(ingredient_type, name, price)
assert ingredient.get_price() == price