Имея опыт работы в области аналитики и науки о данных, я привык считать написание тестов чем-то болезненным. Я знал, что это важно, но никогда не знал, с чего начать, и всегда откладывал проект до конца. Что может быть скучнее, чем тестировать кусок кода, который уже работает?

В последнее время я стал смотреть на вещи с другой стороны. Я открыл для себя разработку через тестирование: пишите свои тесты до того, как вы на самом деле кодируете функциональную часть кода. Это лучшая практика разработки программного обеспечения, которая заслуживает того, чтобы ее чаще применяли к проектам по науке о данных.

Что такое разработка через тестирование (TDD)?

Проще говоря, через каркас Red/Green/Refactor. Каждый раз, когда вы хотите добавить функциональность в код, вы можете следовать трехэтапному циклу:

  1. Красный. Создайте тест, который не пройден.т. е. напишите функциональные потребности вашего кода
  2. Зеленый. Напишите производственный код, который проходит тест. т.е. выполнять функциональные потребности кода
  3. Проведите рефакторинг. Наведите порядок в только что созданном беспорядке.т. е. очистите свой код, не меняя функциональность

Пример из реальной жизни

Проиллюстрируем это на примере из реальной жизни. В качестве этапа постобработки для проекта Распознавание именованных объектов мы хотим создать функцию обработки для извлечения единицы продолжительности (день/неделя/месяц/..) и значения длительности в тексте. .

  1. Давайте напишем модульный тест, отвечающий функциональным потребностям, и пустую функцию.

Тест КРАСНЫЙ🔴 Это нормально, потому что функция возвращает пустой словарь.

2. Мы пишем код, который проходит тест.

Тест ЗЕЛЕНЫЙ 🟢Ура!!Подождите.. мы уверены, что он СУХОЙ, ТВЕРДЫЙ, pep8??

3. Мы рефакторим функцию, чтобы обеспечить лучшие практики кодирования.

Здесь мы добавили аннотации типов, создали универсальную функцию для преобразования числа букв в число с плавающей запятой (также с собственным модульным тестом) и изменили способ заполнения словаря.

Где мы можем применить разработку через тестирование в науке о данных?

Разработка через тестирование не актуальна на каждом этапе проекта по науке о данных. Например, не стоит этого делать во время исследования данных или моделей, когда вы не уверены в том, что ищете: написание тестов без знания ожидаемого результата, вероятно, является излишним.

Это становится очень полезным всякий раз, когда вам нужно построить надежные производственные конвейеры.

В этом контексте нам необходимо реализовать несколько типов тестов:

  • Модульные тесты: тест для каждого фрагмента кода проекта.
  • Тесты модели: убедитесь, что модель имеет хорошую производительность и ведет себя правильно.
  • Интеграционные тесты: проверка наличия хорошей связи между каждым фрагментом кода.

Разработка через тестирование очень хорошо подходит для модульных тестов, особенно для обрабатывающих частей конвейера (предварительной и последующей обработки), где код является детерминированным.

Для тестов моделей его следует использовать с осторожностью. При работе с прогностическими моделями мы имеем дело с неопределенностью. Действительно, многие алгоритмы машинного обучения по своей сути случайны — несколько запусков с использованием одних и тех же входных данных могут каждый раз давать несколько разные результаты. Это может привести к ненадежным тестам: тесту, который иногда проходит, а иногда терпит неудачу, несмотря на отсутствие изменений в коде или самом тесте. Если мы слишком конкретизируем тестовые случаи во время первой разработки через тестирование, весьма вероятно, что некоторые тесты сломаются на следующей итерации. Новая модель может вести себя по-другому в некоторых случаях, но при этом работать лучше в глобальном масштабе.Поэтому лучше включать в модельные тесты только базовые случаи, которые необходимы для проекта.

Наконец, для интеграционных тестов это хорошо подходит для фрагментов кода, которые не включают предсказания модели. Если он включает прогнозирование модели, лучше протестировать формат вывода, чем фактический вывод.

Хорошей практикой является включение этих тестов в CI/CD вашего проекта. Поэтому всякий раз, когда делается предложение о новой функциональности, гарантируется, что никакая другая функциональность не будет нарушена.

Почему это меняет правила игры?

Внедрение разработки через тестирование действительно меняет способ организации сеансов кодирования и дает массу преимуществ:

  • Он мгновенно проверяет деловые и технические спецификации. Кроме того, это отличная документация для специалистов по данным, которые изучают проект и должны понимать, как он работает.
  • Это дает уверенность в коде. Каждый вариант использования проходит тестирование, и вы или ваши товарищи по команде можете добавлять дополнительные функции, не опасаясь сломать уже сделанное.
  • Это экономия времени. Можно рассматривать это как нечто, замедляющее развитие. Но это не так, это заставляет вас заранее думать о функциональных потребностях и предвидеть крайние случаи. Поверьте мне, в конце концов, это экономит много времени на отладку и итерацию.
  • Это дажеделаетразработкуболее увлекательной! Он разбивает код на небольшие решения проблем. И это идеально подходит для однорангового кодирования.

Разработка через тестирование — это один из множества передовых методов кодирования, которым я научился, работая специалистом по данным в Doctolib. Ознакомьтесь с открытыми вакансиями: https://about.doctolib.fr/jobs/.