From cde0ec335bf35b98b75efec18e2b83e2ffc96b45 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 12 Mar 2026 13:46:21 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20BooksCollector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 33 ++++++++++++- tests.py | 138 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 152 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1cc701d..0f5ace5 100644 --- a/README.md +++ b/README.md @@ -1 +1,32 @@ -# qa_python \ No newline at end of file +# qa_python + +## Тесты + +В проекте реализован набор автотестов на базе `pytest`, покрывающий функциональность класса `BooksCollector`. + +### Что проверяют тесты + +- **Добавление книг** + - Книга добавляется в словарь только при корректной длине названия (1–40 символов). + - Одна и та же книга не может быть добавлена повторно. + - У только что добавленной книги жанр по умолчанию пустой. + +- **Установка жанра** + - Жанр можно установить только для уже добавленной книги. + - Устанавливаются только жанры из предопределённого списка `genre`. + - При попытке установить недопустимый жанр значение жанра книги не изменяется. + +- **Получение информации о книгах** + - Корректный возврат жанра по названию книги. + - Корректный возврат всего словаря `books_genre` с актуальными данными. + - Получение списков книг с указанным жанром. + +- **Книги для детей** + - В список детских книг не попадают книги с жанрами из списка `genre_age_rating`. + - Книги без установленного жанра не учитываются в списке книг для детей. + +- **Избранные книги** + - В избранное можно добавить только книгу, уже присутствующую в `books_genre`. + - Одна и та же книга не может быть добавлена в избранное повторно. + - Удаление книги из избранного возможно только при её наличии в списке. + - Корректный возврат текущего списка избранных книг. \ No newline at end of file diff --git a/tests.py b/tests.py index 383385e..0da115d 100644 --- a/tests.py +++ b/tests.py @@ -1,24 +1,126 @@ +import pytest from main import BooksCollector -# класс TestBooksCollector объединяет набор тестов, которыми мы покрываем наше приложение BooksCollector -# обязательно указывать префикс Test -class TestBooksCollector: - # пример теста: - # обязательно указывать префикс test_ - # дальше идет название метода, который тестируем add_new_book_ - # затем, что тестируем add_two_books - добавление двух книг - def test_add_new_book_add_two_books(self): - # создаем экземпляр (объект) класса BooksCollector - collector = BooksCollector() +@pytest.fixture +def collector(): + return BooksCollector() - # добавляем две книги - collector.add_new_book('Гордость и предубеждение и зомби') - collector.add_new_book('Что делать, если ваш кот хочет вас убить') +def test_add_new_book_adds_book_without_genre(collector): + collector.add_new_book('Гарри Поттер') + assert collector.get_books_genre() == {'Гарри Поттер': ''} - # проверяем, что добавилось именно две - # словарь books_rating, который нам возвращает метод get_books_rating, имеет длину 2 - assert len(collector.get_books_rating()) == 2 - # напиши свои тесты ниже - # чтобы тесты были независимыми в каждом из них создавай отдельный экземпляр класса BooksCollector() \ No newline at end of file +def test_add_new_book_not_added_if_name_too_long(collector): + long_name = 'A' * 41 + collector.add_new_book(long_name) + assert long_name not in collector.get_books_genre() + + +def test_add_new_book_not_added_twice(collector): + collector.add_new_book('Книга') + collector.add_new_book('Книга') + assert list(collector.get_books_genre().keys()).count('Книга') == 1 + + +@pytest.mark.parametrize('genre', ['Фантастика', 'Комедии']) +def test_set_book_genre_sets_allowed_genre(collector, genre): + collector.add_new_book('Книга') + collector.set_book_genre('Книга', genre) + assert collector.get_book_genre('Книга') == genre + + +def test_set_book_genre_does_not_set_if_book_not_exist(collector): + collector.set_book_genre('Неизвестная книга', 'Фантастика') + assert collector.get_book_genre('Неизвестная книга') is None + + +def test_set_book_genre_does_not_set_if_genre_not_allowed(collector): + collector.add_new_book('Книга') + collector.set_book_genre('Книга', 'Роман') + assert collector.get_book_genre('Книга') == '' + + + +def test_get_book_genre_returns_none_for_unknown_book(collector): + assert collector.get_book_genre('Неизвестная книга') is None + + +def test_get_books_with_specific_genre_returns_only_matching(collector): + collector.add_new_book('Книга 1') + collector.add_new_book('Книга 2') + collector.add_new_book('Книга 3') + + collector.set_book_genre('Книга 1', 'Фантастика') + collector.set_book_genre('Книга 2', 'Ужасы') + collector.set_book_genre('Книга 3', 'Фантастика') + + result = collector.get_books_with_specific_genre('Фантастика') + assert sorted(result) == ['Книга 1', 'Книга 3'] + + +def test_get_books_with_specific_genre_returns_empty_if_genre_not_allowed(collector): + collector.add_new_book('Книга 1') + collector.set_book_genre('Книга 1', 'Фантастика') + result = collector.get_books_with_specific_genre('Роман') + assert result == [] + + +def test_get_books_genre_returns_actual_dict(collector): + collector.add_new_book('Книга 1') + collector.set_book_genre('Книга 1', 'Фантастика') + assert collector.get_books_genre() == {'Книга 1': 'Фантастика'} + + +def test_get_books_for_children_excludes_age_restricted_genres(collector): + collector.add_new_book('Страшилки') + collector.add_new_book('Смешарики') + collector.add_new_book('Дело Пуаро') + + collector.set_book_genre('Страшилки', 'Ужасы') + collector.set_book_genre('Смешарики', 'Мультфильмы') + collector.set_book_genre('Дело Пуаро', 'Детективы') + + result = collector.get_books_for_children() + assert result == ['Смешарики'] + + +def test_get_books_for_children_ignores_books_without_genre(collector): + collector.add_new_book('Без жанра') + assert collector.get_books_for_children() == [] + + + +def test_add_book_in_favorites_adds_only_existing_book(collector): + collector.add_new_book('Книга') + collector.add_book_in_favorites('Книга') + collector.add_book_in_favorites('Несуществующая') + assert collector.get_list_of_favorites_books() == ['Книга'] + + +def test_add_book_in_favorites_not_added_twice(collector): + collector.add_new_book('Книга') + collector.add_book_in_favorites('Книга') + collector.add_book_in_favorites('Книга') + assert collector.get_list_of_favorites_books() == ['Книга'] + + + +def test_delete_book_from_favorites_removes_if_exists(collector): + collector.add_new_book('Книга') + collector.add_book_in_favorites('Книга') + collector.delete_book_from_favorites('Книга') + assert collector.get_list_of_favorites_books() == [] + + +def test_delete_book_from_favorites_does_nothing_if_not_in_favorites(collector): + collector.add_new_book('Книга') + collector.delete_book_from_favorites('Книга') + assert collector.get_list_of_favorites_books() == [] + + +def test_get_list_of_favorites_books_returns_current_list(collector): + collector.add_new_book('Книга 1') + collector.add_new_book('Книга 2') + collector.add_book_in_favorites('Книга 1') + assert collector.get_list_of_favorites_books() == ['Книга 1'] From 79bba3c393693be21f1e53cc88409cce8eb92f75 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 15 Mar 2026 12:30:15 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=BD=D1=8B=D0=B5?= =?UTF-8?q?=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B8?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B8=20=D0=BA=D0=BD=D0=B8=D0=B3=D0=B8=20?= =?UTF-8?q?=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=BD=D0=BD=D0=BE=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tests.py b/tests.py index 0da115d..ef215cc 100644 --- a/tests.py +++ b/tests.py @@ -6,11 +6,24 @@ def collector(): return BooksCollector() + def test_add_new_book_adds_book_without_genre(collector): collector.add_new_book('Гарри Поттер') assert collector.get_books_genre() == {'Гарри Поттер': ''} +def test_add_new_book_adds_book_with_min_length_name(collector): + name = 'A' # длина 1 + collector.add_new_book(name) + assert name in collector.get_books_genre() + + +def test_add_new_book_adds_book_with_max_allowed_length_name(collector): + name = 'A' * 40 # длина 40 + collector.add_new_book(name) + assert name in collector.get_books_genre() + + def test_add_new_book_not_added_if_name_too_long(collector): long_name = 'A' * 41 collector.add_new_book(long_name) @@ -41,7 +54,6 @@ def test_set_book_genre_does_not_set_if_genre_not_allowed(collector): assert collector.get_book_genre('Книга') == '' - def test_get_book_genre_returns_none_for_unknown_book(collector): assert collector.get_book_genre('Неизвестная книга') is None @@ -90,14 +102,17 @@ def test_get_books_for_children_ignores_books_without_genre(collector): assert collector.get_books_for_children() == [] - def test_add_book_in_favorites_adds_only_existing_book(collector): collector.add_new_book('Книга') collector.add_book_in_favorites('Книга') - collector.add_book_in_favorites('Несуществующая') assert collector.get_list_of_favorites_books() == ['Книга'] +def test_add_book_in_favorites_does_not_add_if_book_not_in_collection(collector): + collector.add_book_in_favorites('Несуществующая') + assert collector.get_list_of_favorites_books() == [] + + def test_add_book_in_favorites_not_added_twice(collector): collector.add_new_book('Книга') collector.add_book_in_favorites('Книга') @@ -105,7 +120,6 @@ def test_add_book_in_favorites_not_added_twice(collector): assert collector.get_list_of_favorites_books() == ['Книга'] - def test_delete_book_from_favorites_removes_if_exists(collector): collector.add_new_book('Книга') collector.add_book_in_favorites('Книга')