level 2#2
Conversation
There was a problem hiding this comment.
👍 тесты отличные, кейсы хорошие. Вмерживай.
💡 далее по комментам давай поработаем и разделим некоторые тесты по раздельным тесткейсам - чтобы ты мог каждому этому тесту дать такое название - по которому не глядя в тело теста и параметры (только глядя в аутпут при запуске теста) будет понятно, что этот тест по факту тестируем (заметь - нам не важно как тестирует - нам важно что)
- тестирую что функция деления при делении на ноль вернет ошибку
- тестирую что уровнение находит два разных корня
- тестирую что уровнение не может найти корни когда оба коэффициента нули
итд
ПС: сорри за долгий отклик, далее буду стараться держать SLA
| return ' '.join(new_words) | ||
|
|
||
|
|
||
| print(replace_word('replace', 'replace', 'htllo')) No newline at end of file |
There was a problem hiding this comment.
❗ print - выпиливай
💡 смотри какой пайплайн норм вместо принтов, чтобы узнать а как же работает функция:
# если функция возвращает строку
def test__somefunc__smoke():
assert somefunc() == ''и запустив это с флагом -vv и установленным для удобства pytest-clarity ты увидешь четкий дифф и значение которое возвращает эта функция и уже в готовом тесте. Дальше остается только понять что уже ты хочешь потестить, написать тест и какое название дать этому тесту.
| from functions.level_2.four_sentiment import check_tweet_sentiment | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(('text', 'result'), [ |
There was a problem hiding this comment.
👍 круто, что попробовал задействовать тут parametrize.
💡 в данном варианте у нас несколько тест кейсов спрятались в один тест - это не здорово. Давай разделим их по кейсам (и для некоторых вполне можно оставить параметрайз):
- return_good
- return_bad
- return_none_on_good_and_bad_equal
- return_none_on_if_no_good_or_bad_verbs_in_text
Так станет понятнее, почему именно такая комбинация параметров дает именно такой результат - не ошибка ли это и тд. Потому что зафиксирован контракт функции словами в ее названии.
💡 а что, если наш словарь плохих и хороших слов пустой?
| from functions.level_2.one_pr_url import is_github_pull_request_url | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(('url', 'result'), [ |
There was a problem hiding this comment.
💡 тоже давай разобьем этот параметрайз на несколько тестов в соответствии с их кейсами - не забывай в названии отразить какой именно кейс тестируем. Некоторые параметры возможно сохранятся - зависит от того какие кейсы ты выделишь.
Помни, всегда название теста должно читаться как осмысленное законченное предложение и выглядеть так test__funcname__do_something_when_something
There was a problem hiding this comment.
💡 название теста должно повторять структуру модулей - test_five_replace_word.py
| ('one', 'one'), | ||
| ('seven', 'one') | ||
| ]) | ||
| def test_five_replace_word_no_replacement(replace_from, replace_to): |
There was a problem hiding this comment.
💡 название теста обязательно пиши по шаблону: test__funcname__do_something_when_something, обрати внимание на двойное подчеркивание
💡 обязательно нужно добавить ожидаемое действие - тут видно только что по факту нет соответствия - ок, но что в таком случае функция должна сделать? - это приходится понимать только глядя уже в тело теста. Тут нужно добавить - test__five_replace_word__do_not_replace_words_if_no_words_for_replace_found
не бойся длинных названий тестов, главное, чтобы они были осмысленными - описывали часть контракта функции.
| ('one', 'seven'), | ||
| ('one', 'two') | ||
| ]) | ||
| def test_five_replace_word_with_replacement(replace_from, replace_to): |
There was a problem hiding this comment.
👍 вот тут параметры зашли вполне неплохо
💡 сложно интерпретировать такой тест из-за сложной логике в теле ради использования параметров. Смотри че можно придумать:
- использовать тупо expected - это будет в данном случае куда читаемей и вполне уместно тут
# все в параметры
assert replace_word(text, replace_from, replace_to) == expected- использовать переменные поактивнее:
replaced_word = "one"
other = "some text here" # or use faker.words
assert replace_word(f"{replaced_word} {other}") == f"{replaced_word} {other}"- но есть самый лучший вариант - сузить тесткейсы:
def test__replace_word__replace_one_word():
assert replace_word("one two three four", "one", "seven") == "seven two three four"
def test__replace_word__replace_many_words():
assert replace_word("one two one four", "one", "seven") == "seven two seven four" Эти тесты весьма понятные, потому что максимально явные.
💡 докинь еще кейсов на тему совпадения строк по ignorecase или нет - тоже вполне себе контракт на функцию - надо зафиксировать в тесте.
| assert first(items, default) == result | ||
|
|
||
|
|
||
| def test_with_attribute_error(): |
There was a problem hiding this comment.
👍 хороший кейс
💡 добавь имя тестируемой функции по шаблону, а заодно надо дописать причину почему она райзит эту ошибку test__somefunc__do_something_when_something
| from functions.level_2.three_first import first | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(('items', 'default', 'result'), [ |
There was a problem hiding this comment.
👍 ну как будто все тест-кейсы отличные
💡 станет куда понятнее, если все таки раскидаешь параметры по разным кейсам - параметры используем, когда хотим проверить один кейс на разных входах:
@parametrize(...)
def test__add__correctly_sum_two_numbers(a, b, expected):
assert a + b == expected
@parametrize(('number'), [10, 20, 0, 1000, -100, 100.500])
def test__division__raise_zero_division_error(number):
with pytest.raises(...):
divide(number, 0)| (0.0, 0.1, -0.1, (1.0, None)), | ||
| (0.0, -0.1, -0.1, (-1.0, None)) | ||
| ]) | ||
| def test_two_square_zero_data(square_coeff, linear_coeff, const_coeff, result): |
There was a problem hiding this comment.
💡 кейсы точно стоит разделить - я даже не сразу понял о какой zero_data - речь. Каждый коэффициент может быть 0 - это все разные тест кейсы. И обязательно ожидаемое поведение - вообще если видишь, что в тесте нет или не можешь дать ожидаемое поведение в названии - что-то с тестом не так. Надо сужать кейсы.
test__solve_square_equation__no_roots_found_for_zero_ab_coeffstest__solve_square_equation__found_one_root_if_only_a_coeff_is_zero
Давай разобьем.
❗ обязательно название функции в тест, а не модуль
| (-0.1, 0.1, -0.9, (None, None)), | ||
| (-0.1, -0.1, -0.1, (None, None)) | ||
| ]) | ||
| def test_two_square_some_equal_coefficients(square_coeff, linear_coeff, const_coeff, result): |
There was a problem hiding this comment.
💡 не так важны входы в кейсе, как то что ты от него ожидаешь. Вот тут ожидаемый результат разный - где-то корень будет найден, где-то нет. Это разные кейсы скорее всего - либо это просто стандартная история при решении уровнения и явно конкретизировать одинаковость коэффициентов не имеет смысла. В этих параметрах я вижу два кейса:
- кейс когда корни остутствуют
- кейс когда корни найдены (а это отлично объединяется со следующим кейсом)
No description provided.