Это было намного проще, чем я думал.Для этого просто потребовалось изменить пару строк одного класса (Runtime.java), чтобы выяснить все методы ловушек и шагов.Все, что затем требовалось, это запустить в режиме dryrun, установленном в true, чтобы получить все подробности.
Переопределить поведение Runtime.java -
Загрузитькласс 1.2.5 по этой ссылке https://github.com/cucumber/cucumber-jvm/blob/v1.2.5/core/src/main/java/cucumber/runtime/Runtime.java
Создайте пакет cucumber.runtime в classpath и скопируйте в него класс Runtime.
3. В приватном методе runHooks (строка 209) закомментируйте строки 210 и 214.
private void runHooks(List<HookDefinition> hooks, Reporter reporter, Set<Tag> tags, boolean isBefore) {
//if (!runtimeOptions.isDryRun()) {
for (HookDefinition hook : hooks) {
runHookIfTagsMatch(hook, reporter, tags, isBefore);
}
//}
}
В приватном методе runHookIfTagsMatch (строка 217) добавьте строку 210 перед существующей строкой 224. В основном, если в режиме dryrun не выполнять ловушку.Блок try содержит этот код.
if(!runtimeOptions.isDryRun())
hook.execute(scenarioResult);
CustomFormatter - Теперь все подробности будут храниться в переменной ThreadLocal.
public class CustomFormatter implements Reporter, Formatter {
private Map<String, Map<Scenario, List<StepDefinitionMatch>>> featureDetails;
private Map<Scenario, List<StepDefinitionMatch>> scenarioDetails;
private List<StepDefinitionMatch> stepDetails;
private String featureUri = "";
private Scenario scenario;
private Map<Scenario, List<Match>> beforeHooks;
private Map<Scenario, List<Match>> afterHooks;
private List<Match> beforeMatches;
private List<Match> afterMatches;
public CustomFormatter() {
featureDetails = new LinkedHashMap<>();
beforeHooks = new LinkedHashMap<>();
afterHooks = new LinkedHashMap<>();
}
@Override
public void before(Match match, Result result) {
beforeMatches.add(match);
}
@Override
public void result(Result result) {
}
@Override
public void after(Match match, Result result) {
afterMatches.add(match);
}
@Override
public void match(Match match) {
//ThreadLocalStepDefinitionMatch.set((StepDefinitionMatch) match);
stepDetails.add((StepDefinitionMatch) match);
}
@Override
public void embedding(String mimeType, byte[] data) {
}
@Override
public void write(String text) {
}
@Override
public void syntaxError(String state, String event,
List<String> legalEvents, String uri, Integer line) {
}
@Override
public void uri(String uri) {
featureUri = uri;
}
@Override
public void feature(Feature feature) {
scenarioDetails = new LinkedHashMap<>();
}
@Override
public void scenarioOutline(ScenarioOutline scenarioOutline) {
}
@Override
public void examples(Examples examples) {
}
@Override
public void startOfScenarioLifeCycle(Scenario scenario) {
this.scenario = scenario;
stepDetails = new ArrayList<>();
beforeMatches = new ArrayList<>();
afterMatches = new ArrayList<>();
}
@Override
public void background(Background background) {
}
@Override
public void scenario(Scenario scenario) {
}
@Override
public void step(Step step) {
}
@Override
public void endOfScenarioLifeCycle(Scenario scenario) {
scenarioDetails.put(this.scenario, stepDetails);
beforeHooks.put(this.scenario, beforeMatches);
afterHooks.put(this.scenario, afterMatches);
}
@Override
public void done() {
}
@Override
public void close() {
/*System.out.println(featureDetails);
System.out.println(beforeHooks);
System.out.println(afterHooks);*/
StepHookDetails shd = new StepHookDetails(featureDetails, beforeHooks, afterHooks);
ThreadLocalStepHookDetails.set(shd);
}
@Override
public void eof() {
featureDetails.put(featureUri, scenarioDetails);
}
}
Если вы раскомментируете строки печати при закрытии() метод, вы можете увидеть результат примерно так.
Шаг Методы соответствия - Соответствует карте - Map<String, Map<Scenario, List<StepDefinitionMatch>>> featureDetails in CustomFormatter class
{src / test /resources / features / format2.feature = {gherkin.formatter.model.Scenario@38d8f54a= [cucumber.runtime.StepDefinitionMatch@6236eb5f, cucumber.runtime.StepDefinitionMatch@7c1e2a9e], gherkin.formatter.mo49. Cuc.runtime.StepDefinitionMatch@fa36558, cucumber.runtime.StepDefinitionMatch@672872e1]}}
до совпадений с крюком - соответствует карте - Map<Scenario, List<Match>> beforeHooks in CustomFormatter class
{gherkin.formatter.model.Scenario@38d8f54a= [gherkin.formatter.model.Match@32910148], gherkin.formatter.model.Scenario@49e53c76= [gherkin.formatter.model.Match@3f56875e]} *
после совпадений с крюком - - соответствует карте - Map<Scenario, List<Match>> afterHooks in CustomFormatter class
{gherkin.formatter.model.Scenario@38d8f54a= [gherkin.formatter.model.Match@2b4bac49], gherkin.formatter.model.Scenario@49e53c76= [gherkin.formatter.model.Match @ fd07cbb]}
Это для запуска одного файла функций, как показано ниже.Если у вас есть несколько файлов объектов, у вас будет несколько ключей функций на карте featureDetails
.Крючки будут добавлены к картам ловушек.
Feature: Validating sample Two
Background:
Given user gets count from "Car0"
@Format
Scenario: Scenario Two
And user gets count from "Car1"
@Format
Scenario: Scenario Two
And user gets count from "Car1"
Важно - Ключ, который связывает три вместе, является объектом Scenario
.Довольно просто перебрать карту featureDetails
и получить хук до, если он доступен, затем доступные шаги, а затем хук.Для получения имен методов ловушек используйте
Класс ThreadLocal -
public class ThreadLocalStepHookDetails {
private static final ThreadLocal<StepHookDetails> threadStepHookDetails = new InheritableThreadLocal<StepHookDetails>();
private ThreadLocalStepHookDetails() {
}
public static StepHookDetails get() {
return threadStepHookDetails.get();
}
public static void set(StepHookDetails match) {
threadStepHookDetails.set(match);
}
public static void remove() {
threadStepHookDetails.remove();
}
}
Класс StepHookDetails -
public class StepHookDetails {
private Map<String, Map<Scenario, List<StepDefinitionMatch>>> featureDetails;
private Map<Scenario, List<Match>> beforeHooks;
private Map<Scenario, List<Match>> afterHooks;
public StepHookDetails() {}
public StepHookDetails(
Map<String, Map<Scenario, List<StepDefinitionMatch>>> featureDetails,
Map<Scenario, List<Match>> beforeHooks,
Map<Scenario, List<Match>> afterHooks) {
this.featureDetails = featureDetails;
this.beforeHooks = beforeHooks;
this.afterHooks = afterHooks;
}
public Map<String, Map<Scenario, List<StepDefinitionMatch>>> getFeatureDetails() {
return featureDetails;
}
public void setFeatureDetails(
Map<String, Map<Scenario, List<StepDefinitionMatch>>> featureDetails) {
this.featureDetails = featureDetails;
}
public Map<Scenario, List<Match>> getBeforeHooks() {
return beforeHooks;
}
public void setBeforeHooks(Map<Scenario, List<Match>> beforeHooks) {
this.beforeHooks = beforeHooks;
}
public Map<Scenario, List<Match>> getAfterHooks() {
return afterHooks;
}
public void setAfterHooks(Map<Scenario, List<Match>> afterHooks) {
this.afterHooks = afterHooks;
}
}
Проверьте детали в магазине -
Вы можете использовать приведенный ниже код в качестве образца, чтобы увидеть детали внутри карт и в порядке.т. е. перед шагами после.
StepHookDetails sd = ThreadLocalStepHookDetails.get();
sd.getFeatureDetails().entrySet().stream().forEach(
e -> e.getValue().entrySet().stream().forEach(
ee -> {
System.out.println(ee.getKey().getLine());
sd.getBeforeHooks().get(ee.getKey()).stream().forEach(bh -> System.out.println(bh.getLocation()));
ee.getValue().stream().forEach(s -> System.out.println(s.getLocation() + " " + s.getArguments()));
sd.getAfterHooks().get(ee.getKey()).stream().forEach(ah -> System.out.println(ah.getLocation()));
}));
Для вышеуказанного файла функций получен этот вывод
Сценарий Строка № 8 До перехвата SampleSteps.before () Шаги SampleSteps.userGetsCountFromAndStores (String) [Car0] Шаги SampleSteps.userGetsCountFromAndStores (String) [Car1] После хука SampleSteps.afterOne (Scenario) Сценарий Строка № 15 перед хуком] After Hook SampleSteps.afterOne (Сценарий)
Это также будет работать для контуров сценария.
ОБНОВЛЕНО -
Feature: UI Automation
@P1
Scenario: Validate_Home_page
Given the customer opens launches the homepage
@Given("^the customer opens launches the homepage$")
public void openbrowser() { }
public static void main (String args[]) throws IOException {
String[] argv = new String[] { "-g", "cucumpar.test.stepdefs", "src/test/resources/features/features.feature",
"-t", "@P1" , "-p", "cusform.CustomFormatter","-d"};
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
byte exitstatus = Main.run(argv, contextClassLoader);
----------------
StepHookDetails sd = ThreadLocalStepHookDetails.get();
----------------
}
Результаты
{src/test/resources/features/features.feature= enjgherkin.formatter.model.Scenario@6771beb3=[cucumber.runtime.StepDefinitionMatch@51399530]}} {gherkin.formatter.model.Scenario@6771beb3= []} {gher.formatter.model.Scenario@6771beb3= []} Строка сценария № 4 Шаги SampleSteps.openbrowser () []
ОБНОВЛЕНО
Необходимо добавить некоторый код в класс StepDefinitionMatch.Аналогично тому, что вы сделали для Runtime.java, скачайте класс 1.2.5 по адресу - https://github.com/cucumber/cucumber-jvm/blob/v1.2.5/core/src/main/java/cucumber/runtime/StepDefinitionMatch.java. Скопируйте этот класс в существующий пакет cucumber.runtime.Затем добавьте следующий метод -
public List<List<String>> getDataTableData() {
List<List<String>> data = new ArrayList<>();
if(step.getRows()!=null)
step.getRows().forEach(row -> data.add(row.getCells()));
return data;
}
Вот и все.Вызовите этот метод в существующем методе печати, как показано ниже.
ee.getValue().stream().forEach(s -> System.out.println("Steps " + s.getLocation() + " " + s.getArguments() + " " + s.getDataTableData()));
Для этого файла функций
Scenario: Scenario Four
And car gets count
| car | owner |
| Car1 | OwnerOne |
| Car2 | OwnerTwo |
| Car3 | OwnerThree |
Получите этот вывод - Первая строка - это заголовок, настройте по необходимости.
SampleSteps.carGetsCount (DataTable) [] [[car, owner], [Car1, OwnerOne], [Car2, OwnerTwo], [Car3, OwnerThree]]
ОБНОВЛЕНИЕ
public Map<String, List<String>> getDataTableData() {
Map<String, List<String>> mapData = new HashMap<>();
if(step.getRows()!=null) {
List<List<String>> data = new ArrayList<>();
step.getRows().forEach(row -> data.add(row.getCells()));
List<String> keys = data.remove(0);
data.stream().forEach(row -> IntStream.range(0, keys.size()).forEach(index -> {
List<String> tempList = new ArrayList<>();
tempList.add(row.get(index));
mapData.compute(keys.get(index), (key, val) -> {
if(val==null)
return tempList;
val.addAll(tempList);
return val;
});
}));
}
return mapData;
}