diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 1cc701d..981d55e 100644 --- a/README.md +++ b/README.md @@ -1 +1,11 @@ -# qa_python \ No newline at end of file +# qa_python +# реализованы +# add_new_book — добавляет новую книгу в словарь без указания жанра. Название книги может содержать максимум 40 символов. Одну и ту же книгу можно добавить только один раз. +# set_book_genre — устанавливает жанр книги, если книга есть в books_genreи её жанр входит в списокgenre. +# get_book_genre— выводит жанр книги по её имени. +# get_books_with_specific_genre— выводит список книг с определённым жанром. +# get_books_genre— выводит текущий словарь books_genre. +# get_books_for_children — возвращает книги, которые подходят детям. У жанра книги не должно быть возрастного рейтинга. +# add_book_in_favorites — добавляет книгу в избранное. Книга должна находиться в словаре books_genre. Повторно добавить книгу в избранное нельзя. +# delete_book_from_favorites — удаляет книгу из избранного, если она там есть. +# get_list_of_favorites_books — получает список избранных книг. \ No newline at end of file diff --git a/__pycache__/main.cpython-314.pyc b/__pycache__/main.cpython-314.pyc new file mode 100644 index 0000000..08aaa6e Binary files /dev/null and b/__pycache__/main.cpython-314.pyc differ diff --git a/__pycache__/tests.cpython-314-pytest-9.0.2.pyc b/__pycache__/tests.cpython-314-pytest-9.0.2.pyc new file mode 100644 index 0000000..3c2a613 Binary files /dev/null and b/__pycache__/tests.cpython-314-pytest-9.0.2.pyc differ diff --git a/tests.py b/tests.py index 383385e..4e622a6 100644 --- a/tests.py +++ b/tests.py @@ -1,3 +1,4 @@ +import pytest from main import BooksCollector # класс TestBooksCollector объединяет набор тестов, которыми мы покрываем наше приложение BooksCollector @@ -16,9 +17,227 @@ def test_add_new_book_add_two_books(self): collector.add_new_book('Гордость и предубеждение и зомби') collector.add_new_book('Что делать, если ваш кот хочет вас убить') - # проверяем, что добавилось именно две - # словарь books_rating, который нам возвращает метод get_books_rating, имеет длину 2 - assert len(collector.get_books_rating()) == 2 + # проверяем, что добавилось именно две книги + # словарь books_genre, который нам возвращает метод get_books_genre, имеет длину 2 + assert len(collector.get_books_genre()) == 2 - # напиши свои тесты ниже - # чтобы тесты были независимыми в каждом из них создавай отдельный экземпляр класса BooksCollector() \ No newline at end of file + # добавление книг с разной длиной названия + @pytest.mark.parametrize('name, expected_in_books', [ + ('Нормальная книга', True), # корректное название + ('', False), # пустое название + ('а' * 41, False), # 41 символ (больше 40) + ('а' * 40, True), # 40 символов (граничное значение) + ('а' * 1, True), # 1 символ (граничное значение) + ('Книга с очень длинным названием которое почти сорок', False) # больше 40 + ]) + def test_add_new_book_different_lengths(self, name, expected_in_books): + collector = BooksCollector() + collector.add_new_book(name) + assert (name in collector.books_genre) == expected_in_books + + # (отдельный тест, так как параметризация здесь неудобна) + def test_add_new_book_duplicate(self): + collector = BooksCollector() + book_name = 'Дублирующая книга' + + # добавляем первый раз + collector.add_new_book(book_name) + assert book_name in collector.books_genre + assert len(collector.books_genre) == 1 + + # добавляем второй раз (дубликат) + collector.add_new_book(book_name) + assert book_name in collector.books_genre + assert len(collector.books_genre) == 1 # количество не должно увеличиться + + # установка валидных жанров + @pytest.mark.parametrize('genre', ['Фантастика', 'Ужасы', 'Детективы', 'Мультфильмы', 'Комедии']) + def test_set_book_genre_valid_genres(self, genre): + collector = BooksCollector() + book_name = 'Тестовая книга' + collector.add_new_book(book_name) + collector.set_book_genre(book_name, genre) + assert collector.get_book_genre(book_name) == genre + + # установка невалидных жанров + @pytest.mark.parametrize('invalid_genre', ['Роман', 'Поэзия', 'Драма', 'Триллер', '']) + def test_set_book_genre_invalid_genres(self, invalid_genre): + collector = BooksCollector() + book_name = 'Тестовая книга' + collector.add_new_book(book_name) + collector.set_book_genre(book_name, invalid_genre) + assert collector.get_book_genre(book_name) == '' # жанр должен остаться пустым + + # получение жанра для разных книг + @pytest.mark.parametrize('book_name, genre, expected_genre', [ + ('Фантастическая книга', 'Фантастика', 'Фантастика'), + ('Страшная книга', 'Ужасы', 'Ужасы'), + ('Детективная книга', 'Детективы', 'Детективы'), + ('Мультик', 'Мультфильмы', 'Мультфильмы'), + ('Смешная книга', 'Комедии', 'Комедии'), + ('Книга без жанра', '', ''), + ]) + def test_get_book_genre_different_books(self, book_name, genre, expected_genre): + collector = BooksCollector() + + # добавляем книгу + collector.add_new_book(book_name) + + # устанавливаем жанр, если он указан + if genre: + collector.set_book_genre(book_name, genre) + + # проверяем, что метод возвращает правильный жанр + assert collector.get_book_genre(book_name) == expected_genre + # получение списка книг с определённым жанром + @pytest.mark.parametrize('genre, expected_books', [ + ('Фантастика', ['Фантастика 1', 'Фантастика 2']), + ('Детективы', ['Детектив 1']), + ('Ужасы', []), + ('Мультфильмы', ['Мультфильм 1']), + ('Комедии', ['Комедия 1', 'Комедия 2']), + ]) + def test_get_books_with_specific_genre(self, genre, expected_books): + collector = BooksCollector() + + # добавляем книги с разными жанрами + books_data = [ + ('Фантастика 1', 'Фантастика'), + ('Фантастика 2', 'Фантастика'), + ('Детектив 1', 'Детективы'), + ('Мультфильм 1', 'Мультфильмы'), + ('Комедия 1', 'Комедии'), + ('Комедия 2', 'Комедии'), + ] + for book_name, book_genre in books_data: + collector.add_new_book(book_name) + collector.set_book_genre(book_name, book_genre) + # получаем список книг с указанным жанром + books = collector.get_books_with_specific_genre(genre) + # проверяем, что получили ожидаемый список + assert books == expected_books + # проверка книг для детей + @pytest.mark.parametrize('book_name, genre, should_be_for_children', [ + ('Мультфильм для детей', 'Мультфильмы', True), + ('Смешная комедия', 'Комедии', True), + ('Космическая фантастика', 'Фантастика', True), + ('Страшный ужастик', 'Ужасы', False), + ('Загадочный детектив', 'Детективы', False), + ('Книга без жанра', '', False), + ]) + def test_get_books_for_children(self, book_name, genre, should_be_for_children): + collector = BooksCollector() + + # добавляем книгу + collector.add_new_book(book_name) + + # устанавливаем жанр, если он указан + if genre: + collector.set_book_genre(book_name, genre) + + # получаем список книг для детей + children_books = collector.get_books_for_children() + + # проверяем, есть ли книга в списке для детей + if should_be_for_children: + assert book_name in children_books + else: + assert book_name not in children_books + + # добавление книг в избранное + @pytest.mark.parametrize('book_name, book_exists, should_be_added', [ + ('Существующая книга', True, True), + ('Несуществующая книга', False, False), + ('', False, False), + ]) + def test_add_book_in_favorites(self, book_name, book_exists, should_be_added): + collector = BooksCollector() + + # если книга должна существовать, добавляем её в books_genre + if book_exists: + collector.add_new_book(book_name) + + # добавляем книгу в избранное + collector.add_book_in_favorites(book_name) + + # проверяем результат + if should_be_added: + assert book_name in collector.get_list_of_favorites_books() + else: + assert book_name not in collector.get_list_of_favorites_books() + + # удаление книг из избранного + @pytest.mark.parametrize('book_to_delete, expected_favorites', [ + ('Книга 1', ['Книга 2', 'Книга 3']), + ('Книга 2', ['Книга 1', 'Книга 3']), + ('Книга 3', ['Книга 1', 'Книга 2']), + ('Несуществующая книга', ['Книга 1', 'Книга 2', 'Книга 3']), + ]) + def test_delete_book_from_favorites(self, book_to_delete, expected_favorites): + collector = BooksCollector() + + # добавляем три книги в books_genre + collector.add_new_book('Книга 1') + collector.add_new_book('Книга 2') + collector.add_new_book('Книга 3') + + # добавляем все книги в избранное + collector.add_book_in_favorites('Книга 1') + collector.add_book_in_favorites('Книга 2') + collector.add_book_in_favorites('Книга 3') + + # удаляем указанную книгу + collector.delete_book_from_favorites(book_to_delete) + + # проверяем, что в избранном остались только ожидаемые книги + assert collector.get_list_of_favorites_books() == expected_favorites + + # добавление одной и той же книги в избранное дважды + def test_add_book_in_favorites_twice(self): + collector = BooksCollector() + book_name = 'Книга для избранного' + collector.add_new_book(book_name) + collector.add_book_in_favorites(book_name) + collector.add_book_in_favorites(book_name) + assert len(collector.get_list_of_favorites_books()) == 1 + assert collector.get_list_of_favorites_books() == [book_name] + + # получение словаря books_genre + def test_get_books_genre(self): + collector = BooksCollector() + collector.add_new_book('Книга 1') + collector.add_new_book('Книга 2') + collector.set_book_genre('Книга 1', 'Фантастика') + books_genre = collector.get_books_genre() + assert len(books_genre) == 2 + assert books_genre['Книга 1'] == 'Фантастика' + assert books_genre['Книга 2'] == '' + + # получение пустого списка избранного + def test_get_list_of_favorites_books_empty(self): + collector = BooksCollector() + assert collector.get_list_of_favorites_books() == [] + + # удаление книги, которой нет в избранном + def test_delete_book_from_favorites_nonexistent(self): + collector = BooksCollector() + collector.add_new_book('Книга 1') + collector.add_book_in_favorites('Книга 1') + collector.delete_book_from_favorites('Несуществующая книга') + assert collector.get_list_of_favorites_books() == ['Книга 1'] + + # установка жанра для несуществующей книги + def test_set_book_genre_for_nonexistent_book(self): + collector = BooksCollector() + collector.set_book_genre('Несуществующая книга', 'Фантастика') + assert collector.get_book_genre('Несуществующая книга') is None + + # изменение жанра у существующей книги + def test_set_book_genre_change_genre(self): + collector = BooksCollector() + book_name = 'Книга для смены жанра' + collector.add_new_book(book_name) + collector.set_book_genre(book_name, 'Ужасы') + assert collector.get_book_genre(book_name) == 'Ужасы' + collector.set_book_genre(book_name, 'Комедии') + assert collector.get_book_genre(book_name) == 'Комедии' \ No newline at end of file