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
3 changes: 0 additions & 3 deletions .idea/.gitignore

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/inspectionProfiles/profiles_settings.xml

This file was deleted.

7 changes: 0 additions & 7 deletions .idea/misc.xml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/qa_python.iml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,60 @@
# qa_python
# qa_python
## Тестирование

В проекте реализовано **25 автоматизированных тестов** для класса `BooksCollector`. Тесты покрывают все методы и граничные случаи.

### Список тестов по методам

#### 1. `add_new_book` (5 тестов)
- Успешное добавление (имя ≤40 символов).
- Повторное добавление (дубликат).
- Пустое имя.
- Имя длиннее 40 символов.
- Ровно 40 символов.

#### 2. `set_book_genre` (3 теста)
- Установка жанра для существующей книги.
- Книга отсутствует в словаре.
- Жанр не в списке допустимых.

#### 3. `get_book_genre` (2 теста)
- Книга есть в словаре.
- Книги нет в словаре (`None`).


#### 4. `get_books_with_specific_genre` (3 теста)
- Найдены книги заданного жанра.
- Книг жанра нет (пустой список).
- Жанр не в списке допустимых (пустой список).


#### 5. `get_books_genre` (1 тест)
- Возврат полного словаря.

#### 6. `get_books_for_children` (3 теста)
- Книги без возрастного рейтинга.
- Книги с возрастным рейтингом (не попадают).
- Книга без жанра (не попадает).


#### 7. `add_book_in_favorites` (3 теста)
- Успешное добавление.
- Книги нет в словаре.
- Дубликат в избранном.


#### 8. `delete_book_from_favorites` (2 теста)
- Успешное удаление.
- Книги нет в избранном (без ошибок).


#### 9. `get_list_of_favorites_books` (5 тестов)
- Пустой список.
- Одна книга в избранном.
- Несколько книг.
- После удаления одной книги.
<<<<<<< HEAD
- Без изменений при добавлении не‑избранного.
=======
- Без изменений при добавлении не‑избранного.
>>>>>>> cfd82bf64599a64cb339780f328b12d95b5289c4
Binary file added __pycache__/main.cpython-314.pyc
Binary file not shown.
Binary file added __pycache__/tests.cpython-314-pytest-9.0.2.pyc
Binary file not shown.
240 changes: 238 additions & 2 deletions tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pytest

from main import BooksCollector

# класс TestBooksCollector объединяет набор тестов, которыми мы покрываем наше приложение BooksCollector
Expand All @@ -18,7 +20,241 @@ def test_add_new_book_add_two_books(self):

# проверяем, что добавилось именно две
# словарь books_rating, который нам возвращает метод get_books_rating, имеет длину 2
assert len(collector.get_books_rating()) == 2
assert len(collector.books_genre) == 2

# напиши свои тесты ниже
# чтобы тесты были независимыми в каждом из них создавай отдельный экземпляр класса BooksCollector()
# чтобы тесты были независимыми в каждом из них создавай отдельный экземпляр класса BooksCollector()
# 1. Тесты add_new_book
@pytest.mark.parametrize(
"book_name,expected_in_dict",
[
("Война и мир", True), # корректное имя
("", False), # пустое имя
("a" * 41, False), # >40 символов
("a" * 40, True), # ровно 40 символов
("1984", True), # короткое имя
]
)
def test_add_new_book_parametrized(self, book_name, expected_in_dict):
collector = BooksCollector()
collector.add_new_book(book_name)

if expected_in_dict:
assert book_name in collector.books_genre
assert collector.books_genre[book_name] == ""
else:
assert book_name not in collector.books_genre

# 2. Тесты set_book_genre
@pytest.mark.parametrize(
"book_name,genre,expected_genre",
[
("Гарри Поттер", "Фантастика", "Фантастика"), # валидный жанр
("Оно", "Ужасы", "Ужасы"), # валидный жанр
("Шерлок Холмс", "Детективы", "Детективы"), # валидный жанр
("Винни-Пух", "Мультфильмы", "Мультфильмы"), # валидный жанр
("Алиса", "Романтика", ""), # жанр не в списке genre
("Неизвестная книга", "Фантастика", None), # книги нет в словаре
]
)
def test_set_book_genre_parametrized(self, book_name, genre, expected_genre):
collector = BooksCollector()
# Предварительно добавляем книгу (если она должна быть в словаре)
if book_name != "Неизвестная книга":
collector.add_new_book(book_name)

collector.set_book_genre(book_name, genre)

if expected_genre is None:
assert book_name not in collector.books_genre # книга не добавлена
else:
assert collector.get_book_genre(book_name) == expected_genre

# 3. Тесты get_books_with_specific_genre
@pytest.mark.parametrize(
"genre,expected_books",
[
("Фантастика", ["Гарри Поттер", "Дюна"]),
("Ужасы", ["Оно", "Сияние"]),
("Детективы", ["Шерлок Холмс"]),
("Мультфильмы", ["Винни-Пух"]),
("Романтика", []), # жанр не в списке
("Комедии", []), # нет книг в жанре
]
)
def test_get_books_with_specific_genre_parametrized(self, genre, expected_books):
collector = BooksCollector()
# Добавляем книги с разными жанрами
books_data = [
("Гарри Поттер", "Фантастика"),
("Дюна", "Фантастика"),
("Оно", "Ужасы"),
("Сияние", "Ужасы"),
("Шерлок Холмс", "Детективы"),
("Винни-Пух", "Мультфильмы"),
]
for name, genre_val in books_data:
collector.add_new_book(name)
collector.set_book_genre(name, genre_val)

result = collector.get_books_with_specific_genre(genre)
assert sorted(result) == sorted(expected_books)

# 4. Тесты get_books_for_children
@pytest.mark.parametrize(
"books_data,expected_children_books",
[
(
[("Винни-Пух", "Мультфильмы"), ("Алиса", "Комедии")],
["Винни-Пух", "Алиса"]
),
(
[("Оно", "Ужасы"), ("Сияние", "Ужасы")],
[]
),
(
[("Дюна", "Фантастика"), ("Шерлок", "Детективы")],
["Дюна"] # Детективы — с возрастным рейтингом
),
(
[("Без жанра", "")],
[] # книга без жанра не подходит
),
]
)
def test_get_books_for_children_parametrized(self, books_data, expected_children_books):
collector = BooksCollector()
for name, genre in books_data:
collector.add_new_book(name)
if genre: # если жанр указан
collector.set_book_genre(name, genre)

result = collector.get_books_for_children()
assert sorted(result) == sorted(expected_children_books)

# 5. Тесты add_book_in_favorites
@pytest.mark.parametrize(
"book_name,is_in_books_genre,expected_in_favorites",
[
("Преступление и наказание", True, True), # книга есть в словаре
("Мастер и Маргарита", True, True), # книга есть в словаре
("Неизвестная книга", False, False), # книги нет в словаре
("Преступление и наказание", True, False), # дубликат (уже в избранном)
]
)
def test_add_book_in_favorites_parametrized(
self, book_name, is_in_books_genre, expected_in_favorites
):
collector = BooksCollector()
# Предварительно добавляем книгу, если нужно
if is_in_books_genre:
collector.add_new_book(book_name)
# Для случая дубликата — сразу добавляем в избранное
if book_name == "Преступление и наказание":
collector.add_book_in_favorites(book_name)

collector.add_book_in_favorites(book_name)

if expected_in_favorites:
assert book_name in collector.favorites
else:
assert book_name not in collector.favorites

# 6. Тесты delete_book_from_favorites
@pytest.mark.parametrize(
"book_name,is_in_favorites,expected_removed",
[
("Идиот", True, True), # книга в избранном
("Герой нашего времени", False, False), # книги нет в избранном
]
)
def test_delete_book_from_favorites_parametrized(
self, book_name, is_in_favorites, expected_removed
):
collector = BooksCollector()
if is_in_favorites:
collector.add_new_book(book_name)
collector.add_book_in_favorites(book_name)

collector.delete_book_from_favorites(book_name)

if expected_removed:
assert book_name not in collector.favorites
else:
assert book_name not in collector.favorites # или в словаре, или нигде

# 7. Тесты get_list_of_favorites_books
@pytest.mark.parametrize(
"favorites_data,expected_list",
[
([], []), # пустое избранное
(["Преступление и наказание"], ["Преступление и наказание"]), # одна книга
(["Мастер и Маргарита", "Идиот"], ["Мастер и Маргарита", "Идиот"]), # две книги
(["Война и мир"], ["Война и мир"]), # одна книга (проверка порядка)
]
)
def test_get_list_of_favorites_books_parametrized(self, favorites_data, expected_list):
collector = BooksCollector()
# Добавляем книги в словарь и в избранное
for book in favorites_data:
collector.add_new_book(book)
collector.add_book_in_favorites(book)

result = collector.get_list_of_favorites_books()
assert sorted(result) == sorted(expected_list)

# 8. Тесты get_books_genre

@pytest.mark.parametrize(
"books_data,expected_dict",
[
(
[],
{} # пустой словарь
),
(
[("Война и мир", "Классика"), ("1984", "Фантастика")],
{"Война и мир": "Классика", "1984": "Фантастика"} # две книги с жанрами
),
(
[("Без жанра", "")],
{"Без жанра": ""} # книга без жанра
),
(
[("Дубровский", "Приключения"), ("Мёртвые души", "Сатира")],
{"Дубровский": "Приключения", "Мёртвые души": "Сатира"} # разные жанры
),
]
)
def test_get_books_genre_parametrized(self, books_data, expected_dict):
collector = BooksCollector()
# Добавляем книги и задаём жанры
for name, genre in books_data:
collector.add_new_book(name)
if genre: # если жанр указан
collector.set_book_genre(name, genre)

result = collector.get_books_genre()
assert result == expected_dict

# 9. Тесты get_book_genre
@pytest.mark.parametrize(
"book_name,books_data,expected_genre",
[
("Война и мир", [("Война и мир", "Классика")], "Классика"), # книга есть, жанр задан
("1984", [("1984", "Фантастика")], "Фантастика"), # книга есть, жанр задан
("Неизвестная книга", [], None), # книги нет в словаре
("Без жанра", [("Без жанра", "")], ""), # книга есть, но жанр не задан
("Дубровский", [("Дубровский", "Приключения")], "Приключения"), # другой жанр
]
)
def test_get_book_genre_parametrized(self, book_name, books_data, expected_genre):
collector = BooksCollector()
# Предварительно добавляем книги из books_data
for name, genre in books_data:
collector.add_new_book(name)
if genre:
collector.set_book_genre(name, genre)

result = collector.get_book_genre(book_name)
assert result == expected_genre