Автоматизированное тестирование «непроверяемого» приложения в C #.Устройство / Интеграция / Функциональное / Системное тестирование - Как? - PullRequest
2 голосов
/ 20 октября 2011

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

  • Приложение является многоуровневым
  • Не написано с учетом тестирования (многие синглтоны содержат настройки уровня приложения, объекты неподделка, "состояние" требуется во многих местах)
  • Приложение очень ориентировано на данные
  • Большинство "функциональных процессов" являются сквозными (клиент -> сервер -> база данных)

Рассмотрим этот сценарий:

var item = server.ReadItem(100);
var item2 = server.ReadItem(200);
client.SomethingInteresting(item1, item2);
server.SomethingInteresting(item1, item2);

Определение вызова сервера:

Server::SomethingInteresting(Item item1, Item item2)
{
  // Semi-interesting things before going to the server.

  // Possibly stored procedure call doing some calculation
  database.SomethingInteresting(item1, item2);
}

Как настроить некоторые автоматические тесты для этого, где есть взаимодействие с клиентом, серверомвзаимодействие, то взаимодействие с базой данных?

Я понимаю, что это не "единица".Возможно, это пример функционального тестирования.

Вот мои вопросы:

  • Тестирование такого приложения - безнадежное дело?
  • Можно ли это сделать с помощьючто-то вроде nUnit или MS Test?
  • Будет ли "настройка" этого теста просто принудительно запускать полное приложение и входить в систему?
  • Буду ли я просто перечитывать item1 и item2 из базы данных, чтобыподтвердить, что они написаны правильно?
  • У вас, ребята, есть какие-нибудь советы о том, как начать этот пугающий процесс?

Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

2 голосов
/ 20 октября 2011

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

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

Является ли тестирование такого приложения безнадежным делом?

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

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

Можно ли это сделать, используя что-то вроде nUnit или MS Test?

Да. Существуют платформы тестирования веб-страниц / пользовательского интерфейса, которые можно использовать из библиотек модульного тестирования .Net, включая встроенную в Visual Studio.

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

Будет ли "настройка" этого теста просто принудительно запускать полное приложение и входить в систему?

На стороне клиента, да. Если вы не хотите проверить логин, конечно:)

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

Могу ли я просто перечитать item1 и item2 из базы данных, чтобы проверить, правильно ли они написаны?

Типичные интеграционные тесты основаны на концепции Finite State Machine . Такие тесты обрабатывают тестируемый код, как если бы он был набором переходов между состояниями, и делают утверждения о конечном состоянии системы.

Таким образом, вы предварительно установите БД в известное состояние, вызовите метод на сервере, а затем проверите БД.

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

Ребята, есть ли у вас какие-нибудь советы, как начать этот пугающий процесс?

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

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

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

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

Затем включите покрытие кода в тестируемом приложении. Посмотрите, какие части приложения вы пропустили.

Повторяйте с каждым последующим набором тестов с более высоким приоритетом, пока все приложение не будет протестировано на каком-либо уровне, и вы отправите:)

2 голосов
/ 20 октября 2011

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

Я думаю, что вы сможете сделать хотя бы некоторые части своего приложения тестируемыми, потратив немного времени.Удачи!

2 голосов
/ 20 октября 2011

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

Чтобы продвинуться дальше, вы должны начатьпопадание в базу данных с интеграционными тестами.Для этого вы должны контролировать данные в базе данных и очистить после завершения теста.Несколько способов сделать это.Вы можете запускать сценарии sql как часть установки / разрыва для каждого теста.Вы можете использовать инфраструктуру AOP времени компиляции, такую ​​как Postsharp, для запуска сценариев sql, просто указав их в атрибутах.Или, если ваш проект не хочет использовать Postsharp, вы можете использовать встроенную функцию точечной сети под названием «Объекты, привязанные к контексту», чтобы внедрить код для запуска сценариев Sql в режиме AOP.Подробнее здесь - http://www.chaitanyaonline.net/2011/09/25/improving-integration-tests-in-net-by-using-attributes-to-execute-sql-scripts/

По сути, я бы предложил следующие шаги:

1) Установите Pex и сгенерируйте несколько юнит-тестов.Это будет самый быстрый и наименее трудоемкий способ создания хорошего набора регрессионных тестов.

2) Проанализируйте модульные тесты и посмотрите, есть ли другие тесты или варианты теста, которые вы можете использовать.Если это так, напишите их от руки.Представьте насмешливую структуру, если вам нужно.

3) Начните выполнять комплексное тестирование.Написание сценариев sql для вставки и удаления данных в базу данных.Напишите модульные тесты, которые будут запускать сценарии вставки SQL.Вызовите очень высокоуровневый метод в вашей прикладной программе, такой как «AddNewUser», и убедитесь, что он проходит весь путь до серверной части.Интерфейсный, высокоуровневый метод может вызывать любое количество промежуточных методов на разных уровнях.

4) Как только вы обнаружите, что пишете множество интеграционных тестов по этому шаблону, «Запустите сценарий sql для вставки тестовых данных» ->Вызов высокоуровневого функционального метода -> «Выполнить сценарий Sql для очистки тестовых данных», вы можете очистить код и инкапсулировать этот шаблон, используя методы AOP, такие как Postsharp или Context Bound Methods.

2 голосов
/ 20 октября 2011

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

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

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