Код машинного обучения поблочного тестирования

Как вы уже сказали, это, безусловно, вопрос, связанный с мнением. Я сам больше обращусь к подходу No-DTO, просто из-за всего кода шаблона, который вам нужен.

Это в основном относится к стороне ответа json / rest api. Я даже написал аддон Джексона, чтобы не писать много json-представлений / фильтров для этих случаев: https://github.com/Antibrumm/jackson-antpathfilter

С другой стороны, DTO являются хорошей вещью на стороне ввода запроса таких API. Например, работа с сущностями может быть довольно сложной с учетом двунаправленных отношений. Также вы действительно не хотите, чтобы вызывающий абонент модифицировал атрибут «создатель», например. Поэтому при сопоставлении таких запросов вам необходимо будет распутать определенные поля.

30
задан Hannes Ovrén 12 February 2010 в 11:59
поделиться

6 ответов

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

Окончательное мнение на этот счет - книга Майкла Фезера, Working Effectively with Legacy Code. Раньше на сайте ObjectMentor было полезное краткое изложение этой книги, но, увы, сайт ушел в небытие. Однако WELC оставил наследие в обзорах и других статьях. Посмотрите их (или просто купите книгу), хотя ключевые уроки - это те, которые S.Lott и tvanfosson освещают в своих ответах.


Обновление 2019 года: я исправил ссылку на резюме WELC на версию из веб-архива Wayback Machine (спасибо @milia).

Также - несмотря на то, что я знаю, что ответы, состоящие в основном из ссылок на другие сайты, являются ответами низкого качества :) - вот ссылка на новый (2019 новый) учебник Google по тестированию и отладке ML-кода. Надеюсь, это будет полезно для будущих искателей, которые наткнутся на этот ответ.

11
ответ дан 28 November 2019 в 00:09
поделиться

«тогда я на самом деле не проверяю все, что может пойти не так».

Правильно.

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

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

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

Выбирайте свои тесты с умом.

Кроме того, работа модульных тестов состоит в том, чтобы проверить, что каждая небольшая часть общего приложения делает правильные вещи - в изоляции.

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

Например, ваша «вычислительная работа на кривой с более низким разрешением», вероятно, состоит из нескольких небольших частей, которые можно протестировать как отдельные модули. В изоляции.

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

12
ответ дан S.Lott 28 November 2019 в 00:09
поделиться

Ваши модульные тесты должны использовать некоторый коэффициент нечеткости , либо принимая аппроксимации, либо используя какие-то вероятностные проверки.

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

TEST_ALMOST_EQ(result, 4.0);

Выше TEST_ALMOST_EQ может убедиться, что result находится между 3,9 и 4,1 (например).

В качестве альтернативы, если ваши алгоритмы машинного обучения являются вероятностными, ваши тесты должны будут учесть это, взяв среднее значение за несколько прогонов и ожидая, что оно будет в некотором диапазоне.

x = 0;
for (100 times) {
  x += result_probabilistic_test();
}

avg = x/100;
TEST_RANGE(avg, 10.0, 15.0);

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

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

НТН.

7
ответ дан 0xfe 28 November 2019 в 00:09
поделиться

Как правило, для статистических показателей вы должны добавить эпсилон для своего ответа. И.Е. среднеквадратичная разница ваших точек будет < 0,01 или что-то подобное. Другой вариант - запускать несколько раз, и если он выходит «слишком часто», у вас есть проблема.

1
ответ дан Joel 28 November 2019 в 00:09
поделиться
  1. Получить соответствующий набор тестовых данных (может быть подмножество того, что вы обычно используете)
  2. Рассчитать некоторую метрику для этого набора данных (например, точность)
  3. Запишите полученное значение ( перекрестная проверка)
  4. Это должно дать представление о том, что нужно установить пороговое значение для

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

0
ответ дан Tobias Domhan 28 November 2019 в 00:09
поделиться

Не видя вашего кода, трудно сказать, но я подозреваю, что вы пытаетесь писать тесты на слишком высоком уровне. Возможно, вам стоит подумать о том, чтобы разбить ваши методы на более мелкие компоненты, которые являются детерминированными, и протестировать их. Затем протестируйте методы, которые используют эти методы, предоставляя имитационные реализации, которые возвращают предсказуемые значения от базовых методов (которые, вероятно, расположены на другом объекте). Затем вы можете написать тесты, которые охватывают область действия различных методов, гарантируя, что у вас есть покрытие всего диапазона возможных результатов. Для небольших методов вы делаете это, предоставляя значения, которые представляют область входных данных. Для методов, которые зависят от них, - путем предоставления имитационных реализаций, которые возвращают диапазон результатов из зависимостей.

11
ответ дан 28 November 2019 в 00:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: