Имеется некий WCF сервис, который хотелось бы протестировать интеграционными тестами.
Создал небольшую простенькую программку следующего содержания:
-- имеются классы сценариев, которые представляют собой реальные сценарии взаимодействия с сервисом, например, завести пользователя,
создать для этого пользователя проект, положить в этот проект какой-нибудь файл, и сделать какой-нибудь запрос;
-- сценарии состоят из отельных шагов (step), т.е. по сути своей шаг -- это некий класс-обертка над методом сервиса: авторизация пользователя,
удаление чего-либо и т.д.
Здравствуйте, Sharov, Вы писали:
S> -- имеются классы сценариев, которые представляют собой реальные сценарии взаимодействия с сервисом, например, завести пользователя,
Слово "сценарий" сразу мне напоминает о BDD. Посмотри в сторону NAct, xBehave, xSpec или подобного. Да вообще погугли ".NET BDD".
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Про BDD слышал. Т.е. мне необходимо боевое тестирование сервиса, со всеми side-effect'ами и прочим.
Интересовал сам подход к тому, как это лучше осуществить. Может кто сталкивался или использовал какие-нибудь
фреймворки для интеграционных и необязательно тестов. Все что я видел, либо платное, либо не очень
продвинутое (soapUI, например).
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, ., Вы писали:
S>Про BDD слышал. Т.е. мне необходимо боевое тестирование сервиса, со всеми side-effect'ами и прочим. S>Интересовал сам подход к тому, как это лучше осуществить. Может кто сталкивался или использовал какие-нибудь S>фреймворки для интеграционных и необязательно тестов. Все что я видел, либо платное, либо не очень S>продвинутое (soapUI, например).
Я бы для сервиса (SOAP?) генерил клиентский стаб из wsdl и тупо писал бы тесты:
@Test
void testUserRegistration()
{
User user = theService.registerUser("vasya");
assert vasya.getName() == "vasya";
}
И это дело бы деплоилось и выполнялось в тестовом окружении CI сервером.
В общем мне не понятен конкретный вопрос. JFDI.
Что ты ожидаешь от фреймворка?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
S>Т.е. мне необходимо боевое тестирование сервиса, со всеми side-effect'ами и прочим. S>Интересовал сам подход к тому, как это лучше осуществить.
Мне вот тоже непонятно что именно спрашивается. Если специализированный тул конкретно для сервисов, то причем тут C# и интерфейсы? Неужели специализированный тул будет заточен как раз под твои нужды?
А самое главное, почему бы не сгенерить клиента к этому сервису (как советует <b>.</b>
), а далее уже использовать любой из инструментов тестирования (а уж в них прикрутить IScenario и проч. не сставит труда).
Я именно так и тестирую свои сервисы. Только я не тестировал сам WCF сервис, я напрямую создавал объект сервиса в коде (благо WCF позволяет это) и вызывл его через его интерфейс.
Здравствуйте, ., Вы писали:
.>Что ты ожидаешь от фреймворка?
Очень виноват, т.к. некорректно сформулировал вопрос. Задача -- боевое тестривание (интеграционное) WCF сервиса.
Сгенерировал клиентов как положено и т.д. и т.п. Теперь просто хочу написать, по сути уже написал, небольшую программулину
для тестирования и организовал сл. образом: имеются классы сценариев (см. выше) и классы шагов (по сути обертки над функциями сервиса).
Ну и далее пишу сценарии из этих простейших шагов и валидирую результат. Вопрос был больше покритиковать мой подход, сценарии и шаги,
поделиться опытом. Наверняка кто-то с подобными задачами сталкивался.
A>Мне вот тоже непонятно что именно спрашивается. Если специализированный тул конкретно для сервисов, то причем тут C# и интерфейсы? Неужели специализированный тул будет заточен как раз под твои нужды?
Специализированный и обобщенный тул не нужен, только если посмотреть на сам подход к вопросу. Свой собственный тул уже написал.
A>А самое главное, почему бы не сгенерить клиента к этому сервису (как советует <b>.</b>
), а далее уже использовать любой из инструментов тестирования (а уж в них прикрутить IScenario и проч. не сставит труда).
Так и сделал.
A>Я именно так и тестирую свои сервисы. Только я не тестировал сам WCF сервис, я напрямую создавал объект сервиса в коде (благо WCF позволяет это) и вызывл его через его интерфейс.
Вы не могли бы подробнее? Т.е. Вы просто локально тестировали какой-то сервисный объект, без удаленного взаимодействия?
Здравствуйте, Sharov, Вы писали:
.>>Что ты ожидаешь от фреймворка? S>Очень виноват, т.к. некорректно сформулировал вопрос. Задача -- боевое тестривание (интеграционное) WCF сервиса. S>Сгенерировал клиентов как положено и т.д. и т.п. Теперь просто хочу написать, по сути уже написал, небольшую программулину S>для тестирования и организовал сл. образом: имеются классы сценариев (см. выше) и классы шагов (по сути обертки над функциями сервиса). S>Ну и далее пишу сценарии из этих простейших шагов и валидирую результат. Вопрос был больше покритиковать мой подход, сценарии и шаги, S>поделиться опытом. Наверняка кто-то с подобными задачами сталкивался.
Можно пример? Просто непонятно зачем тут эти интерфейсы, зачем вводить понятие "сценарий", "шаг" и т.п.? Чем обычный тест-кейс формата arrange/act/assert плох?
А ещё закрадывается подозрение, если без обёрток сервис использовать неудобно, значит что-то не то с его API.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ., Вы писали:
.>Можно пример? Просто непонятно зачем тут эти интерфейсы, зачем вводить понятие "сценарий", "шаг" и т.п.?
Я пишу сценарий, декорирую его атрибутом, выбираю все классы по этому атрибуту, инициализирую, привожу к интерфейсу
сценария и выполняю.
Сценарий выглядит как то так. На строковые константы внимание не обращайте.
[Scenario("User creation scenario.", Order = 1)]
public class CreateUserScenario : IScenario
{
private string _credentials;
private string _failDescription;
#region IScenario Members
public string FailDescription
{
get { return _failDescription; }
}
public bool Prepare()
{
_credentials = ScnHelper.GenerateTestUserCredentials();
return true;
}
public bool Execute()
{
using (Client Client = new Client())
{
var authorize = new AuthorizeUserStep(Client, "test","test").ExecuteStep();
if (!authorize)
{
_failDescription = "Execute stage. " + "Administrator is not properly authorized";
return false;
}
var create = new CreateUserStep(Client, _credentials, _credentials, false).ExecuteStep();
if (create < 1)
{
_failDescription = "Execute stage. " + "User was not created properly";
return false;
}
return true;
}
}
public bool Validate()
{
using (Client Client = new Client())
{
var authorize = new AuthorizeUserStep(Client, "test","test").ExecuteStep();
if (!authorize)
{
_failDescription = "Validate stage. " + " Administrator is not properly authorized";
return false;
}
var check = Utils.CheckUserStep(Client, _credentials, ref _failDescription);
if (!check)
{
_failDescription = "Validate stage. " + "Created user checking return false.";
return false;
}
return true;
}
}
public void Clean()
{
using (var Client = new Client())
{
var authorize = new AuthorizeUserStep(Client, "test", "test").ExecuteStep();
if (!authorize)
{
_failDescription = "Clean stage. " + "Administrator is not properly authorized";
return;
}
var result = new DeleteUserStep(Client, _credentials).ExecuteStep();
if (!result)
{
_failDescription = "Clean stage. " + "User was not deleted properly.";
}
}
}
#endregion
}
PS. Прощу прощения, а как вставлять скрытый текст? Чего-то не вижу такого форматирования...
), а далее уже использовать любой из инструментов тестирования (а уж в них прикрутить IScenario и проч. не сставит труда). S>Так и сделал.
Ну так подключай к нему BDD (фреймворков куча).
Почему BDD? Я, ес. честно, не видел более удобного способа описывать сценарии которые друг от друга отличаются на чуть-чуть (я про переиспользование уже написанного кода).
A>>Я именно так и тестирую свои сервисы. Только я не тестировал сам WCF сервис, я напрямую создавал объект сервиса в коде (благо WCF позволяет это) и вызывл его через его интерфейс. S>Вы не могли бы подробнее? Т.е. Вы просто локально тестировали какой-то сервисный объект, без удаленного взаимодействия?
Да, сервис мой, тест мой, задача была протестировать бизнесс сценарии, а не реализацию WCF в .net
Поэтому было принято решение вызвать сервис напрямую, а не хостить сервис и поключаться к нему клиентом.
Подробности:
Вот у нас есть Services.SomeService c интерфейсом Services.IService. Вместо того чтобы запускать реальный сервис и делать тестового клиента Tests.SomeServiceClient с интерфейсом Tests.IService и работы через Tests.IService, я напрямую создаю Services.SomeService и работаю через Services.IService
В плюсе скорость выполнения тестов и более простая инфраструктура, в минусе -- это не настоящий интеграционный тест (т.е. мой тест может пропустить баг из-за проблем в WCF).
Здравствуйте, Sharov, Вы писали: S>Здравствуйте, ., Вы писали: .>>Можно пример? Просто непонятно зачем тут эти интерфейсы, зачем вводить понятие "сценарий", "шаг" и т.п.? S>Я пишу сценарий, декорирую его атрибутом, выбираю все классы по этому атрибуту, инициализирую, привожу к интерфейсу S>сценария и выполняю.
Не понял. test framework не используешь? Я из java-мира, что там в c# плохо знаю что происходит, но вроде как есть, например, NUnit, там твоё хозяйство будет выглядить так:
[TestFixture]
public class UserTest
{
private Client Client;
[SetUp] public void SetUp()
{
Client = new Client();
string _credentials = ScnHelper.GenerateTestUserCredentials();
Assert.True(Client.authorize(_credentials));
}
[TearDown] public void TearDown()
{
Client.Destroy();
}
[Test] public void userCreation()
{
User user = Client.createUser("vasya", 1985);
Assert.AreEqual(user.GetName(), "vasya");
...
}
[ExpectedException(typeof(UserTooYoungException))]
[Test] public void userAnotherCreation()
{
User user = Client.createUser("vasenka", 2007);
...
}
}
А вот "new Something(...).ExecuteStep()" это трешъ и угаръ... S>PS. Прощу прощения, а как вставлять скрытый текст? Чего-то не вижу такого форматирования...
Так?
Вот так вроде
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ., Вы писали: .>Здравствуйте, Sharov, Вы писали: .>Не понял. test framework не используешь? Я из java-мира, что там в c# плохо знаю что происходит, но вроде как есть, например, NUnit, там твоё хозяйство будет выглядить так:
Я бы все-таки не стал смешивать юнит-тесты, которые в идеале должны быть
без side-effect'ов с интеграционными (боевое тестирование, жизненное).
Поэтому и написал свое решение. .>А вот "new Something(...).ExecuteStep()" это трешъ и угаръ...
Здравствуйте, Sharov, Вы писали:
.>>Не понял. test framework не используешь? Я из java-мира, что там в c# плохо знаю что происходит, но вроде как есть, например, NUnit, там твоё хозяйство будет выглядить так:
S>Я бы все-таки не стал смешивать юнит-тесты, которые в идеале должны быть S>без side-effect'ов с интеграционными (боевое тестирование, жизненное). S>Поэтому и написал свое решение.
Это заблуждение, что NUnit только для юнит-тестов. Просто набор тестов отделяется и их называют "интеграционные тесты", запуская их отдельно, т.к. они требуют внешнего окружения, типа СУБД, веб-серверов, етс. Код же выглядит точно так же. Зачем переизобретать велосипед?
BDD же нужен больше для больших проектов, чтобы сами сценарии можно было описывать естественным языком, для облегчения документирования и взаимодействия с бизнес-аналитиками и прочими непрограммистами.
.>>А вот "new Something(...).ExecuteStep()" это трешъ и угаръ... S>С чего бы?
Ну как бы тогда накой тут интерфейс, если точный тип известен в той же строке? Только ограничивает возможности, например, типы возвращаемого значения и т.п.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ., Вы писали:
.>Здравствуйте, Sharov, Вы писали:
.>Это заблуждение, что NUnit только для юнит-тестов. Просто набор тестов отделяется и их называют "интеграционные тесты", запуская их отдельно, т.к. они требуют внешнего окружения, типа СУБД, веб-серверов, етс. Код же выглядит точно так же. Зачем переизобретать велосипед?
Идея интересная, но все же есть свои минусы: в моем случае я вынес дополнительный настройки в UI,
я могу выбирать какие сценарии выполнять, последовательно или параллельно (т.е. создавать нагрузку),
контролирую сервис(перезапустить, приостановить и т.д.).
В случае юнит-тестов это не очень просто. Необходимо будет дублировать код: для разных настроек, по-разному сгруппированные сценарии,
последовательно или параллельно и т.д. Что-то изменить/добавить -- лезь в код, перекомпилируй. Тут же все не лету.
Велосипед не такой уж и большой.
.>BDD же нужен больше для больших проектов, чтобы сами сценарии можно было описывать естественным языком, для облегчения документирования и .>взаимодействия с бизнес-аналитиками и прочими непрограммистами.
Угу.
.>>>А вот "new Something(...).ExecuteStep()" это трешъ и угаръ... S>>С чего бы? .>Ну как бы тогда накой тут интерфейс, если точный тип известен в той же строке? Только ограничивает возможности, например, типы возвращаемого значения и т.п.
Вообще говоря, там интерфейс обощенный и возвращаемый типы зависят от шага -- где-то надо bool, где надо чей-то id для
последующей обработки.
internal interface IExecuteStep<out T> : IExecute
{
new T ExecuteStep();
}
internal interface IExecute
{
bool ExecuteStep();
}
Здравствуйте, Sharov, Вы писали:
S>Идея интересная, но все же есть свои минусы: в моем случае я вынес дополнительный настройки в UI, S>я могу выбирать какие сценарии выполнять, последовательно или параллельно (т.е. создавать нагрузку), S>контролирую сервис(перезапустить, приостановить и т.д.). S>В случае юнит-тестов это не очень просто. Необходимо будет дублировать код: для разных настроек, по-разному сгруппированные сценарии, S>последовательно или параллельно и т.д. Что-то изменить/добавить -- лезь в код, перекомпилируй. Тут же все не лету. S>Велосипед не такой уж и большой.
NUnit это фреймворк скорее для автоматических тестов. И юнит-тесты, и интеграционные тесты являются автоматическими тестами. А у тебя тут UI говоришь... как это автоматирировать-то? Может тебе не фреймворк нужен, а графическая среда разработки тестов?
Не знаю как там в ваших сишарпах, а IDE для Явы содержат UI для запуска тестов — что выполнять, параллельно ли выполнять, и с какими параметрами.
S>Вообще говоря, там интерфейс обощенный и возвращаемый типы зависят от шага -- где-то надо bool, где надо чей-то id для S>последующей обработки.
Это ладно. А зачем этот интерфейс-то нужен? Он же нигде не используется. Если в классе "CreateUserStep" убрать ": IExecuteStep" — что изменится?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ., Вы писали:
.>Здравствуйте, Sharov, Вы писали:
.>NUnit это фреймворк скорее для автоматических тестов. И юнит-тесты, и интеграционные тесты являются автоматическими тестами. А у тебя тут UI говоришь... как это автоматирировать-то? Может тебе не фреймворк нужен, а графическая среда разработки тестов?
Нет, нет, графическая не нужна. Нужно просто управлять сценариями, т.е. выкинуть какой-то сценарий и прогнать, или изменить последовательность
и прогнать заново, изменить тип протокола с tcp на http и снова прогнать. Как-то так.
Но вот идея использовать какой-нибудь тест-фреймворк довольно хороша, хотя не уверен, что воспользуюсь.
.>Это ладно. А зачем этот интерфейс-то нужен? Он же нигде не используется. Если в классе "CreateUserStep" убрать ": IExecuteStep" — что изменится?
Пока не очень нужен. В голове держал случай, когда, например, можно было бы загнать их все(шаги) в какой-нибудь список
и прогнать в цикле. Что-то типа уже предопределенной последовательности шагов.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, ., Вы писали:
.>>Здравствуйте, Sharov, Вы писали:
.>>NUnit это фреймворк скорее для автоматических тестов. И юнит-тесты, и интеграционные тесты являются автоматическими тестами. А у тебя тут UI говоришь... как это автоматирировать-то? Может тебе не фреймворк нужен, а графическая среда разработки тестов? S>Нет, нет, графическая не нужна. Нужно просто управлять сценариями, т.е. выкинуть какой-то сценарий и прогнать, или изменить последовательность S>и прогнать заново, изменить тип протокола с tcp на http и снова прогнать. Как-то так.
Думаю любой тестовый фреймворк это позволяет.
S>Но вот идея использовать какой-нибудь тест-фреймворк довольно хороша, хотя не уверен, что воспользуюсь.
Хм. А как же это соотносится с темой этого топика?
.>>Это ладно. А зачем этот интерфейс-то нужен? Он же нигде не используется. Если в классе "CreateUserStep" убрать ": IExecuteStep" — что изменится? S>Пока не очень нужен. В голове держал случай, когда, например, можно было бы загнать их все(шаги) в какой-нибудь список S>и прогнать в цикле. Что-то типа уже предопределенной последовательности шагов.
YAGNI...
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
S>>Но вот идея использовать какой-нибудь тест-фреймворк довольно хороша, хотя не уверен, что воспользуюсь. .>Хм. А как же это соотносится с темой этого топика?
Создание простенького своего или узнать о сущ. решениях. Я идею об использование юнит-тест фреймворков как-то сразу
отмел, т.к. имхо, идеологически неверно использовать для боевого тестирования, тем более сервиса. Да и есть ощущения, что кода
писать не меньше, да и гибкость не ахти. В собственном случае контроля больше.
Вот и спрашивал как народ обходиться. А народ, как я понял, просто пишет юнит-тесты и прогоняет либо локально, либо даже удаленно.
Здравствуйте, Sharov, Вы писали:
.>>Хм. А как же это соотносится с темой этого топика? S>Создание простенького своего или узнать о сущ. решениях. Я идею об использование юнит-тест фреймворков как-то сразу S>отмел, т.к. имхо, идеологически неверно использовать для боевого тестирования, тем более сервиса. Да и есть ощущения, что кода S>писать не меньше, да и гибкость не ахти. В собственном случае контроля больше. S>Вот и спрашивал как народ обходиться. А народ, как я понял, просто пишет юнит-тесты и прогоняет либо локально, либо даже удаленно.
NUnit это такая штука, которая позволяет автоматически запускать тучу тест-кейсов. Не понимаю что тут неидеологического. Разница юнит и инт тестов лишь в семантике. Запускалка работает точно так же.
Тест-фреймворки довольно гибкие. Не понимаю что тебе не хватает.
Кстати, они обычно предоставляют API для расширения, если и правда чего-то не хватит.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай