Подтвердить что ты не робот

Как реализовать тестовую структуру в устаревшем проекте

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

G'day,

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

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

  • Изменить: убедитесь, что все согласны с тем, что составляет хороший unit test. Я бы предложил использовать приведенную выше обзорную главу в качестве хорошей отправной точки и, если нужно, оттуда оттуда. Представьте, что люди с энтузиазмом убегают, чтобы создать множество модульных тестов, имея другое представление о том, что такое "хороший" unit test. Было бы ужасно для вас в будущем, что 25% ваших модульных тестов не являются полезными, повторяемыми, надежными и т.д. И т.д.
  • добавьте тесты, чтобы покрывать небольшие куски кода за раз. То есть не создавайте одну монолитную задачу для добавления тестов для существующей базы кода.
  • изменить любые существующие процессы, чтобы добавить новые тесты для любого нового написанного кода. Сделайте его частью процесса обзора кода, который должен быть предоставлен модульными тестами для новых функций.
  • расширять любые существующие процессы исправления, чтобы убедиться, что новые тесты созданы, чтобы показать присутствие и доказать отсутствие ошибки. Нотабене Не забудьте отменить исправление кандидата, чтобы снова ввести ошибку, чтобы убедиться, что это только один патч, который исправил проблему, и не фиксируется комбинацией факторов.
  • Изменить:, когда вы начнете наращивать количество своих тестов, запускайте их как ночные регрессионные тесты, чтобы проверить, что ничего не было нарушено новыми функциями.
  • провести успешный запуск существующих всех существующих тестов и критерия ввода для процесса проверки кандидата. bugfix.
  • Изменить: начать хранить каталог типов тестов, то есть тестировать фрагменты кода, чтобы упростить создание новых тестов. Нет смысла изобретать колесо все время. unit test (ы), написанные для проверки открытия файла в одной части базы кода, будут/будут похожи на unit test (s), записанные на тестовый код, который открывает другой файл в другой части база кода. Каталог, чтобы они легко находились.
  • Изменить:, где вы только модифицируете несколько методов для существующего класса, создайте тестовый набор, чтобы провести полный набор тестов для этого класса. Затем добавьте только отдельные тесты для методов, которые вы модифицируете в этом наборе тестов. Это использует терминологию xUnit, поскольку я предполагаю, что вы будете использовать инфраструктуру xUnit, такую ​​как PHPUnit.
  • используйте стандартное соглашение для обозначения ваших тестовых наборов и тестов, например. testSuite_classA, который затем будет содержать отдельные тесты, такие как test__test_function. Например, test_fopen_bad_name и test_fopen_bad_perms и т.д. Это помогает свести к минимуму шум при перемещении базы кода и поиске других тестов. В то же время он помогает людям, когда они приходят, чтобы назвать свои тесты, в первую очередь, высвобождая свой ум, чтобы работать над более интересными вещами, такими как сами тесты.
  • Изменить: Я бы не использовал TDD на этом этапе. По определению TDD будет нуждаться во всех тестах до того, как изменения будут на месте, поэтому у вас будут неудачные тесты по всему миру, когда вы добавляете новые теги testSuites для охвата классов, над которыми вы работаете. Вместо этого добавьте новый testSuite, а затем добавьте индивидуальные тесты по мере необходимости, чтобы вы не получали много шума, возникающего в результатах теста для неудачных тестов. И, как указывает Йишай, добавление задачи изучения TDD в данный момент времени действительно замедлит вас. Поместите обучающую TDD как задачу, которая будет выполняться, когда у вас будет свободное время. Это не так сложно.
  • в качестве следствия этого вам понадобится инструмент для отслеживания тех существующих классов, где существует testSuite, но где тесты еще не были написаны для покрытия других функций-членов в классе. Таким образом, вы можете отслеживать, где у вашего тестового покрытия есть дыры. Здесь я говорю на высоком уровне, где вы можете создать список классов и конкретных функций-членов, где в настоящее время тестов нет. Стандартное соглашение об именах для тестов и testSuites значительно поможет вам здесь.

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

НТН

Ответ 2

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

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

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

Удачи!

Ответ 10

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

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

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

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

Ответ 11

Я согласен с KOHb, Selenium - это обязательно!

Также посмотрите PHPure,

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

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