Я знаю, что об этом спрашивали довольно давно, но я думаю, что вы хотите, возможно, и, как я понимаю, есть несколько способов достичь этого. По сути, вам действительно нужно определить функцию один раз, но отключить шаги, которые вызываются для функции, в зависимости от того, вызываете ли вы внутреннюю службу, общедоступную веб-службу или WebApp. Обсуждаются различные подходы к решению этой проблемы в списке рассылки для specflow , но суть его заключается в следующем (пример демонстрирует подход API против пользовательского интерфейса, но то же самое относится к вашей внутренней или веб-службе против веб-приложение я считаю):
Вариант 1 #
(спасибо Оливеру Фридриху из списка рассылки)
вам нужно создать одну сборку для каждой опции, которую вы хотите изменить для шагов, одну для внутренней, одну для веб-службы и одну для веб-приложения. Вы говорите specflow обо всех различных сборках в конфигурации, например, так:
<specFlow>
<stepAssemblies>
<stepAssembly assembly="Tests.API" />
<stepAssembly assembly="Tests.UI" />
</stepAssemblies>
</specFlow>
тогда в ваших общих шагах тестирования у вас есть какой-то шаг [BeforeTestRun]
, который выбирает из какой сборки загружать шаги:
[Binding]
public class TestRunSetup {
// this method needs to be static
[BeforeTestRun]
public static void BeforeTestRun()
{
if (RunApiTests()) // <-- implement this method to choose whether to run the tests via your chosen method
{
Assembly.Load("Tests.API");
}
else
{
Assembly.Load("Tests.UI");
}
}
}
Вариант 2 ##
(спасибо Gáspár Nagy из списка рассылки)
Попробуйте сгенерировать тесты во время сборки . Я не уверен, как именно это будет работать, но это область, которую мы можем исследовать.
Вариант 3 ##
(спасибо Dan Mork из списка рассылки)
Если вы используете возможности внедрения зависимостей SpecFlow, вы можете создать интерфейс для выполнения вызовов, которые вы хотите сделать, и использовать это в общем наборе шагов. Затем вы можете иметь 3 реализации этого интерфейса: одну, которая вызывает вашу внутреннюю службу, другую, которая вызывает веб-службу, и другую, которая управляет веб-приложением. Осталось только вставить правильную реализацию этого интерфейса в файлы шагов specflow, что можно сделать так:
// the abstract concept of the system that could be implemented with
Selenium, HttpClient, etc.
public interface IDocument
{
string Title { get;}
void Load();
}
// the steps that are executed when the scenarios from your feature
file are executed
[Binding]
public class Steps
{
private readonly IDocument _document;
public Steps(IDocument document)
{
_document = document;
}
[Given("something")]
public void GivenSomething()
{
// set up given state
}
[When("I view the document")]
public void WhenIViewTheDocument()
{
_document.Load();
}
[Then(@"the title should be ""(.*)""")]
public void Then(string title)
{
Assert.ArEqual(_document.Title, title);
}
}
// this is where the magic happens - get the dependency injection
// container and register an IDocument implementation
[Binding]
public class Dependencies
{
private readonly IObjectContainer _objectContainer;
public Dependencies(IObjectContainer objectContainer)
{
_objectContainer = objectContainer;
}
[BeforeScenario]
public void RegisterDocumentInterfaces()
{
// register the correct IDocument implementation - UI or API
}
}
Это все еще оставляет вас с проблемой, как узнать, какие
Реализация для регистрации. Это будет зависеть от специфики вашего
решение, среда сборки, среда выполнения теста,
и т.д. Некоторые варианты для этого ...
- параметр тега для
BeforeScenarioAttribute
- создать две разные конфигурации сборки для вашего проекта, которые
каждый определяет разные константы и использует директивы прекомпилятора для
встроить правильные регистрации в код
- добавить условную логику для проверки переменной окружения
- добавить условную логику для проверки настроек конфигурации
- Я не проверял, но, возможно,
ScopeAttribute
расширяем для
вам создать подкласс и предоставить свою собственную логику для или нет
BeforeScenarioAttribute
метод выполняется.
Надеюсь, это даст вам несколько вариантов делать то, что вы хотите.
ИМХО первый вариант, вероятно, лучший, хотя вариант 3 тоже довольно приятный.