Как проверить, что функция корректно возвращает 0 или 1 в зависимости от условий
Что проверяют
Умеете ли вы превратить условие в набор тестовых случаев: классы эквивалентности, границы, некорректный ввод. Следом часто просят переписать тесты на pytest с параметризацией или спрашивают, что будет, если функция вернёт True вместо 1.
Как отвечать
Начните с контракта: какие входы допустимы, что возвращается ровно на границе, что должно происходить при None или строке. Без этого тестировать нечего.
Затем разбейте вход на классы и возьмите по значению из каждого плюс границы. Для условия value > 0 это -1, 0, 1 и большое число, для float ещё 0.0, -0.0 и 1e-9. Компактнее всего через параметризацию:
@pytest.mark.parametrize("value, expected", [(-1, 0), (0, 0), (1, 1), (10**9, 1)])
def test_check(value, expected):
assert check(value) == expectedНекорректный ввод проверяется отдельно через pytest.raises(TypeError), если контракт этого требует.
Что стоит проговорить:
- тип результата:
True == 1в Python истинно, потому чтоboolнаследуется отint. Если нужен именноint, добавьтеassert type(result) is int; - float около нуля:
0.1 + 0.2 - 0.3не равно нулю, и функция на таком входе вернёт 1, хотя «по смыслу» ожидали 0; - покрытие ветвей:
pytest --cov --cov-branchизpytest-covпокажет, что выполнились обе ветки; - составные условия: при нескольких
and/orперебирайте комбинации, а на большом пространстве входов подключайтеhypothesisи проверяйте свойство «результат всегда 0 или 1».
Где спотыкаются
Пишут один тест на ветку и не трогают границу. Ошибку >= вместо > ловит только значение ровно 0.
Проверяют через assert check(x) вместо assert check(x) == 1. Такой тест пройдёт и на 2, и на непустой строке.
Оставляют print рядом с функцией вместо assert. Печать ничего не проверяет, в CI такая «проверка» всегда зелёная.