2009-11-30 6 views
18

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

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

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

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

После этого фона, вещи, которые мне нужно помочь в следующем:

  1. Как реализовать структуру теста в уже существующий проекта? (3 года в создание и подсчет)

  2. Какие устройства существуют для тестирования? Я полагаю, что мне понадобится один фреймворк для Javascript и один для PHP.

  3. Каков наилучший подход для тестирования графического интерфейса пользователя ?

Я никогда не использовал Unit Testing, прежде чем это действительно не обозначенная территория для меня.

+5

+1 Это отличный вопрос. На самом деле, я думаю, что существует рыночный разрыв в книге по вопросу введения модульных тестов в унаследованный проект. –

+1

Многие люди на SO, похоже, рекомендуют эту книгу: http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 – yoosiba

ответ

6

G'day,

Edit: Я только что быстрый взгляд через первую главу «The Art of Unit Testing», который также доступен как a free PDF в book's website. Это даст вам хороший обзор того, что вы пытаетесь сделать с модульным тестом.

Я предполагаю, что вы собираетесь использовать инфраструктуру типа xUnit. Некоторые первоначальные мысли высокого уровня являются:

  1. Edit: убедитесь, что все это согласие относительно того, что представляет собой хороший тест единицы. Я бы предложил использовать приведенную выше обзорную главу в качестве хорошей отправной точки и, если нужно, оттуда оттуда. Представьте, что люди с энтузиазмом убегают, чтобы создать множество модульных тестов, имея другое представление о том, что такое «хороший» модульный тест. Было бы ужасно для вас в будущем, чтобы 25% ваших модульных тестов не были полезны, повторяемы, надежны и т. Д. И т. Д.
  2. добавить тесты для покрытия небольших фрагментов кода за раз. То есть не создавайте единую монолитную задачу для добавления тестов для существующей базы кода.
  3. изменить любые существующие процессы, чтобы добавить новые тесты для любого нового написанного кода. Сделайте его частью процесса обзора кода, который должен быть предоставлен для новых функций.
  4. расширяет любые существующие процессы исправления, чтобы убедиться, что новые тесты созданы, чтобы показать присутствие и доказать отсутствие ошибки. Нотабене Не забудьте отменить исправление кандидата, чтобы снова ввести ошибку, чтобы убедиться, что только этот единственный патч исправил проблему и не фиксируется комбинацией факторов.
  5. Редактировать:, когда вы начинаете наращивать количество своих тестов, запускайте их как ночные регрессионные тесты, чтобы проверить, что ничего не было нарушено новыми функциями.
  6. сделать успешный прогон все существующие тесты и критерий ввода для процесса проверки кандидата-исправления.
  7. Редактировать: начать хранить каталог типов испытаний, то есть фрагменты тестового кода, чтобы упростить создание новых тестов. Нет смысла изобретать колесо все время. Тест (ы) блока, написанный для проверки открытия файла в одной части базы кода, будет/будет похож на тестер (ы) модуля, написанный на тестовый код, который открывает другой файл в другой части базы кода , Каталог, чтобы сделать их легко найти.
  8. Редактировать: где вы только модифицируете несколько методов для существующего класса, создайте тестовый набор, чтобы провести полный набор тестов для этого класса. Затем добавьте только отдельные тесты для методов, которые вы модифицируете в этом наборе тестов. Это использует терминологию xUnit, поскольку я предполагаю, что вы будете использовать инфраструктуру xUnit, такую ​​как PHPUnit.
  9. использовать стандартное соглашение для обозначения ваших тестовых наборов и тестов, например. testSuite_classA, который затем будет содержать отдельные тесты, такие как test__test_function. Например, test_fopen_bad_name и test_fopen_bad_perms и т. Д. Это помогает свести к минимуму шум при перемещении базы кода и просмотре тестов других людей. В то же время он помогает людям, когда они приходят, чтобы назвать свои тесты, в первую очередь, высвобождая свой ум, чтобы работать над более интересными вещами, такими как сами тесты.
  10. Редактировать: Я бы не использовал TDD на этом этапе. По определению TDD будет нуждаться во всех тестах до того, как изменения будут на месте, поэтому у вас будут неудачные тесты по всему миру, когда вы добавляете новые теги testSuites для охвата классов, над которыми вы работаете. Вместо этого добавьте новый testSuite, а затем добавьте индивидуальные тесты по мере необходимости, чтобы вы не получали много шума, возникающего в результатах теста для неудачных тестов. И, как указывает Йишай, добавление задачи изучения TDD в данный момент времени действительно замедлит вас. Поместите обучающую TDD как задачу, которая будет выполняться, когда у вас будет свободное время. Это не так сложно.
  11. В качестве следствия этого вам понадобится инструмент для отслеживания тех существующих классов, где существует testSuite, но где тесты еще не были написаны для покрытия других функций-членов в классе. Таким образом, вы можете отслеживать, где у вашего тестового покрытия есть дыры. Здесь я говорю на высоком уровне, где вы можете создать список классов и конкретных функций-членов, где в настоящее время тестов нет. Стандартное соглашение об именах для тестов и testSuites значительно поможет вам здесь.

Я добавлю больше очков, поскольку я думаю о них.

НТН

+2

Должен ли я писать сценарии для полных классов сразу или просто методы? Помните, что я новичок в этом модульном тестировании :) – Skoog

+0

@Skoog, просто добавила ссылку на отличное введение в модульное тестирование. –

+1

Благодарю вас от имени всей нашей команды. Много хорошего материала, который вы предоставили. – Skoog

0

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

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

Я не очень уверен в модульном тестировании, но NetBeans имеет встроенный модуль тестирования модулей.

3

С точки зрения планирования, я думаю, у вас есть три основных варианта:

  1. принять цикл модифицировать код с блок тестирует
  2. Обозначьте часть команды, чтобы модифицировать код с блоком тестирует
  3. постепенно вводить модульные тесты при работе над кодом

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

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

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

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

Для общих принципов модульного тестирования я рекомендую книгу xUnit Test Patterns: Refactoring Test Code по Жерар Мессарос.

+0

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

2

Я использовал PHPUnit с хорошими результатами. PHPUnit, как и другие производные от JUnit проекты, требует, чтобы тестируемый код был организован в классы. Если ваш проект не является объектно-ориентированным, вам нужно будет начать рефакторинг непроцедурного кода в функции и функции в классы.

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

Для тестирования приложений GUI вы можете воспользоваться Selenium, хотя контрольный список, написанный программистом с хорошими интуициями QA, может работать нормально. Я обнаружил, что использование MediaWiki или вашего любимого механизма Wiki - хорошее место для хранения контрольных списков и соответствующей проектной документации.

+0

Как это бывает, 70-80% относится к классу, а остальное все еще процедурное. Тем не менее прилагает все усилия, чтобы получить эти оставшиеся 20% в классы, а также. – Skoog

+0

+1 PHPUnit. Я слышал смешанные сообщения о Селене, потому что он склонен поощрять хрупкие тесты. Однако я не могу предложить более простую инфраструктуру тестирования xUnit-y JS. Если JS были сгенерированы, стиль GWT, то для этого есть xUnit. –

0

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

+0

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

6

Вы должны получить себе копию Working Effectively with Legacy Code. Это даст вам хорошее руководство в том, как вводить тесты в код, который не написан для тестирования.

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

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

+0

@ Yishai, хороший момент о потенциальных последствиях позднего внедрения TDD. Я думаю, что он может быть добавлен для совершенно нового кода, хотя если люди уже знают TDD. Основы обучения TDD, xUnit и основы тестирования модулей все сразу ** не будут работать хорошо! –

0

Может быть, этот список поможет вам и вашим товарищам, чтобы реструктурировать все:

  1. Использование UML, для разработки и обработки исключений (http://en.wikipedia.org/wiki/Unified_Modeling_Language)
  2. Использование BPMS, чтобы создать свой рабочий процесс, чтобы вы не будет бороться (http://en.wikipedia.org/wiki/Business_process_management)
  3. Получить список фреймворок, который также поддерживает JavaScript движков (например, Zend с JQuery)
  4. Сравните эти рамки и принять один, который соответствует самому вашему проекту Desgin и структура кодирования используемый Перед
  5. Вы должны можно рассмотреть вопрос об использовании вещи, как ezComponents и DTrace для отладки и тестирования
  6. Не бойтесь перемен;)
5

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

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

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

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

+0

Я понял, что это долгий процесс. Поэтому я готов. То, что меня больше всего волновало, было: с чего мне начать? Как я могу продолжить? Но все, что вы воспитываете, я понимаю. Я думаю, что это будет очень полезно для нас. Мне просто нужно прочитать информацию об испытаниях TTD и Unit. У вас будут хорошие ресурсы для начинающих в этой области? – Skoog

0

Для тестирования графического интерфейса вы можете взглянуть на Selenium (как уже указывал Игнас Р.) ИЛИ вы также можете взглянуть на этот инструмент: STIQ.

Удачи!

0

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

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

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

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

0

Я согласен с KOHb, Selenium является обязательным!

также посмотреть на PHPure,

Их программное обеспечение записывает входы и выходы из рабочего сайта PHP, а затем автоматически записывает PHPUnit тесты для функций, которые не обращаются к внешним источникам (БД, файлы и т.д ..) ,

Это не 100% -ное решение, но это отличное начало.

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