В чем разница между операторами сравнения и когда какой использовать
Что проверяют
Знаете ли вы, как работает сравнение в языке ваших автотестов, и отличаете ли равенство значений от равенства ссылок. Следом обычно идёт практический вопрос: какую проверку взять в ассерте и почему тест с неверным оператором может остаться зелёным на баге.
Как отвечать
Начните с языка, на котором пишете тесты, и назовите его ловушки:
- JavaScript/TypeScript:
==приводит типы (5 == '5'даётtrue),===сравнивает без приведения, в тестах используют только его. Объекты сравниваются по ссылке, поэтому в Jest и PlaywrighttoBeпроверяет идентичность черезObject.is, а содержимое сравниваетtoEqual; - Java:
==у объектов сравнивает ссылки, содержимое сравниваетequals(). В AssertJ этому соответствуютisSameAsиisEqualTo; - Python:
==про значение,isпро тот же объект.isуместен дляNone, для строк и чисел результат зависит от кэширования интерпретатора; - Go: неявного приведения нет, сравнить
intсоstringне даст компилятор. Слайсы и мапы через==не сравниваются, для нихreflect.DeepEqualилиassert.Equalиз testify.
Отдельно скажите про >, >=, <, <= с точки зрения тест-дизайна. Требование «скидка от 1000 рублей» в коде легко становится > 1000 вместо >= 1000. Поэтому границу проверяют значениями 999, 1000 и 1001: ошибки на единицу живут именно там.
Где спотыкаются
Переносят логику JavaScript на все языки и говорят про === в Java или Python, где такого оператора нет.
Сравнивают объекты через toBe или assertSame и получают падение на одинаковых данных. Или наоборот, проверяют ссылку там, где нужно сравнить содержимое ответа API.
Забывают про особые значения: NaN не равен сам себе, а дробные числа нельзя сравнивать строго, 0.1 + 0.2 не равно 0.3. Для них нужны допуски, например toBeCloseTo в Jest или isCloseTo в AssertJ.