Начало работы с автоматической интеграцией / модульным тестированием в существующей кодовой базе

Предыстория: нам передана очень большая кодовая база (1,4 миллиона строк), которая в основном написана на C #. Приложение состоит в основном из веб-служб asmx в стиле asp.net 2.0, обращающихся к данным в базе данных SQL Server 2008, а также к различным файлам XML. Существующих автоматизированных тестов нет. У нас есть автоматическая ночная сборка (CC.NET).

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

Как мне изолировать хранилища данных, чтобы получить согласованные результаты тестирования? Могут ли какие-либо инструменты тестирования работать с этим подходом лучше, чем другие? xUnit? MS тесты? NUnit?

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


person nolan    schedule 27.07.2010    source источник


Ответы (4)


Моя компания делала нечто подобное с нашей кодовой базой (C, а не C #), которая насчитывает около миллиона строк. Шаги были примерно такими:

1) Напишите несколько автоматических тестов, как вы описали, которые проводят тесты на уровне системы.
2) Реализуйте правило, согласно которому новый код должен иметь модульный тест.
3) Когда в какой-либо области есть несколько ошибок, процесс исправления эти ошибки должны включать написание базового модульного теста.

Дело в том, что 3 не должен требовать полного модульного теста (если проще люди это сделают). Если вы перейдете от 0% тестового покрытия к 40% -ному охвату конкретного модуля, вы добьетесь большого прогресса.

Хотя через 6 месяцев у вас может быть только до 5% от общей базы кода, из которых 5% - это код, который изменяется больше всего и в котором вы, скорее всего, внесете ошибки. Код, над которым я сейчас работаю, примерно на 60% покрывается интеграционными тестами и 15% (по строкам) покрывается модульными тестами. Это не кажется большим количеством, но это дает значительную ценность, и наши усилия по развитию извлекли из этого пользу.

изменить: в ответ на один из других комментариев текущий набор интеграционных тестов, которые мы запускаем, в настоящее время занимает около 14 часов. Сейчас мы планируем запускать некоторые из них параллельно, чтобы ускорить их.

person Daniel    schedule 27.07.2010
comment
Это тот подход, которого мы придерживаемся. Все идет нормально. Спасибо ~ - person nolan; 06.08.2010

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

  1. Напишите хотя бы один простой тест для каждого API веб-сервиса, чтобы убедиться, что вы охватываете все
  2. Определите API, которые исторически были склонны к сбоям, на основе прошлых отчетов об ошибках. Напишите более подробные тесты для этих API.
  3. Каждый раз, когда вы сталкиваетесь с ошибкой теста, опускайте уровень и напишите тесты для методов, вызываемых по этому пути кода. В конце концов вы обнаружите, что один из этих тестов не работает. Если ошибка не очевидна на этом уровне, опустите уровень и повторите.
  4. Прополощите, промойте, повторяйте каждый раз, когда получаете новый отчет об ошибке.

Идея здесь в том, что вы вводите покрытие модульным тестом «по мере необходимости» на тех путях кода, которые в настоящее время подвержены сбоям. Это укрепит эти пути кода на будущее и постепенно расширит охват модульным тестированием всего приложения.

person JSBձոգչ    schedule 27.07.2010
comment
Спасибо JSBangs, это звучит как очень логичный подход. - person nolan; 28.07.2010

Как указал JSBangs, это тест интеграции вызова. И я согласен, что интеграционный тест лучше, чем модульный тест для вашего случая. Имея 1,4 миллиона строк кода, я не совсем уверен, что вы можете провести модульное тестирование на основе этой кодовой базы.

Для изоляции хранилищ данных мне нравится делать следующее:

  1. Имейте набор жестко закодированных данных для начала

  2. Через некоторое время у вас должен быть тест, который фактически создает кучу тестовых данных. Сначала запустите этот тест, и вам больше не нужны жестко закодированные данные.

  3. Если что-то пойдет не так из-за набора «неверных данных», добавьте их в свой тест. В конце концов, у вас будет хороший набор тестовых данных для проверки большинства случаев.

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

person Chi Chan    schedule 27.07.2010
comment
Приятно учитывать, что интеграционные тесты могут длиться часами. Это должно хорошо сочетаться с нашими ночными сборками. Спасибо - person nolan; 28.07.2010

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

person Igor Zevaka    schedule 27.07.2010