diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..1a0ca9295 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +__pycache__/ +*.py[cod] +*.pyo +*.pyd +*.pytest_cache/ +.pytest_cache/ +*.egg-info/ +dist/ +build/ +venv/ +env/ +.venv/ +.idea/ +.vscode/ +*.swp +*.swo +.DS_Store +*.log +selenium-screenshots/ +screenshots/ +videos/ +.cache/ +htmlcov/ +.coverage +coverage.xml \ No newline at end of file diff --git a/README.md b/README.md index 272081708..ad8965eb4 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,67 @@ -## Задание 1: Юнит-тесты +# Задание 1. Юнит-тесты +## Автотесты для проверки программы, которая помогает заказать бургер в Stellar Burgers +### Реализованные сценарии -### Автотесты для проверки программы, которая помогает заказать бургер в Stellar Burgers +Разработаны юнит-тесты для следующих классов: +- `Bun` +- `Burger` +- `Ingredient` +- `Database` -### Реализованные сценарии +Использованы: +- `pytest` +- параметризация (`pytest.mark.parametrize`) +- моки (`unittest.mock`) + +Процент покрытия кода — **78%**. + +HTML-отчет о покрытии можно сгенерировать командой: + +```bash +python3 -m pytest --cov=praktikum --cov-report=html +``` + +## Структура проекта + +```text +praktikum/ + bun.py + burger.py + database.py + ingredient.py + ingredient_types.py + praktikum.py + +tests/ + conftest.py + test_bun.py + test_burger.py + test_database.py + test_ingredient.py +``` -Созданы юнит-тесты, покрывающие классы `Bun`, `Burger`, `Ingredient`, `Database` +## Установка зависимостей -Процент покрытия 100% (отчет: `htmlcov/index.html`) +```bash +pip install -r requirements.txt +``` -### Структура проекта +## Запуск тестов -- `praktikum` - пакет, содержащий код программы -- `tests` - пакет, содержащий тесты, разделенные по классам. Например, `bun_test.py`, `burger_test.py` и т.д. +```bash +python3 -m pytest +``` -### Запуск автотестов +## Запуск тестов с отчетом о покрытии -**Установка зависимостей** +Отчет в консоли: -> `$ pip install -r requirements.txt` +```bash +python3 -m pytest --cov=praktikum --cov-report=term-missing +``` -**Запуск автотестов и создание HTML-отчета о покрытии** +HTML-отчет: -> `$ pytest --cov=praktikum --cov-report=html` +```bash +python3 -m pytest --cov=praktikum --cov-report=html +``` \ No newline at end of file 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/praktikum.py b/praktikum/praktikum.py similarity index 99% rename from praktikum.py rename to praktikum/praktikum.py index ec522fa6d..73012525d 100644 --- a/praktikum.py +++ b/praktikum/praktikum.py @@ -1,11 +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 - def main(): # Инициализируем базу данных database: Database = Database() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..d9d960e3d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +pytest==9.0.2 +pytest-cov==7.1.0 +allure-pytest==2.16.0 \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..dd7ed1307 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,24 @@ +import pytest +from praktikum.bun import Bun +from praktikum.ingredient import Ingredient +from praktikum.burger import Burger +from praktikum.ingredient_types import ( + INGREDIENT_TYPE_SAUCE, + INGREDIENT_TYPE_FILLING +) + +@pytest.fixture +def bun(): + return Bun("white bun", 200) + +@pytest.fixture +def sauce(): + return Ingredient(INGREDIENT_TYPE_SAUCE, "hot sauce", 100) + +@pytest.fixture +def filling(): + return Ingredient(INGREDIENT_TYPE_FILLING, "cutlet", 300) + +@pytest.fixture +def burger(): + return Burger() diff --git a/tests/test_bun.py b/tests/test_bun.py new file mode 100644 index 000000000..872bedb4a --- /dev/null +++ b/tests/test_bun.py @@ -0,0 +1,28 @@ +import pytest +from praktikum.bun import Bun + +class TestBun: + @pytest.mark.parametrize( + "name", + [ + "white bun", + "black bun", + "red bun" + ] +) + def test_get_name(self, name): + bun = Bun(name, 200) + assert bun.get_name() == name + + @pytest.mark.parametrize( + "price", + [ + 100, + 200, + 300 + ] + ) + def test_get_price(self, price): + bun = Bun("white bun", price) + assert bun.get_price() == price + \ No newline at end of file diff --git a/tests/test_burger.py b/tests/test_burger.py new file mode 100644 index 000000000..1bb916945 --- /dev/null +++ b/tests/test_burger.py @@ -0,0 +1,55 @@ +from unittest.mock import Mock + +class TestBurger: + def test_set_bun(self, burger): + bun = Mock() + burger.set_buns(bun) + assert burger.bun == bun + + def test_add_ingredient(self,burger, sauce): + burger.add_ingredient(sauce) + assert sauce in burger.ingredients + + def test_remove_ingredient(self, burger, sauce, filling): + burger.add_ingredient(sauce) + burger.add_ingredient(filling) + burger.remove_ingredient(0) + assert burger.ingredients == [filling] + + def test_move_ingredient(self, burger, sauce, filling): + burger.add_ingredient(sauce) + burger.add_ingredient(filling) + burger.move_ingredient(0, 1) + assert burger.ingredients == [filling, sauce] + + def test_get_price(self, burger): + bun = Mock() + bun.get_price.return_value = 200 + ingredient_1 = Mock() + ingredient_1.get_price.return_value = 100 + + ingredient_2 = Mock() + ingredient_2.get_price.return_value = 300 + burger.set_buns(bun) + burger.add_ingredient(ingredient_1) + burger.add_ingredient(ingredient_2) + assert burger.get_price() == 800 + + def test_get_receipt(self, burger): + bun = Mock() + bun.get_name.return_value = "white bun" + bun.get_price.return_value = 200 + + ingredient = Mock() + ingredient.get_type.return_value = "SAUCE" + ingredient.get_name.return_value = "hot sauce" + ingredient.get_price.return_value = 100 + burger.set_buns(bun) + burger.add_ingredient(ingredient) + expected = ( + "(==== white bun ====)\n" + "= sauce hot sauce =\n" + "(==== white bun ====)\n\n" + "Price: 500" + ) + assert burger.get_receipt() == expected diff --git a/tests/test_database.py b/tests/test_database.py new file mode 100644 index 000000000..6779a7edc --- /dev/null +++ b/tests/test_database.py @@ -0,0 +1,14 @@ +from praktikum.database import Database + +class TestDatabase: + def test_database_contains_buns(self): + database = Database() + buns = database.available_buns() + assert len(buns) == 3 + assert buns[0].get_name() == "black bun" + + def test_database_contains_ingredients(self): + database = Database() + ingredients = database.available_ingredients() + assert len(ingredients) == 6 + assert ingredients[0].get_name() == "hot sauce" diff --git a/tests/test_ingredient.py b/tests/test_ingredient.py new file mode 100644 index 000000000..8081d3ad0 --- /dev/null +++ b/tests/test_ingredient.py @@ -0,0 +1,41 @@ +import pytest +from praktikum.ingredient import Ingredient +from praktikum.ingredient_types import ( + INGREDIENT_TYPE_FILLING, + INGREDIENT_TYPE_SAUCE +) + +class TestIngredient: + @pytest.mark.parametrize( + "ingredient_type", + [ + INGREDIENT_TYPE_SAUCE, + INGREDIENT_TYPE_FILLING, + ] + ) + def test_get_type(self, ingredient_type): + ingredient = Ingredient(ingredient_type, "test", 100) + assert ingredient.get_type() == ingredient_type + + @pytest.mark.parametrize( + "name", + [ + "hot sauce", + "cutlet" + ] + ) + def test_get_name(self, name): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, name, 100) + assert ingredient.get_name() == name + + @pytest.mark.parametrize( + "price", + [ + 100, + 300 + ] + ) + def test_get_price(self, price): + ingredient = Ingredient(INGREDIENT_TYPE_SAUCE, "test", price) + assert ingredient.get_price() == price + \ No newline at end of file