From 2194a11eae7906dcee11d67e7586c07c75d5685e Mon Sep 17 00:00:00 2001 From: Anatoly <30874961+anatoly-kor@users.noreply.github.com> Date: Sat, 8 Oct 2022 20:03:10 +0300 Subject: [PATCH] update tests and flake8 (#40) --- .flake8 | 9 ++++ pytest.ini | 2 +- requirements.txt | 24 ++++----- tests/conftest.py | 4 ++ tests/test_homework.py | 110 +++++++++++++++++++++++++++++++---------- 5 files changed, 108 insertions(+), 41 deletions(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..d2ecd230d --- /dev/null +++ b/.flake8 @@ -0,0 +1,9 @@ +[flake8] +disable-noqa = True +ignore = W503 +filename = + ./homework.py +max-complexity = 10 +max-line-length = 79 +exclude = + tests diff --git a/pytest.ini b/pytest.ini index 400440cfe..ac1ea3c0a 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,5 @@ [pytest] norecursedirs = env/* -addopts = -vv -p no:cacheprovider --disable-warnings +addopts = --tb=short -rE -vv --disable-warnings -p no:cacheprovider testpaths = tests/ python_files = test_*.py diff --git a/requirements.txt b/requirements.txt index 9239a4a62..d2278193e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,12 @@ -attrs==21.2.0 -flake8==4.0.1 -importlib-metadata==4.8.1 +attrs==22.1.0 +flake8==5.0.4 iniconfig==1.1.1 -mccabe==0.6.1 -packaging==21.0 +mccabe==0.7.0 +packaging==21.3 pluggy==1.0.0 -py==1.10.0 -pycodestyle==2.8.0 -pyflakes==2.4.0 -pyparsing==2.4.7 -pytest==6.2.5 -pytest-tldr==0.2.4 -toml==0.10.2 -typing-extensions==3.10.0.2 -zipp==3.6.0 +py==1.11.0 +pycodestyle==2.9.1 +pyflakes==2.5.0 +pyparsing==3.0.9 +pytest==7.1.3 +tomli==2.0.1 diff --git a/tests/conftest.py b/tests/conftest.py index d14bf8847..c56a98c8d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,3 +25,7 @@ def __exit__(self, *args): self.extend(self._stringio.getvalue().splitlines()) del self._stringio sys.stdout = self._stdout + + +def pytest_make_parametrize_id(config, val): + return repr(val) diff --git a/tests/test_homework.py b/tests/test_homework.py index ba3afb85e..da295c2e8 100644 --- a/tests/test_homework.py +++ b/tests/test_homework.py @@ -21,10 +21,10 @@ def test_read_package(): 'входящего пакета - `read_package`' ) assert callable(homework.read_package), ( - 'Проверьте, что `read_package` - это функция.' + '`read_package` должна быть функцией.' ) assert isinstance(homework.read_package, types.FunctionType), ( - 'Проверьте, что `read_package` - это функция.' + '`read_package` должна быть функцией.' ) @@ -43,7 +43,7 @@ def test_read_package_return(input_data, expected): def test_InfoMessage(): assert inspect.isclass(homework.InfoMessage), ( - 'Проверьте, что `InfoMessage` - это класс.' + '`InfoMessage` должен быть классом.' ) info_message = homework.InfoMessage info_message_signature = inspect.signature(info_message) @@ -84,7 +84,7 @@ def test_InfoMessage_get_message(input_data, expected): 'Создайте метод `get_message` в классе `InfoMessage`.' ) assert callable(info_message.get_message), ( - 'Проверьте, что `get_message` в классе `InfoMessage` - это метод.' + '`get_message` в классе `InfoMessage` должен быть методом.' ) result = info_message.get_message() assert isinstance(result, str), ( @@ -104,8 +104,16 @@ def test_InfoMessage_get_message(input_data, expected): def test_Training(): assert inspect.isclass(homework.Training), ( - 'Проверьте, что `Training` - это класс.' + '`Training` должен быть классом.' ) + for attr, value in {'LEN_STEP': 0.65, 'M_IN_KM': 1000, 'MIN_IN_H': 60}.items(): + assert hasattr(homework.Training, attr), ( + f'У класса `Training` должен быть атрибут `{attr}`' + ) + assert getattr(homework.Training, attr) == value, ( + 'У класса `Training` должен быть ' + f'атрибут `{attr}` со значением `{value}`' + ) training = homework.Training training_signature = inspect.signature(training) training_signature_list = list(training_signature.parameters) @@ -165,8 +173,8 @@ def test_Training_get_mean_speed(input_data, expected): 'должен возвращать значение типа `float`' ) assert result == expected, ( - 'Проверьте формулу подсчёта средней скорости движения ' - 'в классе `Training`' + 'Проверьте формулу подсчета средней скорости движения ' + 'класса `Training`' ) @@ -181,7 +189,12 @@ def test_Training_get_spent_calories(input_data): 'Создайте метод `get_spent_calories` в классе `Training`.' ) assert callable(training.get_spent_calories), ( - 'Проверьте, что `get_spent_calories` - это функция.' + '`get_spent_calories` должна быть функцией.' + ) + assert training.get_spent_calories() is None, ( + 'Метод `get_spent_calories` класса `Training` не должен ' + 'высчитывать потреченные калории, так как для каждого типа ' + 'тренировки своя формула подсчета калорий.' ) @@ -208,11 +221,23 @@ def mock_get_spent_calories(): def test_Swimming(): assert hasattr(homework, 'Swimming'), 'Создайте класс `Swimming`' assert inspect.isclass(homework.Swimming), ( - 'Проверьте, что `Swimming` - это класс.' + '`Swimming` должен быть классом.' ) assert issubclass(homework.Swimming, homework.Training), ( 'Класс `Swimming` должен наследоваться от класса `Training`.' ) + for attr, value in { + 'LEN_STEP': 1.38, + 'CALORIES_MEAN_SPEED_SHIFT': 1.1, + 'CALORIES_WEIGHT_MULTIPLIER': 2, + }.items(): + assert hasattr(homework.Swimming, attr), ( + f'У класса `Swimming` должен быть атрибут `{attr}`' + ) + assert getattr(homework.Swimming, attr) == value, ( + 'У класса `Swimming` должен быть ' + f'атрибут `{attr}` со значением `{value}`' + ) swimming = homework.Swimming swimming_signature = inspect.signature(swimming) swimming_signature_list = list(swimming_signature.parameters) @@ -245,8 +270,8 @@ def test_Swimming_get_mean(input_data, expected): @pytest.mark.parametrize('input_data, expected', [ ([720, 1, 80, 25, 40], 336.0), - ([420, 4, 20, 42, 4], 45.68000000000001), - ([1206, 12, 6, 12, 6], 13.272000000000002), + ([420, 4, 20, 42, 4], 182.72000000000003), + ([1206, 12, 6, 12, 6], 159.264), ]) def test_Swimming_get_spent_calories(input_data, expected): swimming = homework.Swimming(*input_data) @@ -262,11 +287,24 @@ def test_Swimming_get_spent_calories(input_data, expected): def test_SportsWalking(): assert hasattr(homework, 'SportsWalking'), 'Создайте класс `SportsWalking`' assert inspect.isclass(homework.SportsWalking), ( - 'Проверьте, что `SportsWalking` - это класс.' + '`SportsWalking` должен быть классом.' ) assert issubclass(homework.SportsWalking, homework.Training), ( 'Класс `SportsWalking` должен наследоваться от класса `Training`.' ) + for attr, value in { + 'CALORIES_WEIGHT_MULTIPLIER': 0.035, + 'CALORIES_SPEED_HEIGHT_MULTIPLIER': 0.029, + 'KMH_IN_MSEC': 0.278, + 'CM_IN_M': 100 + }.items(): + assert hasattr(homework.SportsWalking, attr), ( + f'У класса `SportsWalking` должен быть атрибут `{attr}`' + ) + assert getattr(homework.SportsWalking, attr) == value, ( + 'У класса `SportsWalking` должен быть ' + f'атрибут `{attr}` со значением `{value}`' + ) sports_walking = homework.SportsWalking sports_walking_signature = inspect.signature(sports_walking) sports_walking_signature_list = list(sports_walking_signature.parameters) @@ -278,9 +316,9 @@ def test_SportsWalking(): @pytest.mark.parametrize('input_data, expected', [ - ([9000, 1, 75, 180], 157.50000000000003), - ([420, 4, 20, 42], 168.00000000000003), - ([1206, 12, 6, 12], 151.20000000000002), + ([9000, 1, 75, 180], 349.2517475250001), + ([420, 4, 20, 42], 168.11931219846002), + ([1206, 12, 6, 12], 151.54430943785593), ]) def test_SportsWalking_get_spent_calories(input_data, expected): sports_walking = homework.SportsWalking(*input_data) @@ -296,18 +334,24 @@ def test_SportsWalking_get_spent_calories(input_data, expected): def test_Running(): assert hasattr(homework, 'Running'), 'Создайте класс `Running`' - assert inspect.isclass(homework.Running), ( - 'Проверьте, что `Running` - это класс.' - ) + assert inspect.isclass(homework.Running), '`Running` должен быть классом.' assert issubclass(homework.Running, homework.Training), ( 'Класс `Running` должен наследоваться от класса `Training`.' ) + for attr, value in {'CALORIES_MEAN_SPEED_MULTIPLIER': 18, 'CALORIES_MEAN_SPEED_SHIFT': 1.79}.items(): + assert hasattr(homework.Running, attr), ( + f'У класса `Running` должен быть атрибут `{attr}`' + ) + assert getattr(homework.Running, attr) == value, ( + 'У класса `Running` должен быть ' + f'атрибут `{attr}` со значением `{value}`' + ) @pytest.mark.parametrize('input_data, expected', [ - ([9000, 1, 75], 383.85), - ([420, 4, 20], -90.1032), - ([1206, 12, 6], -81.32032799999999), + ([9000, 1, 75], 481.90500000000003), + ([420, 4, 20], 14.488800000000001), + ([1206, 12, 6], 12.812472), ]) def test_Running_get_spent_calories(input_data, expected): running = homework.Running(*input_data) @@ -327,9 +371,9 @@ def test_main(): assert hasattr(homework, 'main'), ( 'Создайте главную функцию программы с именем `main`.' ) - assert callable(homework.main), 'Проверьте, что `main` - это функция.' + assert callable(homework.main), '`main` должна быть функцией.' assert isinstance(homework.main, types.FunctionType), ( - 'Проверьте, что `main` - это функция.' + '`main` должна быть функцией.' ) @@ -346,15 +390,29 @@ def test_main(): 'Длительность: 12.000 ч.; ' 'Дистанция: 0.784 км; ' 'Ср. скорость: 0.065 км/ч; ' - 'Потрачено ккал: -81.320.' + 'Потрачено ккал: 12.812.' ]), (['WLK', [9000, 1, 75, 180]], [ 'Тип тренировки: SportsWalking; ' 'Длительность: 1.000 ч.; ' 'Дистанция: 5.850 км; ' 'Ср. скорость: 5.850 км/ч; ' - 'Потрачено ккал: 157.500.' - ]) + 'Потрачено ккал: 349.252.' + ]), + (['WLK', [9000, 1.5, 75, 180]], [ + 'Тип тренировки: SportsWalking; ' + 'Длительность: 1.500 ч.; ' + 'Дистанция: 5.850 км; ' + 'Ср. скорость: 3.900 км/ч; ' + 'Потрачено ккал: 364.084.' + ]), + (['WLK', [3000.33, 2.512, 75.8, 180.1]], [ + 'Тип тренировки: SportsWalking; ' + 'Длительность: 2.512 ч.; ' + 'Дистанция: 1.950 км; ' + 'Ср. скорость: 0.776 км/ч; ' + 'Потрачено ккал: 408.429.' + ]), ]) def test_main_output(input_data, expected): with Capturing() as get_message_output: