Предизвикателства > Валидатор за Никулденска рецепта > Решения > Решението на Ева Ганчева

Резултати
1 точки от тестове
1 точки от учител

2 точки общо

4 успешни теста
0 неуспешни теста
Код

 1import unittest
 2from unittest.mock import mock_open, patch
 3
 4from secret import validate_recipe, RuinedNikuldenDinnerError
 5
 6
 7class TestNikuldenValidator(unittest.TestCase):
 8    def test_valid_recipe(self):
 9        valid_cases = [
10            "Тази рецепта съдържа риба.",
11            "Запечете рибена глава.",
12            "На Никулден се приготвя шаран..",
13            "Сьонга е за печене.",
14            "РИБА на фурна.",
15            "арфтцрь56всра%€§$%§ риба.",
16            "РиБа с ориз."
17        ]
18        for content in valid_cases:
19            with patch("builtins.open", mock_open(read_data=content)):
20                self.assertTrue(validate_recipe("valid_recipe.txt"))
21
22    def test_invalid_recipe(self):
23        invalid_cases = [
24            "Днес ще готвим пилешко.",
25            " Днес има ориз.",
26            "Само зеленчуци ириба.",
27            "рибено масло и картофи.",
28            "€§*€%§*(()",
29            ""
30        ]
31        for content in invalid_cases:
32            with patch("builtins.open", mock_open(read_data=content)):
33                self.assertFalse(validate_recipe("invalid_recipe.txt"))
34
35    def test_bad_recipe_file(self):
36        with patch("builtins.open", side_effect=OSError):
37            with self.assertRaises(RuinedNikuldenDinnerError):
38                validate_recipe("bad_recipe.txt")
39
40
41if __name__ == "__main__":
42    unittest.main()

....
----------------------------------------------------------------------
Ran 4 tests in 0.074s

OK

Дискусия
Виктор Бечев
07.12.2024 12:57

Можеш да напишеш нещо сравнително кратко, което да ти прави въпросните пермутации, но истината е, че не е нужно. Алтернативен пример - ако имаме функция, която повдига четни числа на втора степен, нечетни - на трета и работи в отворен интервал от 0 до 100. Имаме да тестване за: 1. Четно число. 2. Нечетно число. 3. Гранични стойности - 0 и 100. Не е нужно да тестваме с 2, 4, 6, 8 и т.н., достатъчно е да тестваме с едно четно число. Същото важи и за нечетните. Не е нужно да тестваме и за -5 и -500, достатъчно е да изтестваме поведението в граничните стойности - 0 и 100. Философията тук е, че да, винаги можеш да напишеш функция, която се чупи точно на 87. Но идеята не е да тестваме функциите, които пишем с всеки възможен input, а да генерализираме тестовете си спрямо изискванията, така че да могат да ни дадат достатъчно добра увереност, че функцията изпълнява дефинираните изисквания. Защото този проблем, който дефинирах е с елементарна сложност, но ако функцията ти е по-сложна или дори със същата сложност, но има граници от -сто милиона до +сто милиона - ще тестваш ли 200 000 002 пъти? Пък и да не забравяме невалидните стойности - те са безкрайно множество. Така че - тестовете ти са чудесни, хванала си дори и случая `"Само зеленчуци ириба."`. Повече от това не е необходимо.
Ева Ганчева
06.12.2024 14:08

Исках да попитам също дали има по-умен начин да се направят тестовете, така че да тестват повече функционалности, например предполагам може с f string и вътре да има ключовите думи, но как мога да генерирам всички разновидности на риба - тоест рИба, риБа .... Просто се чудех дали има функция, която го прави
История

f1import unittestf1import unittest
2from unittest.mock import mock_open, patch2from unittest.mock import mock_open, patch
33
4from secret import validate_recipe, RuinedNikuldenDinnerError4from secret import validate_recipe, RuinedNikuldenDinnerError
55
66
7class TestNikuldenValidator(unittest.TestCase):7class TestNikuldenValidator(unittest.TestCase):
8    def test_valid_recipe(self):8    def test_valid_recipe(self):
9        valid_cases = [9        valid_cases = [
10            "Тази рецепта съдържа риба.",10            "Тази рецепта съдържа риба.",
11            "Запечете рибена глава.",11            "Запечете рибена глава.",
12            "На Никулден се приготвя шаран..",12            "На Никулден се приготвя шаран..",
13            "Сьонга е за печене.",13            "Сьонга е за печене.",
14            "РИБА на фурна.",14            "РИБА на фурна.",
15            "арфтцрь56всра%€§$%§ риба.",15            "арфтцрь56всра%€§$%§ риба.",
16            "РиБа с ориз."16            "РиБа с ориз."
17        ]17        ]
18        for content in valid_cases:18        for content in valid_cases:
19            with patch("builtins.open", mock_open(read_data=content)):19            with patch("builtins.open", mock_open(read_data=content)):
20                self.assertTrue(validate_recipe("valid_recipe.txt"))20                self.assertTrue(validate_recipe("valid_recipe.txt"))
2121
22    def test_invalid_recipe(self):22    def test_invalid_recipe(self):
23        invalid_cases = [23        invalid_cases = [
24            "Днес ще готвим пилешко.",24            "Днес ще готвим пилешко.",
25            " Днес има ориз.",25            " Днес има ориз.",
t26            "Само зеленчуци и риба.",t26            "Само зеленчуци ириба.",
27            "рибено масло и картофи.",27            "рибено масло и картофи.",
28            "€§*€%§*(()",28            "€§*€%§*(()",
29            ""29            ""
30        ]30        ]
31        for content in invalid_cases:31        for content in invalid_cases:
32            with patch("builtins.open", mock_open(read_data=content)):32            with patch("builtins.open", mock_open(read_data=content)):
33                self.assertFalse(validate_recipe("invalid_recipe.txt"))33                self.assertFalse(validate_recipe("invalid_recipe.txt"))
3434
35    def test_bad_recipe_file(self):35    def test_bad_recipe_file(self):
36        with patch("builtins.open", side_effect=OSError):36        with patch("builtins.open", side_effect=OSError):
37            with self.assertRaises(RuinedNikuldenDinnerError):37            with self.assertRaises(RuinedNikuldenDinnerError):
38                validate_recipe("bad_recipe.txt")38                validate_recipe("bad_recipe.txt")
3939
4040
41if __name__ == "__main__":41if __name__ == "__main__":
42    unittest.main()42    unittest.main()
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import unittestf1import unittest
2from unittest.mock import mock_open, patch2from unittest.mock import mock_open, patch
33
4from secret import validate_recipe, RuinedNikuldenDinnerError4from secret import validate_recipe, RuinedNikuldenDinnerError
55
66
7class TestNikuldenValidator(unittest.TestCase):7class TestNikuldenValidator(unittest.TestCase):
8    def test_valid_recipe(self):8    def test_valid_recipe(self):
9        valid_cases = [9        valid_cases = [
10            "Тази рецепта съдържа риба.",10            "Тази рецепта съдържа риба.",
11            "Запечете рибена глава.",11            "Запечете рибена глава.",
n12            "На Никулден се приготвя шаран.",n12            "На Никулден се приготвя шаран..",
13            "Сьонга е за печене.",13            "Сьонга е за печене.",
14            "РИБА на фурна.",14            "РИБА на фурна.",
15            "арфтцрь56всра%€§$%§ риба.",15            "арфтцрь56всра%€§$%§ риба.",
16            "РиБа с ориз."16            "РиБа с ориз."
17        ]17        ]
18        for content in valid_cases:18        for content in valid_cases:
19            with patch("builtins.open", mock_open(read_data=content)):19            with patch("builtins.open", mock_open(read_data=content)):
20                self.assertTrue(validate_recipe("valid_recipe.txt"))20                self.assertTrue(validate_recipe("valid_recipe.txt"))
2121
22    def test_invalid_recipe(self):22    def test_invalid_recipe(self):
23        invalid_cases = [23        invalid_cases = [
n24            "Днес ще готвим пилешко месо.",n24            "Днес ще готвим пилешко.",
25            " Днес има ориз.",
25            "Само зеленчуци ириба.",26            "Само зеленчуци и риба.",
26            "рибено масло и картофи.",27            "рибено масло и картофи.",
t27            "!@#$%^&*()",t28            "€§*€%§*(()",
28            ""29            ""
29        ]30        ]
30        for content in invalid_cases:31        for content in invalid_cases:
31            with patch("builtins.open", mock_open(read_data=content)):32            with patch("builtins.open", mock_open(read_data=content)):
32                self.assertFalse(validate_recipe("invalid_recipe.txt"))33                self.assertFalse(validate_recipe("invalid_recipe.txt"))
3334
34    def test_bad_recipe_file(self):35    def test_bad_recipe_file(self):
35        with patch("builtins.open", side_effect=OSError):36        with patch("builtins.open", side_effect=OSError):
36            with self.assertRaises(RuinedNikuldenDinnerError):37            with self.assertRaises(RuinedNikuldenDinnerError):
37                validate_recipe("bad_recipe.txt")38                validate_recipe("bad_recipe.txt")
3839
3940
40if __name__ == "__main__":41if __name__ == "__main__":
41    unittest.main()42    unittest.main()
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import unittestf1import unittest
2from unittest.mock import mock_open, patch2from unittest.mock import mock_open, patch
nn3 
3from secret import validate_recipe, RuinedNikuldenDinnerError4from secret import validate_recipe, RuinedNikuldenDinnerError
nn5 
46
5class TestNikuldenValidator(unittest.TestCase):7class TestNikuldenValidator(unittest.TestCase):
6    def test_valid_recipe(self):8    def test_valid_recipe(self):
7        valid_cases = [9        valid_cases = [
8            "Тази рецепта съдържа риба.",10            "Тази рецепта съдържа риба.",
9            "Запечете рибена глава.",11            "Запечете рибена глава.",
10            "На Никулден се приготвя шаран.",12            "На Никулден се приготвя шаран.",
11            "Сьонга е за печене.",13            "Сьонга е за печене.",
12            "РИБА на фурна.",14            "РИБА на фурна.",
13            "арфтцрь56всра%€§$%§ риба.",15            "арфтцрь56всра%€§$%§ риба.",
14            "РиБа с ориз."16            "РиБа с ориз."
15        ]17        ]
16        for content in valid_cases:18        for content in valid_cases:
17            with patch("builtins.open", mock_open(read_data=content)):19            with patch("builtins.open", mock_open(read_data=content)):
18                self.assertTrue(validate_recipe("valid_recipe.txt"))20                self.assertTrue(validate_recipe("valid_recipe.txt"))
nn21 
19    def test_invalid_recipe(self):22    def test_invalid_recipe(self):
20        invalid_cases = [23        invalid_cases = [
21            "Днес ще готвим пилешко месо.",24            "Днес ще готвим пилешко месо.",
22            "Само зеленчуци ириба.",25            "Само зеленчуци ириба.",
23            "рибено масло и картофи.",26            "рибено масло и картофи.",
24            "!@#$%^&*()",27            "!@#$%^&*()",
25            ""28            ""
26        ]29        ]
27        for content in invalid_cases:30        for content in invalid_cases:
28            with patch("builtins.open", mock_open(read_data=content)):31            with patch("builtins.open", mock_open(read_data=content)):
29                self.assertFalse(validate_recipe("invalid_recipe.txt"))32                self.assertFalse(validate_recipe("invalid_recipe.txt"))
nn33 
30    def test_bad_recipe_file(self):34    def test_bad_recipe_file(self):
31        with patch("builtins.open", side_effect=OSError):35        with patch("builtins.open", side_effect=OSError):
32            with self.assertRaises(RuinedNikuldenDinnerError):36            with self.assertRaises(RuinedNikuldenDinnerError):
33                validate_recipe("bad_recipe.txt")37                validate_recipe("bad_recipe.txt")
3438
tt39 
35if __name__ == "__main__":40if __name__ == "__main__":
36    unittest.main()41    unittest.main()
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op