Skip to content

level_4 tests#5

Open
uraniumcore238 wants to merge 2 commits intomainfrom
level_4
Open

level_4 tests#5
uraniumcore238 wants to merge 2 commits intomainfrom
level_4

Conversation

@uraniumcore238
Copy link
Copy Markdown
Owner

No description provided.

Copy link
Copy Markdown

@vppuzakov vppuzakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 тесты хорошие, вмерживай
💡 погляди комменты и как будет время - поправь

Comment thread tests/level_4/conftest.py
import pytest


@pytest.fixture
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 хорошая фикстура для интеграционного теста, например, где нам нужно создать файл и подчистить за собой после теста

💡 но в рамках юнит-тестирования, на не нужно создавать реальные файлы - достаточно замокать методы, которые пытаются обращаться к файлам и возвращать контент.

💡 если нужно мокать непосредственно операции с файлом - есть mock_open:

from unittest.mock import patch, mock_open
with patch("builtins.open", mock_open(read_data="data")) as mock_file:
    assert open("path/to/open").read() == "data"
mock_file.assert_called_with("path/to/open")


@pytest.mark.parametrize('value', ['value1', '[tool:app-config]', 'field'])
def test__five_extra_fields__return_none_if_the_str_is_not_in_config_fields(file_path, value):
assert fetch_app_config_field(file_path, value) is None
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 в данной функции нам достаточно даже не мокировать файл, а замокировать вызовы методов ConfigParser, эти методы (read, __getitem__ - обращение по ключу):

config = configparser.ConfigParser()
config.read(config_file_path)
config["tool:app-config"][field_name]



@pytest.mark.parametrize('value', ['value1', '[tool:app-config]', 'field'])
def test__five_extra_fields__return_none_if_the_str_is_not_in_config_fields(file_path, value):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 отличное название теста, такие параметры здесь очень уместны
❗ опять поспешил похвалить название - в названии надо указать название тестируемой функции, а не модуля - сам тестируемый модуль у нас в названии модуля теста отражен.

assert fetch_app_config_field(file_path, value) is None


def test__five_extra_fields__return_value_if_the_str_is_in_config_fields(file_path):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 этот и тесты ниже отличные
💡 правда, они используют внутри себя знания о содержимом фикстур, что делает тест менее очевидным - но если сделать из этих фикстур, фикстуры-фабрики - тесты удастся сделать более явными.

from functions.level_4.four_lines_counter import count_lines_in


def test__four_line_counter__return_lines_quantity_in_the_file(file_path):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 отличные тесты, кейсы и название

❗ хотя поспешил с названием, в названии надо отражать не название модуля - а название тестируемой функции

💡 фикстура-фабрика помогла бы сделать их более явными - мы бы видели кол-во передаваемых строк при создании файла или даже можно было бы сделать фикстуру, которая на вход принимает число создаваемых строк, вроде make_lines(count=3) и ее уже передать в мок-фикстуру на чтение файла (использовать mock_open)

def test__three_promocodes__return_promo_code_with_passed_len(code_length):
code = generate_promocode(code_length)
assert len(code) == code_length
assert isinstance(code, str) is True
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗ не проверяем в тестах на тип возвращаемого значения - для этого работает mypy

def test__three_promocodes__return_promo_code_if_no_len_passed():
code = generate_promocode()
assert len(code) == 8
assert isinstance(code, str) is True
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗ надо убрать из теста проверку на тип проверяемого значения

@@ -0,0 +1,17 @@
import pytest
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗ тут крайне здорово потестить на возвращаемые контент (что он рандомный, например) с использованием мока на функцию random - давай попробуем сделать

from functions.level_4.two_students import get_student_by_tg_nickname, Student


def test__two_students__return_none_if_username_is_not_the_same_as_tg_account():
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❗ в названии обязательно используй тестируемую функцию, а не модуль



def test__two_students__return_none_if_username_is_not_the_same_as_tg_account():
student = Student(first_name='Vasya', last_name='Osipov', telegram_account='@pacman')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 более понятным тест нам помогла бы сделать фикстура-фабрика:

student = make_student(telegram_account="@pacman")

Подчеркивая, что имя и фамилия не важны, важно лишь расхождение аккаунта

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants