Оригинал
Driving Web Behaviour
Selenium является мощным инструментом с открытым исходным кодом для автоматизированного тестирования web-приложений. С версии 2.x, он предлагает на выбор два API: API Selenium (обратная совместимость с 1.x) и новый WebDriver API. JBehave поддерживает оба. Когда мы говорим о Selenium, мы обычно подразумеваем сам фреймворк, а если нужно различать API, мы специально обратимся к API и Selenium WebDriver API.
Давайте посмотрим, как мы можем легко использовать Selenium для запуска "веб-историй". Целью создания DSL является представление бизнес-функциональности домена в то же время абстрагируясь от деталей реализации, в этом случае доступ к веб-слою осуществляется с помощью специального инструмента тестирования, такого как Selenium. То же самое DSL должно иметь возможность повторного использования с другими инструментами тестирования.
Как обычно, примеры говорят громче, чем слова:
Scenario: User searches for a single stepGiven user is on Home pageWhen user opens Find Steps pageThen Find Steps page is shownWhen user searches for "Given a threshold of 10.0"Then search returns: "Given a threshold of $threshold"When user views with methodsThen search returns: "Given a threshold of $threshold, [org.jbehave.web.examples.trader.steps.TraderSteps.aThreshold(double)]"And steps instances include: "TraderSteps,StockExchangeSteps"public class TraderWebSteps { private final Pages pages; public TraderWebSteps(Pages pages) { this.pages = pages; } @Given("user is on Home page") public void userIsOnHomePage(){ pages.home().open(); } @When("user opens Find Steps page") public void userClicksOnFindSteps(){ pages.findSteps().open(); } @Then("Find Steps page is shown") public void findStepsPageIsShown(){ pages.findSteps().pageIsShown(); } @When("user searches for \"$step\"") public void userSearchesForSteps(String step){ pages.findSteps().find(step); } @Then("search returns: \"$stepsOrMethods\"") public void stepsFound(List<String> stepsOrMethods){ pages.findSteps().found(stepsOrMethods); } @Then("steps instances include: \"$names\"") public void stepsInstancesFound(List<String> names){ pages.findSteps().found(names); }} |
Настройка JBehave для использования Selenium
Как всегда, мы настроим JBehave несколькими различными способами. Один из способов, это иметь встраиваемый запускаемый класс, то есть JUnit-запускаемый класс TraderWebStories. Здесь в игру вступает выбор API.Использование Selenium API
public class TraderWebStories extends JUnitStories { private Selenium selenium = SeleniumConfiguration.defaultSelenium(); private ConditionRunner conditionRunner = SeleniumConfiguration.defaultConditionRunner(selenium); private Pages pages = new Pages(selenium, conditionRunner); private SeleniumSteps lifecycleSteps = new PerStorySeleniumSteps(selenium); private SeleniumContext seleniumContext = new SeleniumContext(); @Override public Configuration configuration() { Class<? extends Embeddable> embeddableClass = this.getClass(); return new SeleniumConfiguration() .useSelenium(selenium) .useSeleniumContext(seleniumContext) .useStepMonitor(new SeleniumStepMonitor(selenium, seleniumContext, new SilentStepMonitor())) .useStoryLoader(new LoadFromClasspath(embeddableClass)) .useStoryReporterBuilder(new StoryReporterBuilder() .withCodeLocation(codeLocationFromClass(embeddableClass)) .withDefaultFormats() .withFormats(CONSOLE, TXT, HTML, XML)); } @Override public InjectableStepsFactory stepsFactory() { return new InstanceStepsFactory(configuration(), new TraderWebSteps(pages), lifecycleSteps, new SeleniumScreenshotOnFailure(selenium)); } @Override protected List<String> storyPaths() { return new StoryFinder() .findPaths(codeLocationFromClass(this.getClass()).getFile(), asList("**/*.story"), null); }} |
Использование API WebDriver
public class TraderWebStories extends JUnitStories { private WebDriverProvider driverProvider = new PropertyWebDriverProvider(); private WebDriverSteps lifecycleSteps = new PerStoriesWebDriverSteps(driverProvider); // or PerStoryWebDriverSteps(driverProvider) private Pages pages = new Pages(driverProvider); private SeleniumContext context = new SeleniumContext(); private ContextView contextView = new LocalFrameContextView().sized(500, 100); public TraderWebStories() { // If configuring lifecycle per-stories, you need to ensure that you a same-thread executor if ( lifecycleSteps instanceof PerStoriesWebDriverSteps ){ configuredEmbedder().useExecutorService(MoreExecutors.sameThreadExecutor()); } } @Override public Configuration configuration() { Class<? extends Embeddable> embeddableClass = this.getClass(); return new SeleniumConfiguration() .useSeleniumContext(context) .useWebDriverProvider(driverProvider) .useStepMonitor(new SeleniumStepMonitor(contextView, context, new SilentStepMonitor())) .useStoryLoader(new LoadFromClasspath(embeddableClass)) .useStoryReporterBuilder(new StoryReporterBuilder() .withCodeLocation(codeLocationFromClass(embeddableClass)) .withDefaultFormats() .withFormats(CONSOLE, TXT, HTML, XML)); } @Override public InjectableStepsFactory stepsFactory() { Configuration configuration = configuration(); return new InstanceStepsFactory(configuration, new TraderWebSteps(pages), lifecycleSteps, new WebDriverScreenshotOnFailure(driverProvider, configuration.storyReporterBuilder())); } @Override protected List<String> storyPaths() { return new StoryFinder() .findPaths(codeLocationFromClass(this.getClass()).getFile(), asList("**/*.story"), null); } // This Embedder is used by Maven or Ant and it will override anything set in the constructor public static class SameThreadEmbedder extends Embedder { public SameThreadEmbedder() { useExecutorService(MoreExecutors.sameThreadExecutor()); } }} |
Жизненный цикл шагов
JBehave интеграции с Selenium и WebDriver API, направлена на выполнение общих задач. Среди них одна из самых распространенных является управление жизненным циклом, например, запуском и остановкой браузера.JBehave предусматривает три типа управления жизненным циклом:
- Через истории: через PerStoriesSeleniumSteps или PerStoriesWebDriverSteps .
- Через историю: через PerStorySeleniumSteps или PerStoryWebDriverSteps .
- Через сценарий: через PerScenarioSeleniumSteps или PerScenarioWebDriverSteps .