Как работает модульное тестирование, когда программа не поддается функциональному стилю? - PullRequest
8 голосов
/ 04 марта 2009

Я думаю о случае, когда программа на самом деле ничего не вычисляет, она просто делает много. Модульное тестирование имеет смысл для меня, когда вы пишете функции, которые что-то вычисляют, и вам нужно проверить результат, но что, если вы ничего не вычисляете? Например, программа, которую я поддерживаю на работе, полагается на то, чтобы пользователь заполнил форму, затем открыл внешнюю программу и автоматизировал внешнюю программу, чтобы сделать что-то на основе ввода пользователя. Процесс довольно сложный. Там примерно 3000 строк кода (распределенных по нескольким функциям *), но я не могу вспомнить ни одной вещи, которая имеет смысл для модульного тестирования.

Это всего лишь пример. Стоит ли вам даже пытаться тестировать «процедурные» программы?

* EDIT

Ответы [ 10 ]

2 голосов
/ 04 марта 2009

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

  • Правильно ли работает проверка формы пользовательского ввода
  • При правильном вводе из формы внешняя программа называется корректно
  • Введите пользовательский ввод во внешнюю программу и посмотрите, правильно ли вы выводите

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

2 голосов
/ 04 марта 2009

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

1 голос
/ 04 марта 2009

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

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

  • Установите что-то вроде репозитория git для начального состояния файловой системы, запустите форму и посмотрите на вывод git diff. Скорее всего, это будет скорее регрессионное тестирование, чем юнит-тестирование.

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

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

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

1 голос
/ 04 марта 2009

У вас есть 3000 строк кода в одной процедуре / методе? Если это так, то вам, вероятно, нужно реорганизовать ваш код в более мелкие, более понятные части, чтобы сделать его поддерживаемым. Когда вы сделаете это, у вас будут те части, которые вы можете и должны тестировать. Если нет, то у вас уже есть эти части - отдельные процедуры / методы, которые вызываются вашей основной программой.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Хорошая статья об объекте наставника по TDD

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...