Всем привет. Давайте поговорим о BDD подходе в Java при использовании Webdriver'a. Кто, какие использует фреймворки и почему?
Предистория: Работаю с IDE - IDEA. Я испробовал несколько штукенций и вот какие вижу проблемы:
1) Если использовать Thucydidies то у проекта нет гибкости (хотелось бы немного другой отчет, хотелось бы управлять браузером и его запуском (профилем, настройками, расширениями), хотелось бы видеть TestNG и поддержку AfterSuite / BeforeSuite аннотаций, хотелось бы перехватывать результат выполнения сценария каким-нибудь AterMethod)
2) Попробовал использовать Cucumber - нет учета времени при выполнении шагов, нет все той же поддержки TestNG (Если использовать пример из документации, то тогда все тесты будут выполнятья в 1 методе и называться run, что не дает никакого представления о том в каком состоянии проект) и самое главное ХЗ как запустить тесты из Maven (Хотя А. Дзыне вроде тут помогли - https://groups.google.com/forum/?fromgroups=#!topic/cukes/1DSrCLkhXZo)
3) Попрообал Jbehave, все так же нет поддержки TestNG (хотя в документации заявлено, что можно, но у меня так и не вышло), нет никакой отчетности и наглядности, зато оно отлично запускаеся Maven"ом.
Итого, очень хочу иметь гибкость в проекте, использовать TestNG и BDD подход, при этом хочу запускать это все дело из Maven. Как быть? Как организованы тесты у вас?
Почему именно TestNG? JUnit из всех "свистелок" пока вроде как параллельное выполнение не поддерживает. А в остальном они практически идентичны. Хотя, вот для JBehave пример TestNG теста: https://github.com/jbehave/jbehave-core/blob/master/examples/trader-testng/src/main/java/org/jbehave/examples/trader/testng/TestNGTraderStories.java
Про отчетность и наглядность JBehave - это вы скорее всего недосмотрели. Для этого в конфигурации JBehave надо указать форматы вывода. Вот один из примеров:
public Configuration configuration() { return new MostUsefulConfiguration() .useStoryLoader(new JiraStoryLoader("SC-10")) .useStoryReporterBuilder( new StoryReporterBuilder() .withRelativeDirectory("") .withDefaultFormats() .withFormats(Format.CONSOLE, Format.TXT, Format.XML, Format.HTML)); }
Спасибо, по поводу отчетности, действительно недоглядел, буду пробовать. А вот по поводу примера - он не рабочий :) Попробуйте его запустить. Там есть импорт import org.jbehave.examples.trader.TraderStories; которого нет в пакете, а без этого файла не запускается.
TestNG потому что функциональных возможностей больше, например поддержка большего числа аннотаций и dataprovider (BeforeSuite, BeforeTest, BeforeMethod и тд.). А по поводу параллельного выполнения, я слышал что наоборот TestNG поддежирвает а Junit нет, но в данный момент мне это не важно, нет больших проектов.
А вот по поводу примера - он не рабочий :) Попробуйте его запустить. Там есть импорт import org.jbehave.examples.trader.TraderStories; которого нет в пакете, а без этого файла не запускается.
Его можно найти здесь: https://github.com/jbehave/jbehave-core/blob/master/examples/trader/src/main/java/org/jbehave/examples/trader/TraderStories.java . Там много всяких пакетов и для того, чтобы всё нормально запускалось, надо тянуть всё.
TestNG потому что функциональных возможностей больше, например поддержка большего числа аннотаций и dataprovider (BeforeSuite, BeforeTest, BeforeMethod и тд.).
Разного рода hooks есть в самом JBehave: http://jbehave.org/reference/stable/annotations.html (как раз те самые аналоги BeforeSuite, BeforeTest, BeforeMethod и тд.). TestNG DataProvider для JBehave не особо нужен. Посмотрите в сторону Examples в JBehave: http://jbehave.org/reference/stable/tabular-parameters.html (см. раздел Parametrized Tables ). Это по сути аналог DataProvider, с той разницей, что входные параметры вы задаете прямо в сценарии в качестве примеров (что в-общем-то и задумывалось)
А по поводу параллельного выполнения, я слышал что наоборот TestNG поддежирвает а Junit нет, но в данный момент мне это не важно, нет больших проектов.
Я про TestNG и говорил. Возможность параллельного запуска - это его фича, которая никак не представлена в JUnit. Все остальное - это разного рода "свистелки", просто представленные под разным соусом.
Круто, спасибо вам большое. Действительно не доглядел с отчетами, они формируются во вложенную папку target/jbehave/view я сначала не заметил их там, выглядят отлично и наглядно. И за аннотации тоже спасибо, это для меня было главным критерием, оказывается тоже не доглядел в документацию.
В целом, Jbehave пока доволен, вроде бы можно реализовать все что я задумал, отличный инструмент.
Осталось только найти как использовать русский язык и перехватывать результаты выполнения сценариев (чтобы работало снятие скриншота при падении).
У вас случайно примера не найдется? У меня не получилось, может я что-то не так делаю:
1) создал файл keywords_ru.properties.
2) добавил его в архив C:\Users\***\.m2\repository\org\jbehave\jbehave-core\3.7.5\
3) Добавил строчку Keywords keywords = new LocalizedKeywords(new Locale("ru")); в класс конфига.
Запускаю и получаю:
Resource bundle i18n/keywords not found for locale ru in classLoader ClassRealm[plugin>org.jbehave:jbehave-maven-plugin:3.7.5, parent: sun.misc.Launcher$AppClassLoader@5d91dd1d]: Can't find bundle for base name i18n/keywords, locale ru -> [Help 1]
Потом нашел пример тут http://jockeholm.wordpress.com/2010/01/25/localizing-jbehave-scenarios/ запустить не удалось.
Вы сами скинули ссылку на ответ на свой вопрос. Там же приведен пример инициализации поля keywords:
this.keywords = new I18nKeyWords( new Locale("sv", "SE"), new StringEncoder("ISO-8859-1", "ISO-8859-1"), "se/adaptiv/minesweeper/scenario/keywords", classLoader);
3-й параметр конструктора - тот самый путь, который вам надо указать к вашему файлу. В вашей реализации JBehave ищет в каталоге по умолчанию и естественно не находит. Попробуйте вот такую версию. Для отладки можете сначала использовать абсолютный путь к файлу настроек.
В последней версии Jbehave 3.7.5 нету класса I18nKeyWords и насколько я понял, его заменили на LocalizedKeywords; А вот альтернативу StringEncoder не могу найти :( кажется его совсем удалили. На всякий случай вот код:
/** * <p> * {@link Embeddable} class to run multiple textual stories via JUnit. * </p> * <p> * Stories are specified in classpath and correspondingly the {@link LoadFromClasspath} story loader is configured. * </p> */ public class StoryRunner extends JUnitStories {
public StoryRunner() { configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(true) .doIgnoreFailureInView(true).useThreads(2).useStoryTimeoutInSecs(60); }
private ClassLoader classLoader;
@Override public Configuration configuration() {
Keywords keywords = new LocalizedKeywords(new Locale("ru"));
keywords = new LocalizedKeywords (new Locale("ru", "RU"), new StringEncoder("ISO-8859-1", "ISO-8859-1"), "se/adaptiv/minesweeper/scenario/keywords", classLoader);
Class<? extends Embeddable> embeddableClass = this.getClass(); // Start from default ParameterConverters instance ParameterConverters parameterConverters = new ParameterConverters(); // factory to allow parameter conversion and loading from external resources (used by StoryParser too) ExamplesTableFactory examplesTableFactory = new ExamplesTableFactory(new LocalizedKeywords(), new LoadFromClasspath(embeddableClass), parameterConverters); // add custom converters parameterConverters.addConverters(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")), new ExamplesTableConverter(examplesTableFactory)); return new MostUsefulConfiguration() .useStoryLoader(new LoadFromClasspath(embeddableClass)) .useStoryParser(new RegexStoryParser(examplesTableFactory)) .useStoryReporterBuilder(new StoryReporterBuilder() .withCodeLocation(CodeLocations.codeLocationFromClass(embeddableClass)) .withDefaultFormats() .withFormats(CONSOLE, TXT, HTML, XML)) .useParameterConverters(parameterConverters); }
@Override public InjectableStepsFactory stepsFactory() { return new InstanceStepsFactory(configuration(), new MySteps()); }
@Override protected List<String> storyPaths() { return new StoryFinder().findPaths(codeLocationFromClass(this.getClass()), "**/*.story", "**/excluded*.story");
keywords = new LocalizedKeywords (new Locale("ru", "RU"), new StringEncoder("ISO-8859-1", "ISO-8859-1"), "se/adaptiv/minesweeper/scenario/keywords", classLoader);
3-й параметр - это путь. Он направлен на некоторый локальный каталог. Попробуйте его поменять на путь к вашему файлу.