From ef9c0445d2c90b3c107db013d1118a1c1fb96bcc Mon Sep 17 00:00:00 2001 From: Aleksey Doludin Date: Fri, 4 Jul 2025 16:45:07 +0300 Subject: [PATCH 1/6] =?UTF-8?q?=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B0=D0=B2=D1=82=D0=BE=D1=82=D0=B5=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .coverage | Bin 0 -> 53248 bytes __pycache__/main.cpython-311.pyc | Bin 0 -> 3691 bytes .../tests.cpython-311-pytest-8.4.1.pyc | Bin 0 -> 22381 bytes tests.py | 103 +++++++++++++++--- 4 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 .coverage create mode 100644 __pycache__/main.cpython-311.pyc create mode 100644 __pycache__/tests.cpython-311-pytest-8.4.1.pyc diff --git a/.coverage b/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..32c3236720a1b99feb786c3f624dfeac217e5371 GIT binary patch literal 53248 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 PGd99sX#0Dc20rn>tm9qm literal 0 HcmV?d00001 diff --git a/__pycache__/tests.cpython-311-pytest-8.4.1.pyc b/__pycache__/tests.cpython-311-pytest-8.4.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20a1b1377a8b08ee6c7d7fc6579c9bff3ee04ca4 GIT binary patch literal 22381 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 L`L7$~%6k1DGG#X1 literal 0 HcmV?d00001 diff --git a/tests.py b/tests.py index 383385e..34f5e67 100644 --- a/tests.py +++ b/tests.py @@ -1,24 +1,93 @@ +import pytest from main import BooksCollector -# класс TestBooksCollector объединяет набор тестов, которыми мы покрываем наше приложение BooksCollector -# обязательно указывать префикс Test class TestBooksCollector: + @pytest.fixture + def collector(self): + """Фикстура для чистого коллектора книг""" + return BooksCollector() + + @pytest.fixture + def collector_with_books(self): + """Фикстура с подготовленными данными: + - 2 книги с разными жанрами + - 1 книга в избранном""" + collector = BooksCollector() # Создаем новый экземпляр + # Добавляем тестовые данные + collector.add_new_book("Книга 1") + collector.add_new_book("Книга 2") + collector.set_book_genre("Книга 1", "Фантастика") + collector.set_book_genre("Книга 2", "Комедии") + collector.add_book_in_favorites("Книга 1") + return collector - # пример теста: - # обязательно указывать префикс test_ - # дальше идет название метода, который тестируем add_new_book_ - # затем, что тестируем add_two_books - добавление двух книг - def test_add_new_book_add_two_books(self): - # создаем экземпляр (объект) класса BooksCollector - collector = BooksCollector() + # Базовые тесты + def test_add_new_book_valid_name(self, collector): + collector.add_new_book('Том Сойер') + assert 'Том Сойер' in collector.get_books_genre() - # добавляем две книги - collector.add_new_book('Гордость и предубеждение и зомби') - collector.add_new_book('Что делать, если ваш кот хочет вас убить') + def test_add_new_book_invalid_name_too_short(self, collector): + collector.add_new_book('') + assert '' not in collector.get_books_genre() - # проверяем, что добавилось именно две - # словарь books_rating, который нам возвращает метод get_books_rating, имеет длину 2 - assert len(collector.get_books_rating()) == 2 + def test_add_new_book_invalid_name_too_long(self, collector): + long_name = 'x' * 41 + collector.add_new_book(long_name) + assert long_name not in collector.get_books_genre() - # напиши свои тесты ниже - # чтобы тесты были независимыми в каждом из них создавай отдельный экземпляр класса BooksCollector() \ No newline at end of file + def test_add_new_book_duplicate(self, collector): + collector.add_new_book('Том Сойер') + collector.add_new_book('Том Сойер') + assert len(collector.get_books_genre()) == 1 + + def test_added_book_has_no_genre(self, collector): + collector.add_new_book('Том Сойер') + assert collector.get_book_genre('Том Сойер') == '' + + # Тесты работы с жанрами + def test_set_book_genre_valid(self, collector): + collector.add_new_book('Том Сойер') + collector.set_book_genre('Том Сойер', 'Фантастика') + assert collector.get_book_genre('Том Сойер') == 'Фантастика' + + def test_set_book_genre_invalid_genre(self, collector): + collector.add_new_book('Том Сойер') + collector.set_book_genre('Том Сойер', 'Фэнтези') + assert collector.get_book_genre('Том Сойер') == '' + + def test_set_book_genre_nonexistent_book(self, collector): + collector.set_book_genre('Несуществующая книга', 'Фантастика') + assert collector.get_book_genre('Несуществующая книга') is None + + # Тесты с подготовленными данными + def test_get_books_with_specific_genre(self, collector_with_books): + books = collector_with_books.get_books_with_specific_genre('Фантастика') + assert 'Книга 1' in books + assert len(books) == 1 + + def test_get_books_for_children(self, collector_with_books): + children_books = collector_with_books.get_books_for_children() + assert 'Книга 1' in children_books # "Фантастика" - детский жанр + assert 'Книга 2' in children_books # "Комедии" - детский жанр + assert len(children_books) == 2 + + # Тесты работы с избранным + def test_add_book_in_favorites(self, collector): + collector.add_new_book('Том Сойер') + collector.add_book_in_favorites('Том Сойер') + assert 'Том Сойер' in collector.get_list_of_favorites_books() + + def test_add_book_in_favorites_twice(self, collector): + collector.add_new_book('Том Сойер') + collector.add_book_in_favorites('Том Сойер') + collector.add_book_in_favorites('Том Сойер') + assert len(collector.get_list_of_favorites_books()) == 1 + + def test_delete_book_from_favorites(self, collector_with_books): + collector_with_books.delete_book_from_favorites("Книга 1") + assert "Книга 1" not in collector_with_books.get_list_of_favorites_books() + + def test_get_list_of_favorites_books(self, collector_with_books): + favorites = collector_with_books.get_list_of_favorites_books() + assert 'Книга 1' in favorites + assert len(favorites) == 1 \ No newline at end of file From 25acebd4fcae1ee10704f1d9ebaa5916217ba6e7 Mon Sep 17 00:00:00 2001 From: Aleksey Doludin Date: Fri, 4 Jul 2025 19:11:25 +0300 Subject: [PATCH 2/6] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20README,=20=D1=82=D0=B5=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B8=20gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++++ README.md | 31 ++++++++++++++++++++++++++++++- tests.py | 16 ++++------------ 3 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..767725b --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +*.log +*.cache +.coverage diff --git a/README.md b/README.md index 1cc701d..34a8e3e 100644 --- a/README.md +++ b/README.md @@ -1 +1,30 @@ -# qa_python \ No newline at end of file + +## Фикстуры +1. `collector` - чистый экземпляр BooksCollector +2. `collector_with_books` - подготовленный экземпляр с: + - 2 книгами разных жанров + - 1 книгой в избранном + +## Группы тестов + +### 1. Тесты добавления книг +- Добавление книги с валидным названием +- Попытка добавить книгу с слишком коротким названием +- Попытка добавить книгу с слишком длинным названием +- Попытка добавить дубликат книги +- Проверка, что у новой книги нет жанра + +### 2. Тесты работы с жанрами +- Установка валидного жанра +- Попытка установки недопустимого жанра +- Попытка установки жанра несуществующей книге + +### 3. Тесты с подготовленными данными +- Получение книг определенного жанра +- Получение книг для детей (проверка детских жанров) + +### 4. Тесты работы с избранным +- Добавление книги в избранное +- Попытка повторного добавления в избранное +- Удаление книги из избранного +- Получение списка избранных книг diff --git a/tests.py b/tests.py index 34f5e67..452c5c2 100644 --- a/tests.py +++ b/tests.py @@ -4,16 +4,12 @@ class TestBooksCollector: @pytest.fixture def collector(self): - """Фикстура для чистого коллектора книг""" return BooksCollector() @pytest.fixture def collector_with_books(self): - """Фикстура с подготовленными данными: - - 2 книги с разными жанрами - - 1 книга в избранном""" - collector = BooksCollector() # Создаем новый экземпляр - # Добавляем тестовые данные + + collector = BooksCollector() collector.add_new_book("Книга 1") collector.add_new_book("Книга 2") collector.set_book_genre("Книга 1", "Фантастика") @@ -21,7 +17,6 @@ def collector_with_books(self): collector.add_book_in_favorites("Книга 1") return collector - # Базовые тесты def test_add_new_book_valid_name(self, collector): collector.add_new_book('Том Сойер') assert 'Том Сойер' in collector.get_books_genre() @@ -44,7 +39,6 @@ def test_added_book_has_no_genre(self, collector): collector.add_new_book('Том Сойер') assert collector.get_book_genre('Том Сойер') == '' - # Тесты работы с жанрами def test_set_book_genre_valid(self, collector): collector.add_new_book('Том Сойер') collector.set_book_genre('Том Сойер', 'Фантастика') @@ -59,7 +53,6 @@ def test_set_book_genre_nonexistent_book(self, collector): collector.set_book_genre('Несуществующая книга', 'Фантастика') assert collector.get_book_genre('Несуществующая книга') is None - # Тесты с подготовленными данными def test_get_books_with_specific_genre(self, collector_with_books): books = collector_with_books.get_books_with_specific_genre('Фантастика') assert 'Книга 1' in books @@ -67,11 +60,10 @@ def test_get_books_with_specific_genre(self, collector_with_books): def test_get_books_for_children(self, collector_with_books): children_books = collector_with_books.get_books_for_children() - assert 'Книга 1' in children_books # "Фантастика" - детский жанр - assert 'Книга 2' in children_books # "Комедии" - детский жанр + assert 'Книга 1' in children_books + assert 'Книга 2' in children_books assert len(children_books) == 2 - # Тесты работы с избранным def test_add_book_in_favorites(self, collector): collector.add_new_book('Том Сойер') collector.add_book_in_favorites('Том Сойер') From 75c40a4329a28de3c3559498667b4bf46b369cc9 Mon Sep 17 00:00:00 2001 From: Aleksey Doludin Date: Fri, 4 Jul 2025 19:14:15 +0300 Subject: [PATCH 3/6] Cleanup: Remove cache and coverage files --- .coverage | Bin 53248 -> 0 bytes __pycache__/main.cpython-311.pyc | Bin 3691 -> 0 bytes __pycache__/main.cpython-38.pyc | Bin 2030 -> 0 bytes __pycache__/test.cpython-38-pytest-7.1.2.pyc | Bin 8183 -> 0 bytes __pycache__/tests.cpython-311-pytest-8.4.1.pyc | Bin 22381 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .coverage delete mode 100644 __pycache__/main.cpython-311.pyc delete mode 100644 __pycache__/main.cpython-38.pyc delete mode 100644 __pycache__/test.cpython-38-pytest-7.1.2.pyc delete mode 100644 __pycache__/tests.cpython-311-pytest-8.4.1.pyc diff --git a/.coverage b/.coverage deleted file mode 100644 index 32c3236720a1b99feb786c3f624dfeac217e5371..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 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 PGd99sX#0Dc20rn>tm9qm 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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 L`L7$~%6k1DGG#X1 From 13e92fc40c2be9ca35b9e989c9493858388a934a Mon Sep 17 00:00:00 2001 From: Aleksey Doludin Date: Fri, 4 Jul 2025 19:45:58 +0300 Subject: [PATCH 4/6] Reset git cache --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 767725b..e15006d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ __pycache__/ *.log *.cache .coverage +__pycache__/ +.coverage +htmlcov/ From 6c3dcfe00d111d8f54658b6dc3739fb01f8a9cd8 Mon Sep 17 00:00:00 2001 From: Aleksey Doludin Date: Fri, 4 Jul 2025 20:12:33 +0300 Subject: [PATCH 5/6] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20tests.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests.py b/tests.py index 452c5c2..8156543 100644 --- a/tests.py +++ b/tests.py @@ -4,6 +4,7 @@ class TestBooksCollector: @pytest.fixture def collector(self): + return BooksCollector() @pytest.fixture @@ -82,4 +83,4 @@ def test_delete_book_from_favorites(self, collector_with_books): def test_get_list_of_favorites_books(self, collector_with_books): favorites = collector_with_books.get_list_of_favorites_books() assert 'Книга 1' in favorites - assert len(favorites) == 1 \ No newline at end of file + assert len(favorites) == 1 From c373c67c998ce5b8e25314631970ccfebb36de58 Mon Sep 17 00:00:00 2001 From: Aleksey Doludin Date: Mon, 7 Jul 2025 13:44:08 +0300 Subject: [PATCH 6/6] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= =?UTF-8?q?,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20*=20get=5Fbook=5Fgenre=20=D0=B8=20=D0=B8=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B1=D0=BB=D1=8E=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8?= =?UTF-8?q?=D0=BD=D0=BA=D0=B0=D0=BF=D1=81=D1=83=D0=BB=D1=8F=D1=86=D0=B8?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tests.py b/tests.py index 8156543..ee26ee1 100644 --- a/tests.py +++ b/tests.py @@ -4,12 +4,10 @@ class TestBooksCollector: @pytest.fixture def collector(self): - return BooksCollector() @pytest.fixture def collector_with_books(self): - collector = BooksCollector() collector.add_new_book("Книга 1") collector.add_new_book("Книга 2") @@ -20,16 +18,16 @@ def collector_with_books(self): def test_add_new_book_valid_name(self, collector): collector.add_new_book('Том Сойер') - assert 'Том Сойер' in collector.get_books_genre() + assert collector.get_book_genre('Том Сойер') is not None def test_add_new_book_invalid_name_too_short(self, collector): collector.add_new_book('') - assert '' not in collector.get_books_genre() + assert collector.get_book_genre('') is None def test_add_new_book_invalid_name_too_long(self, collector): long_name = 'x' * 41 collector.add_new_book(long_name) - assert long_name not in collector.get_books_genre() + assert collector.get_book_genre(long_name) is None def test_add_new_book_duplicate(self, collector): collector.add_new_book('Том Сойер') @@ -54,15 +52,22 @@ def test_set_book_genre_nonexistent_book(self, collector): collector.set_book_genre('Несуществующая книга', 'Фантастика') assert collector.get_book_genre('Несуществующая книга') is None + def test_get_book_genre_for_book_with_genre(self, collector_with_books): + assert collector_with_books.get_book_genre("Книга 1") == "Фантастика" + + def test_get_book_genre_for_book_without_genre(self, collector): + collector.add_new_book("Книга без жанра") + assert collector.get_book_genre("Книга без жанра") == "" + def test_get_books_with_specific_genre(self, collector_with_books): books = collector_with_books.get_books_with_specific_genre('Фантастика') - assert 'Книга 1' in books + assert "Книга 1" in books assert len(books) == 1 def test_get_books_for_children(self, collector_with_books): children_books = collector_with_books.get_books_for_children() - assert 'Книга 1' in children_books - assert 'Книга 2' in children_books + assert "Книга 1" in children_books + assert "Книга 2" in children_books assert len(children_books) == 2 def test_add_book_in_favorites(self, collector): @@ -82,5 +87,5 @@ def test_delete_book_from_favorites(self, collector_with_books): def test_get_list_of_favorites_books(self, collector_with_books): favorites = collector_with_books.get_list_of_favorites_books() - assert 'Книга 1' in favorites - assert len(favorites) == 1 + assert "Книга 1" in favorites + assert len(favorites) == 1 \ No newline at end of file