Тестирование, когда правильность плохо определена? - PullRequest
4 голосов
/ 18 марта 2009

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

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

Обычно я делаю все возможное, используя утверждения для проверок работоспособности и создавая небольшой тестовый набор игрушек с известным шаблоном и неформально проверяя, выглядит ли ответ по крайней мере «разумным», без необходимости быть объективно правильным. Есть ли лучший способ проверить такие случаи?

Ответы [ 6 ]

3 голосов
/ 18 марта 2009

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

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

3 голосов
/ 18 марта 2009

Я думаю, что вам просто нужно написать модульные тесты, основанные на небольших наборах данных, которые позволят убедиться, что ваш код выполняет именно то, что вы хотите. Если это дает вам разумный алгоритм извлечения данных, это отдельная проблема, и я не думаю, что ее можно решить с помощью модульных тестов. Существует два «уровня» правильности вашего кода:

  1. Ваш код правильно реализует данный алгоритм интеллектуального анализа данных (эту вещь вам следует выполнить юнит-тестирование)
  2. Алгоритм интеллектуального анализа данных, который вы реализуете, является «правильным» - решает бизнес-проблему. Это довольно открытый вопрос, он, вероятно, зависит как от некоторых параметров вашего алгоритма, так и от реальных данных (разные алгоритмы работают для разных типов данных).
1 голос
/ 18 марта 2009

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

Другой способ - разбить каждый компонент вашей программы на тестируемые части. Если A вызывает B, вызывает C, вызывает D, и вы знаете, что A, B, C, D, все дают правильный ответ, тогда вы проверяете A-> B, B-> C и C-> D, тогда достаточно уверенно, что A-> D дает правильный ответ.

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

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

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

0 голосов
/ 18 мая 2010

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

  • Начните с небольшой, упрощенной, но достаточно репрезентативной выборки данных и протестируйте базовое поведение, выполнив это
  • Вместо того, чтобы утверждать, что вывод - это какой-то ответ, иногда лучше выяснить, что в этом важного. Например, для нашей поисковой системы меня не очень заботил точный порядок перечисления документов, если только три ключевых были на первой странице результатов.
  • Когда вы делаете небольшое, постепенное изменение, выясните, в чем его суть, и напишите для этого тест. Несмотря на то, что общие вычисления требуют много входных данных, отдельные изменения в кодовой базе должны быть изолированными. Например, мы обнаружили, что некоторые документы не появлялись из-за присутствия дефисов в некоторых ключевых словах. Мы создали тесты, которые проверяли, что это ведет себя так, как мы ожидали.
  • Посмотрите на такие инструменты, как Fitness, которые позволяют бросать большое количество наборов данных в кусок кода и утверждать что-то о результатах. Это может быть легче понять, чем более традиционные модульные тесты.
  • Я вернулся к владельцу продукта, сказав: «Я не могу понять, как это будет работать. Как мы узнаем, правильно ли это?» Возможно, он / она может сформулировать суть смутно определенной проблемы. Это сработало очень хорошо для меня много раз, и я отговорил людей от особенностей, потому что они не могли быть объяснены.
  • Будь креативным!
0 голосов
/ 20 марта 2009

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

На самом деле, в идеале компьютер сказал бы: «Не совсем. Я понимаю, почему вы так думаете, но рассмотрите эти 4,2 терабайта информации здесь. Вы уже читали их? На основании этого я бы сказал, что ответ должен быть Z. "

И если вы действительно достигли своей первоначальной цели, конечный пользователь может иногда сказать: «Зоуи, ты прав. Это лучший ответ. Вы нашли образец, который принесет нам деньги! (Или спасет нас»). деньги или что-то в этом роде. "

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

Итак, самое лучшее, что я могу придумать, - это позволить реальной жизни помочь вам составить список тестовых сценариев. Если в прошлом был обнаружен паттерн, который оказался ценным, то проведите «модульный тест», который обнаружит, обнаруживает ли ваша система его при получении аналогичных данных. Я говорю «модульный тест» в кавычках, потому что он может быть больше похож на интеграционный тест, но вы все равно можете использовать NUnit или VS.Net или RSpec или любые другие инструменты модульного тестирования, которые вы используете.

В некоторых из этих тестов вы могли бы как-то попытаться «насмехаться» над 4,2 терабайтами данных (вы не будете насмехаться над данными, но на более высоком уровне вы будете высмеивать некоторые выводы, сделанные из этих данных) , Для других, возможно, у вас есть «тестовая база данных» с некоторыми данными, из которой вы ожидаете, что будет обнаружен набор шаблонов.

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

0 голосов
/ 18 марта 2009

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

...