Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SUREFIRE-1372 Filter tests to be rerun by description #150

Closed
wants to merge 2 commits into from
Closed

SUREFIRE-1372 Filter tests to be rerun by description #150

wants to merge 2 commits into from

Conversation

mpkorstanje
Copy link
Contributor

Filtering tests by the tuple of (Class, Method) does not work when a test
suite is used as a suite may not have (Class, Method) . Filtering by the
description of the failed test should however work.

Related Issues:

@mpkorstanje
Copy link
Contributor Author

This is still WIP until cucumber-jvm 2.0.0 is done.

@mpkorstanje mpkorstanje changed the title SUREFIRE-1372 Filter tests to be rerun by description [WIP] SUREFIRE-1372 Filter tests to be rerun by description May 26, 2017
@mpkorstanje mpkorstanje changed the title [WIP] SUREFIRE-1372 Filter tests to be rerun by description SUREFIRE-1372 Filter tests to be rerun by description Jul 29, 2017
@mpkorstanje
Copy link
Contributor Author

All done. Tests are running against cucumber-java:2.0.0-SNAPSHOT

@Tibor17
Copy link
Contributor

Tibor17 commented Jul 31, 2017

@mpkorstanje
You changed something in your code or what happened that snapshot was not available?
Is the release 2.0.0 coming soon?

@mpkorstanje
Copy link
Contributor Author

Yes! We're satisfied with the current state of the code and more people are now able to make releases. As such we're finalizing the release at the moment, I expect we'll do a couple of last minute bug fixes but that should be it. I can't make any promises about a time frame but I reckon it will be soon now.

@Tibor17
Copy link
Contributor

Tibor17 commented Jul 31, 2017

ok, take your time. No worries. Just rebase the PR after your team finished the release. Surefire need some week to make release as well.

@johnktims
Copy link

Cucumber 2.0.0 was released a few days ago.

</dependency>
</dependencies>

<repositories>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed.

* Re-run execution in Cucumber JVM

Since of 2.21 the provider <<<surefire-junit47>>> can rerun scenarios created by <<cucumber-jvm>>
2.0.0-SNAPSHOT and higher.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls change to 2.0.0 without SNAPSHOT.

<name>Test for rerun failing cucumber tests in JUnit 47</name>

<properties>
<cucumber.version>2.0.0-SNAPSHOT</cucumber.version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This too.

/**
* Only run test methods in the given input map, indexed by test class
*/
final class FailingMethodFilter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this can be removed. I have to check the algorithms of FailingMethodFilter and MatchMethodDescriptions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before deleting a class, tests with high coverage should be added and new implementation should pass on them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not really possible as as the way we're dealing selecting the tests to rerun has changed fundamentally. I have however added JUnit4ProviderUtilTest#testGenerateFailingTestDescriptions to show equivalence to JUnit4ProviderUtilTest#testGenerateFailingTests

This shows that the set of failed tests is the same as before - though described in a different format.

}
return description.toString();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here a new line should be added.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@Override
public boolean shouldRun( Description description )
{
for ( Filter filter : filters )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop is different from the deleted class but I need to have spare time to have deep looking.

Copy link
Contributor Author

@mpkorstanje mpkorstanje Sep 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MatchMethodDescriptions is created with a list of failed test descriptions. FailingMethodFilter was created with a list of failed class-method tuples.

When shouldRun is called the FailingMethodFilter would recurse down the description tree to find a leave (a test case). For each leave it uses the class of the description to find the set of failed methods for that class. Then it tests if the set of failed methods contain the method of the description. If so it returns true and the test should be rerun.

When shouldRun is called the MatchMethodDescriptions will check for each failed-test-description if it can be found in the the tree of descriptions. This is done by delegating the recursive descent search to Filter#matchMethodDescription. matchMethodDescription recurses until it finds a leave, when found it compares descriptions. When they match, the test should be rerun.

This should explain where the recursion has moved to.

@mpkorstanje
Copy link
Contributor Author

I'll try to address the minor changes soontm.

@Tibor17
Copy link
Contributor

Tibor17 commented Sep 12, 2017

@mpkorstanje
Currently we are cutting two versions. This week 2.20.1 and 2.21.0.Jigsaw next week having support with Jigsaw of Java 9.
This PR is planned in 2.20.2 but the version will be renamed to 2.21.1 in Jira having 3 fixes which should be fast release, and then 2.21.2 with one but big fix which removes 2 blockers. After this the plugins should be stable, I hope, and we can cut 3.0.0.M1 and we will break backwards compatibility in parameters and their properties.

@ckurban
Copy link

ckurban commented Oct 12, 2017

@Tibor17 whats ETA for this ?

@Tibor17
Copy link
Contributor

Tibor17 commented Oct 13, 2017

@ckurban
I could not release 2.21.0.Jigsaw because I was ill. It's not much work do to.

@sworisbreathing
Copy link

@Tibor17 have there been any updates for this? I'm pretty keen to start using the new version if it fixes support for Cucumber tests with rerunFailingTestCount in surefire/failsafe.

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 8, 2017

@sworisbreathing
Let me go through these changes again.

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 8, 2017

@mpkorstanje
@ckurban
@sworisbreathing
I could not merge and release this PR because the class FailingMethodFilter.java in [1] was deleted.
We have to have it back and find root cause and good cure.
I may have spare time during the weekend but this troubleshooting may take several days to understand the cure.
[1]: 780e878

@naveedriay
Copy link

Is it possible to ask the original developer (@mpkorstanje ) to look at this deleted file changes as it might help get it through quickly. I suppose quite a number of people are waiting for this fix to go in (including me)

@mpkorstanje
Copy link
Contributor Author

@Tibor17 would it help if I rebased this branch against master?

@mpkorstanje
Copy link
Contributor Author

@Tibor17 It appears this branch is still up to date with master.

Is the removal of the class the problem or the underlying fundamentals? If it is just the removal I can restore FailingMethodFilter.java. It went unused after my changes. If it is the underlying fundamentals please let me know how I can help you.

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 8, 2017 via email

</parent>

<artifactId>junit47-rerun-failing-tests-with-cucumber</artifactId>
<packaging>jar</packaging>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jar packaging is default one. You don't need to specify it.

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 10, 2017

@mpkorstanje
How is Description constructed now by Cucumber?
Does it contain the real method name or it is a scenario text?

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 10, 2017

@mpkorstanje
Additionally, can you write a separate documentation file cucumber.apt.vm for Cucumber with your best practices to setup and use cucumber in terms of maven-surefire-plugin and maven-failsafe-plugin tests, annotations like CucumberOptions, dependencies, versions, configuration if any, and re-run notices?
Take a notice that maven-failsafe-plugin has name or class *IT but maven-surefire-plugin has *Test.
The files in folder examples will show you how to cope with both plugins and alter the text.
The file cucumber.apt.vm should be located in maven-surefire-plugin/src/site/apt/examples.
And add the following to site.xml:
<item name="Cucumber and Surefire Recommendations" href="examples/cucumber.html"/>

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 10, 2017

@mpkorstanje
I want to ask you few question because I want to make minimum invasive changes in the code.
Why you have chosen provider surefire-junit47 and not also the surefire-junit4?
Why the method generateFailingTestDescriptions has to return Set<Description> and not the previous Map<Class<?>, Set<String>>?

@mpkorstanje
Copy link
Contributor Author

mpkorstanje commented Dec 23, 2017

@Tibor17 that should be doable. Replacing the inner most loop in the JUnit4Provider.executeWithRerun with the code below should do it. This would require the FilterFactory to be moved to another common module. I can't quite tell what the the nock-on effects of that would be.

for ( int i = 0; i < rerunFailingTestsCount && !failureListener.getAllFailures().isEmpty(); i++ )
{
    Set<Description> failures = generateFailingTestDescriptions( failureListener.getAllFailures() );
    failureListener.reset();
    FilterFactory filterFactory = new FilterFactory( testClassLoader );
    Filter failureDescriptionFilter = filterFactory.createMatchDescriptionsFilter( failures );
    Request.aClass( clazz ).filterWith( failingMethodsFilter ).getRunner().run( rerunNotifier );
}

 Filtering tests by the tuple of (Class, Method) does not work when a test
 suite is used as a suite may not have (Class, Method) . Filtering by the
 description of the failed test should however work.

 Related Issues:
 - cucumber/cucumber-jvm#1134
 - temyers/cucumber-jvm-parallel-plugin#31
@mpkorstanje
Copy link
Contributor Author

mpkorstanje commented Dec 23, 2017

Can you write the documentation?

Done.

Fix the checkstyle in your integration test and the classes FlakeCucumberTest.

I seem to be unable to get checkstyle to scan these tests and classes. I've visually checked these files.

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 23, 2017 via email

@mpkorstanje
Copy link
Contributor Author

@Tibor17

MatchDescriptions uses Filter.matchMethodDescription which does not exist in junit4. It would make the junit 4 version of MatchDescriptions divergent enough to duplicate its functionality.

I've added an extra commit onto this PR that shows just that.

@@ -55,7 +53,8 @@
import static java.lang.reflect.Modifier.isAbstract;
import static java.lang.reflect.Modifier.isInterface;
import static org.apache.maven.surefire.booter.CommandReader.getReader;
import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.generateFailingTests;
import static org.apache.maven.surefire.common.junit4.FilterFactory.createMatchDescriptionsFilter;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems we can move this method to JUnit4ProviderUtil and remove org.apache.maven.surefire.common.junit4.FilterFactory.

@Tibor17
Copy link
Contributor

Tibor17 commented Dec 24, 2017

@mpkorstanje
The build passed successfully. I will refactor little details, I will squash our commits and then I will push it to master.

I could not find a documentation for configuring annotation CucumberOptions. For instance we were using it like this @CucumberOptions(features = {"classpath:flake"}) in your previous commit. Why we do not use it any more and why it was important? Do you think it is important for the users and important for proper functionality of Surefire?

One more question I have is regarding artifacts of Cucumber. Which one is right to use:
<artifactId>cucumber-junit</artifactId>
<artifactId>cucumber-java8</artifactId>

@mpkorstanje
Copy link
Contributor Author

The build passed successfully. I will refactor little details, I will squash our commits and then I will push it to master.

Cheers.

I could not find a documentation for configuring annotation

I've changed the layout of the project to match the default used by cucumber. When using the default layout @CucumberOptions is not needed. Cucumber uses the location of the runner class to figure out where the features and glue are.

All in all @CucumberOptions influences which features are included but doesn't change how cucumber presents itself to surefire. From surefires perspective it should be yet another junit test suite.

One more question I have is regarding artifacts of Cucumber. Which one is right to use:

cucumber-junit provides integration with junit and should be used when junit is to be used. cucumber-java provides java annotations to denote step definitions. cucumber-java8 depends on cucumber-java and adds lambda based step definitions. Using cucumber-java is sufficient.

@mpkorstanje
Copy link
Contributor Author

Merged in 0a81c48.

@mpkorstanje mpkorstanje closed this Jan 4, 2018
@Tibor17
Copy link
Contributor

Tibor17 commented Jan 4, 2018

@mpkorstanje
Thx for contributing.

@mpkorstanje
Copy link
Contributor Author

You're welcome!

@kuppuswamynaiduh
Copy link

Hi Guys,

Thanks for helping us by contributing to the open source community...

I am using surefire 2.20.1 and getting the same exception "org.apache.maven.surefire.testset.TestSetFailedException: Unable to create test Class".

Could you please let me know if I should be waiting for the next version of surefire or am I missing something else here?

@mpkorstanje
Copy link
Contributor Author

Bit hard to say without the full stack trace, components and version numbers involved.

To fix this bug I also had to fix cucumber to ensure that the it provided the proper ids to Description.createSuiteDescription. The ids had to be unique in a single run but when a suite was recreated they had to be the same such as to satisfy the equals and hashcode method.

@kuppuswamynaiduh
Copy link

kuppuswamynaiduh commented Feb 2, 2018

Sorry for not giving enough information. the full track trace is here

org.apache.maven.surefire.testset.TestSetFailedException: Unable to create testclass 'rerun_test'
at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:387)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:293)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:239)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:160)
Caused by: java.lang.ClassNotFoundException: rerun_test
at org.apache.maven.surefire.junit4.JUnit4Provider.executeFailedMethod(JUnit4Provider.java:381)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:293)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:239)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:160)

where 'rerun_test' is the feature file name.

And the cucumber libraries used are 2.3.1 from group Id "io.cucumber" and cucumber-jvm-parallel-plugin version 4.2.0

@mpkorstanje
Copy link
Contributor Author

In that case yes, you only need to wait for the release of surefire. cucumber/cucumber-jvm#1120 was fixed by cucumber/cucumber-jvm#1134 and is part of cucumber-jvm 2.x.x.

@kuppuswamynaiduh
Copy link

Sure and let me wait!!!!!
Thank you so much for the updates!!!Cheers!!!!!

@Tibor17
Copy link
Contributor

Tibor17 commented Feb 4, 2018 via email

@Tibor17
Copy link
Contributor

Tibor17 commented Feb 4, 2018 via email

@mpkorstanje
Copy link
Contributor Author

mpkorstanje commented Feb 4, 2018

The path:

F:\jenkins\jenkins-slave\workspace\fire-pipeline_SUREFIRE-1463-5KZ5VLS45OW347227XHB7NPF5FLJFXODCMZF4ZDVYJEJZVION6UQ\build\surefire-integration-tests\target\TestMultipleMethodPatternsTestNGIT_shouldMatchSimpleClassNameAndMethodWithJavaExtWildcardPkg_testng-test

Contains 261 characters. MS allows for a maximum of 260 characters including the drive designation.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx

Assuming all the other parts of the path are not under your control you might want to shorten the method name a bit.

@adarshkv
Copy link

adarshkv commented Mar 23, 2018

Hi All.. with the new version of maven-surefire 2.21.0 and cucumber-jvm 2.4.0 (io.cucucmber)... we are able to perform rerun's successfully.

However, I am facing a new issue with regards to reporting... in our project we have integrated our reports with VSTS i.e. after I perform parallel execution (using docker container) all the reports are getting generated with TEST-.(*).xml and VSTS then consolidates all the .xml files to give us a single report after parallel execution. But in the XML the testcase names are missing i.e. we are not able to view each step definitions (step-step names Given When Then) rather I am seeing only the scenario name as a result.. is anyone aware why we are having this ? and how we can resolve this issue?

Below is my XML file if i am using info.cukes as group ID for execution (cucumber-jvm v 1.2.5) -- Rerun doesnt work here but test case name is available.

<property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
<property name="java.class.version" value="52.0"/>
** **

Below is the my XML file if I am using io.cucumber as group id for execution (cucumber-jvm v 2.4.0) --- Rerun works perfectly fine but testcase name is missing

<property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
<property name="java.class.version" value="52.0"/>


@mpkorstanje
Copy link
Contributor Author

It would appear that your XML snippets have been truncated.

Anyway. As of 2.x cucumber-jvm does not map steps to test cases by default (cucumber/cucumber-jvm#1159, cucumber/cucumber-jvm#1135). They don't properly map to JUnits concept of test cases. This results in odd behavior in various places. You can control this setting by providing the --step-notifications option or through @CucumberOptions(junit = "--no-step-notifications") .

@adarshkv
Copy link

@mpkorstanje -- Thank you.. I did try by providing @CucumberOptions(junit = "--no-step-notifications") . but no luck.. I need each step to be show in my report.

Please find below my runner file - Parallel01it.java (parallel execution)

@RunWith(Cucumber.class)
@CucumberOptions(
strict = true,
features = {"/Automation/WOW-Automation-Web/src/test/resources/features/TestScenario.feature:5"},
plugin = {"pretty", "junit:/Automation/Automation-Web/target/cucumber-parallel/1.xml", "html:/Automation/Automation-Web/target/cucumber-parallel/1", "json:/Automation/Automation-Web/target/cucumber-parallel/1.json", "rerun:/Automation/Automation-Web/target/cucumber-parallel/1.txt"},
junit = "--no-step-notifications",
monochrome = true,
glue = {"steps"})

Below is the my XML file if I am using io.cucumber as group id for execution (cucumber-jvm v 2.4.0) --- Rerun works perfectly fine but testcase name is missing

Below is what I am getting at present:

image

testcase name="Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" classname="Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="18.391"/>

Below is my XML file if i am using info.cukes as group ID for execution (cucumber-jvm v 1.2.5) -- Rerun doesnt work here but test case name is available.

testcase name="Given I am on the home page" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="When I click on Login Profile on home page" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="And I click on sign up in login page" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="Then I click on Sign Up" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="And I should see the valid message "The sign up was not successful." and "There are 6 field(s) that require your attention."" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="And I should see error message for first name "First name is required."" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0.008"/>
testcase name="And I should see error message for last name "Last name is required."" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="And I should see error message for email address "Email address is required."" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="And I should see error message for password "Password is required."" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="And I should see error message for preferred contact number "Phone number is required."" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="And I should see error message for delivery address "Address is required."" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="0"/>
testcase name="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" classname="Scenario: Sign Up Verify That Error Message Is Shown If Any Of The Mandatory Field Is Left Blank" time="1.288"/>

@mpkorstanje
Copy link
Contributor Author

Try @CucumberOptions(junit = "--step-notifications"). Forgot to remove the -no before copying.

@adarshkv
Copy link

Thanks a lot @mpkorstanje ... My issue is fixed with this change 👍

@adarshkv
Copy link

@mpkorstanje -- Any idea how we can embed screenshot to XML report (surefire-XML report ?)... At present I am attaching/ embedding the failed screenshot to html report.. but I want to embed the screenshot to surefire-maven XML report TEST.(.*).XML

@Tibor17
Copy link
Contributor

Tibor17 commented Mar 24, 2018 via email

@mpkorstanje
Copy link
Contributor Author

mpkorstanje commented Mar 24, 2018

The current surefire documentation references @CucumberOptions. I believe this to be sufficient. Any thing more would create a rather tight coupling between the documentation of Cucumber and Surefire.

Using --step-notifications will result in cucumber/cucumber-jvm#263 and cucumber/cucumber-jvm#577. So I also believe the current defaults to be correct.

Admittedly the documentation of @CucumberOptions could stand to be improved but this was covered in the release announcement for cucumber 2.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants