prashant-ramcharan / courgette-jvm

Multiprocess | Parallel Cucumber-JVM | Parallelize your Java Cucumber tests on a feature level or on a scenario level.
MIT License
133 stars 39 forks source link

No feature information in hooks #33

Closed clicman closed 6 years ago

clicman commented 6 years ago

In classic cucumber runner, I can access current Feature object via Scenario instance in a @before hook. With courgette the Scenario.reporter field is null I want to get current feature name and its lang iso code at runtime. Is it possible to implement?

prashant-ramcharan commented 6 years ago

Scenario.reporter is a private field, so this value is not accessible anyway: refer to Cucumber code here

Are you using reflection to access this?

What you need to use is:

    @Before
    public void before(Scenario scenario) {
        scenario.getName(); // This will print the scenario name

        scenario.getId(); // This will print the "feature name; scenario name; id"
    }

Note: Courgette does not change any of Cucumber's source code

clicman commented 6 years ago

Yes, I'm using reflection. There is the only way to access feature lang iso code.

prashant-ramcharan commented 6 years ago

Courgette re-creates its own runtime options for each feature / scenario so this is why Cucumber's runtime options (reporter) is null. We do not have access to the JUnit report when running in a multi-threaded session.

Why don't you write a custom library that reads the feature file and extract the ISO code? This can be put into an after hook?

# language: fr

If you need additional properties, then you can then use this:

final String language = "fr";

final String isoCode = I18n.getAll().stream().map(I18n::getIsoCode).filter(dialect -> dialect.equalsIgnoreCase(language)).findFirst().orElseThrow(() -> new RuntimeException("Unable to find ISO code using this language"));

I18n.getAll().stream().filter(t -> t.getIsoCode().equalsIgnoreCase(isoCode)).findFirst().get();

This will give you access to this.

screen shot 2018-03-29 at 13 57 20

clicman commented 6 years ago

Because I need to know language before scenario execution. As I can see it is possible to pass via system property to cli execution. Will you accept such PR?

Отправлено с iPhone

29 марта 2018 г., в 19:58, Prashant Ramcharan notifications@github.com написал(а):

Courgette re-creates its own runtime options for each feature / scenario so this is why Cucumber's runtime options (reporter) is null. We do not have access to the JUnit report when running in a multi-threaded session.

Why don't you write a custom library that reads the feature file and extract the ISO code? This can be put into an after hook?

language: fr

If you need additional properties, then you can then use this:

final String language = "fr";

final String isoCode = I18n.getAll().stream().map(I18n::getIsoCode).filter(dialect -> dialect.equalsIgnoreCase(language)).findFirst().orElseThrow(() -> new RuntimeException("Unable to find ISO code using this language"));

I18n.getAll().stream().filter(t -> t.getIsoCode().equalsIgnoreCase(isoCode)).findFirst().get(); This will give you access to this.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

prashant-ramcharan commented 6 years ago

The CLI will only List keywords for in a particular language and exit. It will not tell you the ISO code for a feature file.

Passing --i18n system property to Courgette or the Cucumber CLI will simply exit the JVM, it will not continue with any test execution.

Please look here

clicman commented 6 years ago

No. Just put it as system property passed to startup command

Отправлено с iPhone

29 марта 2018 г., в 22:11, Prashant Ramcharan notifications@github.com написал(а):

The CLI will only List keywords for in a particular language and exit. It will not tell you the ISO code for a feature file.

Passing --i18n system property to Courgette or the Cucumber CLI will simply exit the JVM, it will not continue with any test execution.

Please look here

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

clicman commented 6 years ago

as I see it can be passed like in https://github.com/prashant-ramcharan/courgette-jvm/commit/14f97d9b547cb822430343c9ba4b6a2af2eb1b7e as additional -DfeatureName -DfeatureIsoCode

PrashantRiverIsland commented 6 years ago

I understand what you mean now.

This functionality already exists. Courgette passes in all system properties to the CLI by default.

The important step is to import the system properties from the gradle task. Without this, the JVM will not be aware of the property.

task runTest(type: Test) {
   systemProperties = System.getProperties() // this ensures all provided system props are available to the JVM

   include '**/CourgetteRunner.class'

   outputs.upToDateWhen { false }
}
gradle runTest -Dname=foo

System.getProperty(“name”) will be available to Courgette which then passes it to the CLI.

clicman commented 6 years ago

Yes, but it isn't possible to determine which feature runs for the current scenario from outside. And the idea is to pass it on cli command build.

clicman commented 6 years ago

@kosteman FYI

prashant-ramcharan commented 6 years ago

Courgette-JVM does not have it own CLI.

You cannot use this from the command line like you would do with Cucumber. This does not exist!

Courgette simply uses Cucumber CLI. So whatever system property you provide to Courgette at runtime is passed to Cucumber CLI.

There’s no way around this, unfortunately.

clicman commented 6 years ago

Could I try to implement it and send you PR?

prashant-ramcharan commented 6 years ago

Sure

prashant-ramcharan commented 6 years ago

But just passing a system property as you previously described already exists by default and it’s not the solution to your issue.

prashant-ramcharan commented 6 years ago

Please write a test as well. Thanks

clicman commented 6 years ago

https://github.com/prashant-ramcharan/courgette-jvm/pull/35

prashant-ramcharan commented 6 years ago

Thanks for the PR @clicman

I think there is very little benefit in exposing CucumberFeature fields as system properties. I know it might solve your immediate problem but its not in keeping with the open close principle.

Cucumber limits the access to these objects for a reason and Courgette follows the same principles.

Having said that, you can still use Gherkin parser to get the I18N language.

I added a solution here courgette-jvm-example-github-issue-33 Please clone branch /github-issue-33 and run.

Code that validates this is here

Code that get the I18N language is here

The only caveat is that the "Feature:" tag in the feature file MUST match the feature filename.

clicman commented 6 years ago

Thank you for example, but filename limitation doesn't satisfy our requirements. So I'll think more about it.

prashant-ramcharan commented 6 years ago

Ok sure 👍

If we explicitly set custom system properties from Courgette then we will be enforcing these rules to all users.

By that I mean, if I were to specify -DfeatureName or -DfeatureIsoCode with a value of my own, then Courgette will ignore my value and use the one specified in the library.

At present, Courgette only accepts user provided system properties. It does not, and should not set its own custom system properties from within the library.

I'll close this issue for now.

prashant-ramcharan commented 6 years ago

Hi @clicman

I've upgraded Courgette-JVM to 2.0.0.

This now uses Cucumber-JVM 2.4.0 and Gherkin 5. With this, the scenario object is updated.

So you can get the feature info using Gherkin including the language

    private Feature getFeature(Scenario scenario) throws FileNotFoundException {
        Parser<GherkinDocument> parser = new Parser<>(new AstBuilder());

        TokenMatcher matcher = new TokenMatcher();

        return parser.parse(new FileReader(scenario.getUri()), matcher).getFeature();
    }
clicman commented 6 years ago

great! Thank you! Better approach to access feature is like in: https://github.com/sbtqa/qa-utils/blob/master/src/main/java/ru/sbtqa/tag/qautils/cucumber/CucumberUtils.java