2009-11-23 3 views
2

Я никогда раньше не использовал модульное тестирование, поэтому я даю CxxTest. Я написал тест, чтобы проверить, правильно ли функция сортирует std :: vector. Сначала я убедился, что тест завершился неудачно, когда вектор не был отсортирован, а затем, как проверка работоспособности, я проверил, работал ли std :: sort (конечно, это было). Все идет нормально.Как провести тестирование сортировки std :: vector

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

Я делаю что-то неправильно здесь? Я думал, что модульное тестирование было так просто, как

1) Написать тест
2) Написать функцию
3) Тест функция
4) Если тест не пройден, пересмотреть функции
5) Повторите 3 и 4 до испытания проходит

процесс я был больше похож

1) Написать тест
2) Написать функцию
3) Тест функция
4) Если тест не пройден, отлаживать функция пока не работает правильно
5) Повторите 3 (даже если функция уже известно, работает)

Я чувствую например, мой процесс не был действительно TDD, потому что дизайн моей функции сортировки не был приведенным мной испытанием. Должен ли я написать больше тестов, например. тесты, которые проверяют промежуточные состояния вектора по мере его сортировки?

+0

Как вы запустили функцию без использования модульного теста? Используя другой код, если это так, зачем вам нужно, чтобы модульные тесты должны предоставлять нужные вам данные. – Mark

ответ

4

Тесты не должны отлаживать ваш код для вас.

Я чувствую, что мой процесс не был действительно TDD

Вы написали тест. Он нашел ошибку. Вы исправили ошибку. Ваш тест прошел. Система работает!

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

В любом случае, чувство вины, потому что вы не достигаете чистого TDD или чистого ООП или что-то еще такое психологическое расстройство. Идите вперед и будьте продуктивны.

+0

'Тесты не должны отлаживать ваш код для вас.« Это ключевой момент, который мне не хватало. +1 для объяснения этого в самых ясных условиях. – ThisSuitIsBlackNot

2

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

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

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

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

+0

Вы подняли несколько хороших моментов, которые я не рассматривал. Я только сортировал случайные данные, но уже отсортированные и реверсированные массивы данных являются важными краевыми случаями для проверки. Отличная идея о стабильных родах ... Думаю, они потребуют от меня написать дополнительные тесты. – ThisSuitIsBlackNot

1

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

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

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

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

+0

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

+1

Кстати, +1 для этого: «Преимущество заключается не столько в том, чтобы заставить единицы кода работать, сколько в том, что они все еще работают, когда вы меняете вещи ...» Просто потому, что я знаю, что мой алгоритм работает сейчас, означает, что он будет работать после того, как я его реорганизую. Тесты должны сказать мне, если я сломаю его по дороге. – ThisSuitIsBlackNot

2

Модульное тестирование фокусируется на специфическом внешнем поведении вещи, которую вы пишете, оно не может реально понять промежуточные состояния алгоритма. Функция сортировки - довольно частный случай.

Более обычно мы имеем дело с бизнес-логикой рода

«Стоимость заказа является суммой цен пунктов заказа уменьшенных на скидку в размере 10%, если общая стоимость превышает £ 20 и еще на 5%, если клиент является членом золота»

Мы сразу же можем написать тесты, такие как

  • нет порядка пунктов
  • Один заказ стоимость вещь £ 20,00
  • одно значение позиции заказа £ 20,01
  • Две позиции заказа Общая стоимость £ 20,00 золота клиента
  • ...

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

Для кода сортировки может быть полезно иметь тесты, такие как

  • {0}
  • {1, 2}
  • {2, 1}
  • {1, 1}

и так далее, но тесты действительно не знают, выполняете ли вы QuickSort или BubbleSort или что-то еще.

2

Процесс TDD является

  1. RED: написать тест, убедитесь, что он не может

  2. ЗЕЛЕНЫЙ записи достаточно просто код, чтобы сделать его пройти, убедитесь, что он проходит

  3. рефакторинг кода - как испытательный, так и производственный код

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

+0

Я думаю, что ты прав ... Я * слишком много тестировал. Тест, который я написал первоначально, проверял, был ли отсортирован вектор из 100 случайных чисел. Я должен был написать тест, чтобы проверить сортировку пустого вектора, затем ** другой ** тест для проверки одного элемента вектора и т. Д. (Если я придерживаюсь только одного утверждения для каждого теста, то есть). – ThisSuitIsBlackNot

Смежные вопросы