Как проверить корректную работу калькулятора с дробными числами
Что проверяют
Знаете ли вы, почему дробные числа ломаются в компьютере, и умеете ли превратить это в тест-кейсы, а не ограничиться «проверю 1,5 плюс 1,5». Следом обычно просят объяснить, почему 0,1 + 0,2 где-то даёт 0,30000000000000004.
Как отвечать
Начните с требований, без них ожидаемый результат не определить: сколько знаков после запятой показывать, как округлять (математически или банковским способом), сколько цифр влезает на экран, когда переходить в экспоненциальную запись.
Дальше классы проверок:
- двоичная точность: большинство языков хранит дроби в формате IEEE 754, где 0,1 точно не представимо.
0.1 + 0.2в double даёт0.30000000000000004, а калькулятор обязан показать0,3. Сюда же 1,1 × 3 и 0,3 минус 0,1; - округление: 1,005 до двух знаков. В двоичном виде это 1,00499999..., поэтому наивное округление даёт 1,00 вместо 1,01: в JavaScript
(1.005).toFixed(2)возвращает"1.00"; - периодические дроби: 1 ÷ 3 × 3 должно дать 1, а не 0,9999999;
- разделитель: в русской локали запятая; ввод с точкой и с запятой, два разделителя подряд, ввод с разделителя (
,5), лишние нули в конце; - границы: очень маленькие и очень большие числа, переполнение экрана, деление на ноль, отрицательные дроби, смена знака.
Кейсы стройте через классы эквивалентности и граничные значения. Эталон считайте не той же арифметикой, что в приложении: удобно взять Python decimal.Decimal или fractions.Fraction.
Основную массу проверок уводите в параметризованные юнит-тесты движка вычислений (@pytest.mark.parametrize, @ParameterizedTest в JUnit 5), а через UI гоняйте несколько сквозных сценариев.
Где спотыкаются
Сравнивают дробные результаты в автотесте через ==. Для внутренних вычислений нужна погрешность (pytest.approx, assertEquals с delta), а для экрана калькулятора точная строка.
Не уточняют правила округления и спорят с разработчиком о баге, который на деле был трактовкой требований.
Проверяют только операции и забывают про ввод: запятую, вставку из буфера, стирание последнего символа после разделителя.