Примеры сравнения чисел с плавающей точкой в pytest
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Простейшим способом утверждения приближенного равенства чисел с плавающей точкой в pytest служит функция pytest.approx()
.
Пример:
assert 0.1 * 3 == pytest.approx(0.3)
Также возможно отрегулировать уровень точности через параметры abs
или rel
.
Пример с настройкой точности:
assert 0.1 * 3 == pytest.approx(0.3, abs=1e-12)
В дальнейшем углубимся в более сложные случаи и обсудим другие доступные для этого инструменты.
Первый уровень сложности: pytest для сложных задоч
Задачи могут быть гораздо сложнее, чем кажется на первый взгляд.
Сравнение переполненных кортежей
Сравнивая кортежи или списки чисел с плавающей точкой, можно избежать утомительного перебора каждого из элементов, используя следующий эффективный подход с map
и all
.
assert all(map(lambda x, y: abs(x – y) < threshold, tuple1, tuple2))
# Здесь надо быть бездушным — всё или ничего
Указанный код последовательно сравнивает элементы кортежей, обеспечивая ясность и эффективность тестов.
Альтернативы с NumPy и Unittest
Если вы предпочитаете работать с библиотеками NumPy или unittest, именно они предлагают отличные способы для утверждения приближенного равенства чисел с плавающей точкой.
NumPy's assert_allclose
:
import numpy as np
np.testing.assert_allclose(actual_array, expected_array, rtol=1e-5)
# Отлично подходит не только для задач с числами с плавающей точкой, но и для метания подков.
Unittest's assertAlmostEqual
:
import unittest
class TestFloats(unittest.TestCase):
def test_floats(self):
self.assertAlmostEqual(0.1 * 3, 0.3, places=5)
# Работа со сравнением чисел с плавающей точкой напоминает: нужно быть готовым к малым неточностям.
Больше гибкости с пользовательской функцией
Создание собственной функции может дать дополнительную гибкость и адаптацию к конкретным кейсам.
def are_floats_almost_equal(x, y, tolerance):
return abs(x – y) < tolerance
assert are_floats_almost_equal(0.1 * 3, 0.3, 1e-12)
# Готов потерпеть что угодно, кроме нетерпимости... и значительных погрешностей в числах с плавающей точкой.
Высокая точность благодаря math.isclose()
Ваши усилия по написанию прозрачного кода не приведут к ущербу для его точности, если вы используете math.isclose()
в Python:
import math
assert math.isclose(0.1 * 3, 0.3, rel_tol=1e-9)
# Мы ближе, чем может показаться на первый взгляд.
Комментарии помогают разобраться в сложностях кода, а порой и уместная шутка может придать тексту некоторый изюм.
Визуализация
Следующая визуализация поможет лучше понять, как работает утверждение приближенного равенства в pytest
:
Цель 🎯: это 'точное значение', к которому мы стремимся
Стрела 1 🏹: Результат, близкий к цели
Стрела 2 🏹: Результат, весьма отклонившийся от цели
🎯
\ | /
– 🏹 -
/ | \
pytest позволяет засчитать попадание стрелы 1 🏹 как почти точное при малых погрешностях.
assert actual_value == pytest.approx(expected_value, abs=tolerance)
Яблочко: expected_value
Круг допустимого отклонения: tolerance
Стрела 1: actual_value
, попадающий в пределы допустимой погрешности
Стрела 2: выход за пределы допустимой погрешности, соответственно ошибка утверждения
Обучение на ошибках
Использование сообщений об ошибках в утверждениях значительно упрощает отладку:
assert a == pytest.approx(b), f"Ожидалось {b}, получено {a}"
# Ого! Похоже, что-то пошло не так.
Такие сообщения предоставляют важные сведения об ошибках и ускоряют процесс отладки.
Полезные материалы
- API Reference — документация pytest — официальная документация pytest, раскрывающая использование
approx
для утверждений приближенного равенства. - numpy.testing.assert_almost_equal — Руководство NumPy v1.26 — справка по сравнению массивов с учетом допустимых отклонений от стандартов с применением NumPy.
- [pytest Quick Start Guide [Книга]](https://www.oreilly.com/library/view/pytest-quick-start/9781789347562/) — краткое введение в утверждения и плагины в pytest для новичков.
- Эффективное тестирование с помощью pytest – Real Python — подробное руководство по тестированию на базе pytest для разработчиков на Python.
- unittest — Фреймворк модульного тестирования — Документация Python 3.12.2 — методы утверждения приближенного равенства в unittest.
- Тестирование Python с помощью pytest: Просто, быстро, эффективно и масштабируемо, автор Brian Okken — практические стратегии для тестирования в Python с использованием pytest.
- The Floating-Point Guide – Сравнение — обзор распространенных проблем при сравнении чисел с плавающей точкой и их решений.