Как реализовать тестовую среду в устаревшем проекте - PullRequest
18 голосов
/ 30 ноября 2009

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

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

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

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

После этого фона мне нужна помощь:

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

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

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

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

Ответы [ 11 ]

6 голосов
/ 30 ноября 2009

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

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

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

6 голосов
/ 30 ноября 2009

G'day,

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

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

  1. Редактировать: убедиться, что все согласны с тем, что представляет собой хороший модульный тест. Я бы предложил использовать приведенную выше обзорную главу в качестве хорошей отправной точки и, если необходимо, взять ее оттуда. Представьте себе, что люди с энтузиазмом убегают создавать множество модульных тестов, но по-разному понимают, что такое «хороший» модульный тест. Было бы ужасно, если бы в будущем вы увидели, что 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, но где еще не написаны тесты для охвата других функций-членов в классе. Таким образом, вы можете отслеживать, где в вашем тестовом покрытии есть дыры. Я говорю здесь на высоком уровне, где вы можете создать список классов и конкретных функций-членов, где в настоящее время нет тестов. Стандартное соглашение об именах для tests и testSuites очень поможет вам в этом.

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

НТН

5 голосов
/ 30 ноября 2009

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

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

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

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

3 голосов
/ 30 ноября 2009

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

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

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

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

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

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

Для общих принципов модульного тестирования я рекомендую книгу Gerard Meszaros Тестовые таблицы xUnit: рефакторинг тестового кода.

2 голосов
/ 30 ноября 2009

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

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

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

0 голосов
/ 14 апреля 2015

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

Также взгляните на PHPure ,

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

Это не 100% решение, но хорошее начало

0 голосов
/ 01 декабря 2009

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

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

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

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

0 голосов
/ 30 ноября 2009

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

Удачи!

0 голосов
/ 30 ноября 2009

Возможно, этот список поможет вам и вашим товарищам перестроить все:

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

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

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