From ed908f22bd767803a9d2cbc17f25c8fd0a93d5a1 Mon Sep 17 00:00:00 2001 From: Serg-nt Date: Tue, 6 May 2025 11:53:40 +0300 Subject: [PATCH 1/6] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B2=20tests.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests.py | 112 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 15 deletions(-) diff --git a/tests.py b/tests.py index 383385e..2a4f1e3 100644 --- a/tests.py +++ b/tests.py @@ -1,24 +1,106 @@ from main import BooksCollector +import pytest # класс 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(self): + return BooksCollector() - # добавляем две книги - collector.add_new_book('Гордость и предубеждение и зомби') - collector.add_new_book('Что делать, если ваш кот хочет вас убить') + def test_initial_state(self, collector): + assert collector.get_books_genre() == {} + assert collector.get_list_of_favorites_books() == [] - # проверяем, что добавилось именно две - # словарь books_rating, который нам возвращает метод get_books_rating, имеет длину 2 - assert len(collector.get_books_rating()) == 2 + def test_add_new_book_correct_add_book_successful_add(self, collector): + collector.add_new_book('Азбука') + assert collector.get_book_genre('Азбука') == '' + assert len(collector.get_books_genre()) == 1 + + def test_add_new_book_incorrect_add_book_unsuccessful_add(self, collector): + collector.add_new_book('Азбука') + assert len(collector.get_books_genre()) == 1 + collector.add_new_book('Азбука') + assert len(collector.get_books_genre()) == 1 + collector.add_new_book('Азбука' * 10) + assert len(collector.get_books_genre()) == 1 - # напиши свои тесты ниже - # чтобы тесты были независимыми в каждом из них создавай отдельный экземпляр класса BooksCollector() \ No newline at end of file + def test_set_book_genre_correct_genre_success(self, collector): + collector.add_new_book('Азбука') + collector.set_book_genre('Азбука', 'Ужасы') + assert collector.books_genre['Азбука'] == 'Ужасы' + + def test_set_book_genre_incorrect_genre_unsuccess(self, collector): + collector.set_book_genre('Азбука', 'Ужасы') + assert len(collector.books_genre) == 0 + collector.add_new_book('Азбука') + collector.set_book_genre('Азбука', 'FFFFFF') + assert collector.books_genre['Азбука'] == '' + + def test_get_book_genre(self, collector): + collector.add_new_book('Азбука') + collector.set_book_genre('Азбука', 'Ужасы') + assert collector.get_book_genre('Азбука') == 'Ужасы' + + def test_get_books_with_specific_genre(self, collector): + books = ['Азбука', 'Алгебра', 'Маленький принц'] + for book in books: + collector.add_new_book(book) + collector.set_book_genre(book, 'Ужасы') + + collector.add_new_book('Ну погоди') + collector.set_book_genre('Ну погоди', 'Мультфильмы') + + assert len(collector.get_books_with_specific_genre('Ужасы')) == 3 + assert len(collector.get_books_with_specific_genre('Мультфильмы')) == 1 + + def test_get_books_genre(self, collector): + collector.add_new_book('Азбука') + assert collector.get_books_genre() == {'Азбука': ''} + + def test_get_books_for_children(self, collector): + books = ['детская1', 'детская2', 'детская3', 'взрослая1', 'взрослая2'] + genres = ['Фантастика', 'Мультфильмы', 'Комедии', 'Ужасы', 'Детективы'] + + for i in range(len(books)): + collector.add_new_book(books[i]) + collector.set_book_genre(books[i], genres[i]) + + children_books = collector.get_books_for_children() + assert len(children_books) == 3 + assert 'детская1' in children_books + assert 'детская2' in children_books + assert 'детская3' in children_books + assert 'взрослая1' not in children_books + assert 'взрослая2' not in children_books + + def test_add_book_in_favorites(self, collector): + collector.add_book_in_favorites('Азбука') + assert len(collector.get_books_genre()) == 0 + collector.add_new_book('Азбука') + collector.add_book_in_favorites('Азбука') + assert len(collector.get_books_genre()) == 1 + assert len(collector.favorites) == 1 + assert 'Азбука' in collector.favorites + collector.add_book_in_favorites('Азбука') + assert len(collector.favorites) == 1 + + def test_delete_book_from_favorites(self, collector): + collector.add_new_book('Азбука') + collector.add_book_in_favorites('Азбука') + collector.delete_book_from_favorites('Алгебра') + assert len(collector.favorites) == 1 + assert 'Азбука' in collector.favorites + collector.delete_book_from_favorites('Азбука') + assert len(collector.favorites) == 0 + assert 'Азбука' not in collector.favorites + + def get_list_of_favorites_books(self, collector): + collector.add_new_book('Азбука') + collector.add_book_in_favorites('Азбука') + collector.add_new_book('Алгебра') + collector.add_book_in_favorites('Алгебра') + assert len(collector.get_list_of_favorites_books()) == 2 + assert 'Азбука' in collector.get_list_of_favorites_books() + assert 'Алгебра' in collector.get_list_of_favorites_books() \ No newline at end of file From 94b22430d0351a8570c24d1c808259552e30cc8a Mon Sep 17 00:00:00 2001 From: Serg-nt Date: Wed, 14 May 2025 13:27:21 +0300 Subject: [PATCH 2/6] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests.py | 107 +++++++++++++++++++++++-------------------------------- 1 file changed, 45 insertions(+), 62 deletions(-) diff --git a/tests.py b/tests.py index 2a4f1e3..5484ccc 100644 --- a/tests.py +++ b/tests.py @@ -1,49 +1,48 @@ -from main import BooksCollector import pytest +from main import BooksCollector + -# класс TestBooksCollector объединяет набор тестов, которыми мы покрываем наше приложение BooksCollector -# обязательно указывать префикс Test class TestBooksCollector: - @pytest.fixture - def collector(self): - return BooksCollector() + def test_initial_state(self): + collector = BooksCollector() + assert collector.get_books_genre() == {} and collector.get_list_of_favorites_books() == [] - def test_initial_state(self, collector): - assert collector.get_books_genre() == {} - assert collector.get_list_of_favorites_books() == [] - - def test_add_new_book_correct_add_book_successful_add(self, collector): + def test_add_new_book_correct_add_book_successful_add(self): + collector = BooksCollector() collector.add_new_book('Азбука') assert collector.get_book_genre('Азбука') == '' - assert len(collector.get_books_genre()) == 1 - - def test_add_new_book_incorrect_add_book_unsuccessful_add(self, collector): - collector.add_new_book('Азбука') - assert len(collector.get_books_genre()) == 1 - collector.add_new_book('Азбука') - assert len(collector.get_books_genre()) == 1 - collector.add_new_book('Азбука' * 10) - assert len(collector.get_books_genre()) == 1 - def test_set_book_genre_correct_genre_success(self, collector): + @pytest.mark.parametrize("name, expected_count", [ + ('Азбука', 1), + ('', 0), + ('Азбука' * 10, 0) + ]) + def test_add_new_book_incorrect_add_book_unsuccessful_add(self, name, expected_count): + collector = BooksCollector() + collector.add_new_book(name) + assert len(collector.get_books_genre()) == expected_count + + def test_set_book_genre_correct_genre_success(self): + collector = BooksCollector() collector.add_new_book('Азбука') collector.set_book_genre('Азбука', 'Ужасы') assert collector.books_genre['Азбука'] == 'Ужасы' - def test_set_book_genre_incorrect_genre_unsuccess(self, collector): - collector.set_book_genre('Азбука', 'Ужасы') - assert len(collector.books_genre) == 0 + def test_set_book_genre_incorrect_genre_unsuccess(self): + collector = BooksCollector() collector.add_new_book('Азбука') collector.set_book_genre('Азбука', 'FFFFFF') assert collector.books_genre['Азбука'] == '' - def test_get_book_genre(self, collector): + def test_get_book_genre(self): + collector = BooksCollector() collector.add_new_book('Азбука') collector.set_book_genre('Азбука', 'Ужасы') assert collector.get_book_genre('Азбука') == 'Ужасы' - def test_get_books_with_specific_genre(self, collector): + def test_get_books_with_specific_genre(self): + collector = BooksCollector() books = ['Азбука', 'Алгебра', 'Маленький принц'] for book in books: collector.add_new_book(book) @@ -52,55 +51,39 @@ def test_get_books_with_specific_genre(self, collector): collector.add_new_book('Ну погоди') collector.set_book_genre('Ну погоди', 'Мультфильмы') - assert len(collector.get_books_with_specific_genre('Ужасы')) == 3 - assert len(collector.get_books_with_specific_genre('Мультфильмы')) == 1 + assert collector.get_books_with_specific_genre('Ужасы') == books - def test_get_books_genre(self, collector): + def test_get_books_genre(self): + collector = BooksCollector() collector.add_new_book('Азбука') assert collector.get_books_genre() == {'Азбука': ''} - def test_get_books_for_children(self, collector): - books = ['детская1', 'детская2', 'детская3', 'взрослая1', 'взрослая2'] - genres = ['Фантастика', 'Мультфильмы', 'Комедии', 'Ужасы', 'Детективы'] - - for i in range(len(books)): - collector.add_new_book(books[i]) - collector.set_book_genre(books[i], genres[i]) + def test_get_books_for_children(self): + collector = BooksCollector() + collector.add_new_book('Детская') + collector.add_new_book('Взрослая') + collector.set_book_genre('Детская', 'Фантастика') + collector.set_book_genre('Взрослая', 'Ужасы') - children_books = collector.get_books_for_children() - assert len(children_books) == 3 - assert 'детская1' in children_books - assert 'детская2' in children_books - assert 'детская3' in children_books - assert 'взрослая1' not in children_books - assert 'взрослая2' not in children_books + assert collector.get_books_for_children() == ['Детская'] - def test_add_book_in_favorites(self, collector): - collector.add_book_in_favorites('Азбука') - assert len(collector.get_books_genre()) == 0 + def test_add_book_in_favorites(self): + collector = BooksCollector() collector.add_new_book('Азбука') collector.add_book_in_favorites('Азбука') - assert len(collector.get_books_genre()) == 1 - assert len(collector.favorites) == 1 - assert 'Азбука' in collector.favorites - collector.add_book_in_favorites('Азбука') - assert len(collector.favorites) == 1 + assert collector.get_list_of_favorites_books() == ['Азбука'] - def test_delete_book_from_favorites(self, collector): + def test_delete_book_from_favorites(self): + collector = BooksCollector() collector.add_new_book('Азбука') collector.add_book_in_favorites('Азбука') - collector.delete_book_from_favorites('Алгебра') - assert len(collector.favorites) == 1 - assert 'Азбука' in collector.favorites collector.delete_book_from_favorites('Азбука') - assert len(collector.favorites) == 0 - assert 'Азбука' not in collector.favorites + assert collector.get_list_of_favorites_books() == [] - def get_list_of_favorites_books(self, collector): + def test_get_list_of_favorites_books(self): + collector = BooksCollector() collector.add_new_book('Азбука') - collector.add_book_in_favorites('Азбука') collector.add_new_book('Алгебра') + collector.add_book_in_favorites('Азбука') collector.add_book_in_favorites('Алгебра') - assert len(collector.get_list_of_favorites_books()) == 2 - assert 'Азбука' in collector.get_list_of_favorites_books() - assert 'Алгебра' in collector.get_list_of_favorites_books() \ No newline at end of file + assert collector.get_list_of_favorites_books() == ['Азбука', 'Алгебра'] \ No newline at end of file From 102d8895ebc4feb4fa453c83cd6bc477719b86ae Mon Sep 17 00:00:00 2001 From: Serg-nt Date: Wed, 14 May 2025 13:41:37 +0300 Subject: [PATCH 3/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20README=20=D1=81=D0=BE=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA?= =?UTF-8?q?=D0=BE=D0=BC=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cc701d..286080d 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ -# qa_python \ No newline at end of file +# qa_python +Тесты для BooksCollector + +test_initial_state - проверка первоначального состояния +test_add_new_book_correct_add_book_successful_add - проверка добавления книги в словарь без жанра +test_add_new_book_incorrect_add_book_unsuccessful_add - проверка добавления книги в словарь +test_set_book_genre_correct_genre_success - проверка на успешную установку жанра из списка +test_set_book_genre_incorrect_genre_unsuccess - проверку жанр не входящий в список не устанавливается +test_get_book_genre - получение книг по жанрам +test_get_books_with_specific_genre - проверка выведения списка книг с определенным жанром +test_get_books_genre - проверка получения списка книг +test_get_books_for_children - проверка возврата детских книг +test_add_book_in_favorites - проверка добавления книги в избранное +test_delete_book_from_favorites - проверка удаления книги из избранного +test_get_list_of_favorites_books - проверка получения списка избранных книг \ No newline at end of file From 4dd5cbc102fdcbb2f21b0adce504dae09d9e26c8 Mon Sep 17 00:00:00 2001 From: Artur Kozlov Date: Mon, 2 Feb 2026 09:38:09 +0300 Subject: [PATCH 4/6] Fix tests structure and naming --- .gitignore | 2 + __pycache__/main.cpython-38.pyc | Bin 2030 -> 0 bytes __pycache__/test.cpython-38-pytest-7.1.2.pyc | Bin 8183 -> 0 bytes tests.py | 172 +++++++++---------- 4 files changed, 86 insertions(+), 88 deletions(-) create mode 100644 .gitignore delete mode 100644 __pycache__/main.cpython-38.pyc delete mode 100644 __pycache__/test.cpython-38-pytest-7.1.2.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a60b85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.pyc diff --git a/__pycache__/main.cpython-38.pyc b/__pycache__/main.cpython-38.pyc deleted file mode 100644 index 5786eeb8eea4dc1762353e0d9309eb8d1407edbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2030 zcmb7FO>Y}F5GA=Qc`dI$>NrlLq-jwYMHQgYy$FmT3DBD^PA)W9_a&t`k^T zpOPOEAN7~^nq1OrZ#{J$SBj*y9H1099CC-`n>RDm%kAw3qxSjlt5^3o82g0Da`R~N zgu2})@dr~(@ekDBi!M{*gtfdrt*&*HfPIY4lZ1)oHA$ z4HeK>SDUIq7jh68o5}G-cA6$~Y|_^Rs2%sB;-B@R_4r zWG>|I#aSJ*WwcYTV~}%Swn(%*2ib(A7d6vMhMJau-0WbfUdE^Dz^>Jq13!!3HrdX6 zX!6N}iVqdzn`s7$g&QZ#AP5FH4Q{xGf_Pp=ffBJUhSxDvOjj_}Xx~>VpVDN=E*)j& zIOiEh?KmQj9X4^rp0mH2e~L@*($D>zp9%AGEcf~n-LpmWx;b>z;C#qE|Nxns&x=o~kmG7eLRNArbM}w$8Bi2Qsy9I;!3aVl$mmbVLTYtbISzGYR zxX%yxJ`Z>(Ccjl8^zAdQl{b>zL3v#T{i%{X|CdX#IF2p3-(D zTq~9N%M3wTnG^_Ara0RmjYbLz)hl;Z>XK<55-?&Ab8`n`U3T3@={e$~M1Fmqj>z1? zZN@|1;FF^Y^0k|8hVLF0_n1(j9=iN;Ps}o8;eb*p>NtI?*J5odJ<^#j;SNk1F91IT zV0g*^w^f0A^S=KRbVua6px;B#M-jcy>0klL!L)4vn^o(>3aoEz>$F0=>v&eBEE-bA zsX8A)52bu_-W!!)%qAUgb|DTRZbN(zaTfx-oBI$yKrCv?X?T(ik{sRr^9CZQxt||2 c0zaq+HTS(k84sIv2Nc2M6525={-MtP1Ay7ZO8@`> diff --git a/__pycache__/test.cpython-38-pytest-7.1.2.pyc b/__pycache__/test.cpython-38-pytest-7.1.2.pyc deleted file mode 100644 index b2898a8a207c1ae4014c5ac436acbbfebcdd6cd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8183 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 40 символов не добавляется +def test_add_new_book_with_long_name_is_not_added(books_collector): + long_name = 'А' * 41 + books_collector.add_new_book(long_name) + assert long_name not in books_collector.get_books_genre() + + +# set_book_genre + get_book_genre — жанр устанавливается корректно +def test_set_and_get_book_genre_returns_correct_genre(books_collector): + books_collector.add_new_book('Матрица') + books_collector.set_book_genre('Матрица', 'Фантастика') + assert books_collector.get_book_genre('Матрица') == 'Фантастика' + + +# set_book_genre — жанр не из списка не устанавливается +def test_set_book_genre_not_from_allowed_list_is_not_set(books_collector): + books_collector.add_new_book('Оно') + books_collector.set_book_genre('Оно', 'Роман') + assert books_collector.get_book_genre('Оно') == '' + + +# get_books_with_specific_genre — возвращаются книги нужного жанра +def test_get_books_with_specific_genre_returns_correct_books(books_collector): + books_collector.add_new_book('Чужой') + books_collector.set_book_genre('Чужой', 'Ужасы') + + books_collector.add_new_book('Назад в будущее') + books_collector.set_book_genre('Назад в будущее', 'Фантастика') + + assert books_collector.get_books_with_specific_genre('Ужасы') == ['Чужой'] + + +# get_books_for_children — книги с возрастным рейтингом исключаются +def test_get_books_for_children_excludes_age_restricted_genres(books_collector): + books_collector.add_new_book('Оно') + books_collector.set_book_genre('Оно', 'Ужасы') + + books_collector.add_new_book('Король Лев') + books_collector.set_book_genre('Король Лев', 'Мультфильмы') + + assert books_collector.get_books_for_children() == ['Король Лев'] + + +# add_book_in_favorites — книга добавляется в избранное +def test_add_book_in_favorites_adds_book(books_collector): + books_collector.add_new_book('Интерстеллар') + books_collector.add_book_in_favorites('Интерстеллар') + assert 'Интерстеллар' in books_collector.get_list_of_favorites_books() + + +# add_book_in_favorites — книга не добавляется повторно +def test_add_book_in_favorites_does_not_duplicate(books_collector): + books_collector.add_new_book('Гарри Поттер') + books_collector.add_book_in_favorites('Гарри Поттер') + books_collector.add_book_in_favorites('Гарри Поттер') + assert books_collector.get_list_of_favorites_books().count('Гарри Поттер') == 1 + + +# delete_book_from_favorites — книга удаляется из избранного +def test_delete_book_from_favorites_removes_book(books_collector): + books_collector.add_new_book('Аватар') + books_collector.add_book_in_favorites('Аватар') + books_collector.delete_book_from_favorites('Аватар') + assert 'Аватар' not in books_collector.get_list_of_favorites_books() From 4b2e4d4a41ee1eb957b2d494571539f3344ce649 Mon Sep 17 00:00:00 2001 From: Artur Kozlov Date: Fri, 30 Jan 2026 14:26:05 +0300 Subject: [PATCH 5/6] Add unit tests for BooksCollector --- __init__.py | 0 __pycache__/__init__.cpython-311.pyc | Bin 0 -> 143 bytes __pycache__/main.cpython-311.pyc | Bin 0 -> 3689 bytes .../test_main.cpython-311-pytest-9.0.2.pyc | Bin 0 -> 3835 bytes __pycache__/tests.cpython-311-pytest-9.0.2.pyc | Bin 0 -> 15170 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 __init__.py create mode 100644 __pycache__/__init__.cpython-311.pyc create mode 100644 __pycache__/main.cpython-311.pyc create mode 100644 __pycache__/test_main.cpython-311-pytest-9.0.2.pyc create mode 100644 __pycache__/tests.cpython-311-pytest-9.0.2.pyc diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/__pycache__/__init__.cpython-311.pyc b/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d621d6a34e652faebcc9fe486d6838cffcf6991 GIT binary patch literal 143 zcmZ3^%ge<81je~FnIQTxh=2h`DC095kTIPhg&~+hlhJP_LlF~@{~09tOUcLyM{ED zY11?hRN(RC1T7!XuH8$MDb7G*QJ%M7D)Z z1Ac{4W%qq3tP_n)3o4lwRpBm~wy7eZU9|y9svWRFl>iT^4S){y5MZO~0Blkl0i9|S zpi6baDy~Ay+wu5yVGyPt{+_u*w=$mrZqsLU>m{;BzoWl0Za(6xSmO%_vCR;$a^pG^;6kC=rRxZVCmvp+#p5bkzT#{y$>8MDz|AYC4WFLdTO{rHmF3&q2OcH{%?}F@U|* zK^=0vAJ(Dz2F9(ES+b1V2W6i03AVwN+c{R*p04D?97G;L>9JLtBp>;&K)+?%vOQ%_ z3D?;e6iOOdtV=0d^|2MmYHtcI3C@?jER=!-(QMu*G=vrww3sSOTsJ70!ZAEchH^8K zm{W`eEgYGNgt=gtt_n@q&J6~J1dx|0ur8C;J%=Yx)#&ZO-bZ0-^S}m9P)9F_Fz56Y ziLLQ`TH5gb*g^dxkn@55Twru3FqRFBWdh^5z<7~}&F2|pJpMKN+O>RJSGqmhc7nE@ z$a{x&yrWs~=+@=;u3Z?H4SMWp-daP^ea_$*I6Ob>ff3?xnco zF1yBVie&e`uCw-D9FLQj`lF7X`rl(I?kniY6jv2O(v`m*dhk@Is8dW);<7D;VcAmQ zlAw1pi=`|Ul7uv_T9;B{ozjL z7i~Fe;gV%l9WIku**_WFm($8_L72>V# z2M8VwgT7pPl?ocDO|x9oU=Sx+#nW;}yA&mc8(QQ|j5 zp7lI{xDWRxuCpqR?y36yX)^B)WT()eYxD6Xt)8F`Rf}o~jdL`k$LA|pl51Gnzv~E6 zg;2Ue?_Z$KUdVZuXLV}F)thzorUMz*$(-vXHFMEM;633i>8a8=EdOUXVw+wYj(m86 zq7fsZ#AnKmFz1ZqK#e;G^gW0E;DKggYV{L%Z?fH+lAG~Ki_bGfDKsg{d|X|OV%eoA zHx@%t-lF59TgSkz`w+Si`VjDt>iq}<2q-aq7+{mI`PpMnN8cGB5ynpdx2?aT-7dW& z6iEfPh!VWVENBv?L9CXbNstEMwPu2&L4r4+1+9YQ$JP=!BVo~G|CRXa*T7{F6g7sz`T3|3h=TNgray(fEnxIFSPx=M+2Mq EUpjwX7XSbN literal 0 HcmV?d00001 diff --git a/__pycache__/test_main.cpython-311-pytest-9.0.2.pyc b/__pycache__/test_main.cpython-311-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74025ebb8a073e89dbab0908d29e3e55bf8d983e GIT binary patch literal 3835 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 literal 0 HcmV?d00001 From 8bb7337805687744718bd2075b1202467098817d Mon Sep 17 00:00:00 2001 From: Artur Kozlov Date: Mon, 2 Feb 2026 11:17:33 +0300 Subject: [PATCH 6/6] Add tests for BooksCollector --- test_books_collector.py | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test_books_collector.py diff --git a/test_books_collector.py b/test_books_collector.py new file mode 100644 index 0000000..a6d83c0 --- /dev/null +++ b/test_books_collector.py @@ -0,0 +1,85 @@ +import pytest +from qa_python.main import BooksCollector + + +@pytest.fixture +def books_collector(): + return BooksCollector() + + +# add_new_book — книга добавляется в коллекцию +def test_add_new_book_adds_book_to_collection(books_collector): + books_collector.add_new_book('Властелин колец') + assert 'Властелин колец' in books_collector.get_books_genre() + + +# add_new_book — новая книга добавляется без жанра +def test_add_new_book_has_empty_genre_by_default(books_collector): + books_collector.add_new_book('Дюна') + assert books_collector.get_book_genre('Дюна') == '' + + +# add_new_book — книга с названием > 40 символов не добавляется +def test_add_new_book_with_long_name_is_not_added(books_collector): + long_name = 'А' * 41 + books_collector.add_new_book(long_name) + assert long_name not in books_collector.get_books_genre() + + +# set_book_genre + get_book_genre — жанр устанавливается корректно +def test_set_and_get_book_genre_returns_correct_genre(books_collector): + books_collector.add_new_book('Матрица') + books_collector.set_book_genre('Матрица', 'Фантастика') + assert books_collector.get_book_genre('Матрица') == 'Фантастика' + + +# set_book_genre — жанр не из списка не устанавливается +def test_set_book_genre_not_from_allowed_list_is_not_set(books_collector): + books_collector.add_new_book('Оно') + books_collector.set_book_genre('Оно', 'Роман') + assert books_collector.get_book_genre('Оно') == '' + + +# get_books_with_specific_genre — возвращаются книги нужного жанра +def test_get_books_with_specific_genre_returns_correct_books(books_collector): + books_collector.add_new_book('Чужой') + books_collector.set_book_genre('Чужой', 'Ужасы') + + books_collector.add_new_book('Назад в будущее') + books_collector.set_book_genre('Назад в будущее', 'Фантастика') + + assert books_collector.get_books_with_specific_genre('Ужасы') == ['Чужой'] + + +# get_books_for_children — книги с возрастным рейтингом исключаются +def test_get_books_for_children_excludes_age_restricted_genres(books_collector): + books_collector.add_new_book('Оно') + books_collector.set_book_genre('Оно', 'Ужасы') + + books_collector.add_new_book('Король Лев') + books_collector.set_book_genre('Король Лев', 'Мультфильмы') + + assert books_collector.get_books_for_children() == ['Король Лев'] + + +# add_book_in_favorites — книга добавляется в избранное +def test_add_book_in_favorites_adds_book(books_collector): + books_collector.add_new_book('Интерстеллар') + books_collector.add_book_in_favorites('Интерстеллар') + assert 'Интерстеллар' in books_collector.get_list_of_favorites_books() + + +# add_book_in_favorites — книга не добавляется повторно +def test_add_book_in_favorites_does_not_duplicate(books_collector): + books_collector.add_new_book('Гарри Поттер') + books_collector.add_book_in_favorites('Гарри Поттер') + books_collector.add_book_in_favorites('Гарри Поттер') + assert books_collector.get_list_of_favorites_books().count('Гарри Поттер') == 1 + + +# delete_book_from_favorites — книга удаляется из избранного +def test_delete_book_from_favorites_removes_book(books_collector): + books_collector.add_new_book('Аватар') + books_collector.add_book_in_favorites('Аватар') + books_collector.delete_book_from_favorites('Аватар') + assert 'Аватар' not in books_collector.get_list_of_favorites_books()