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

Should work for cucumber scenario outlines #83

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

alexmsmartins
Copy link

@alexmsmartins alexmsmartins commented May 8, 2018

Problem

Cucumber tests with Data Tables will pass with failing examples as long as the first example passes.

This happens because all the examples in have the same fully qualified name that comes from the scenario outline description.

The changes

This Pr simply allows for tests with equal names to pass through from the JUnit RunNotifier to the SBT EventHandler without repeats being filtered out.

The first commit in this test is a passing build that should have failed and the second commit is the fix.

@alexmsmartins
Copy link
Author

I already signed the CLA.

@benmccann
Copy link
Contributor

Hey @alexmsmartins, I was the primary maintainer of this repo for the past several years. I no longer use SBT much because my company was acquired by a company that uses Gradle. We should find someone at Lightbend to take over this repo and review your PR. I'll let you drive that since you're probably more motivated to get this change in

A couple places you might try:

@dwijnand @jsuereth would you be able to help find a new maintainer for this repo?

@alexmsmartins
Copy link
Author

alexmsmartins commented Aug 16, 2018

Hi @benmccann , @dwijnand and @jsuereth

Is it possible to just get merge permissions?

That should get things going because, in my team, we keep getting bitten by this problem where scenarios with the same name that pass basically stop failing scenarios with the same name in other files from failing the build. And the fix in this PR does solve that problem.

While you don't get a new maintainer, I could just push things forward a bit.

@benmccann
Copy link
Contributor

@szeiger perhaps you could help review this PR?

@alexmsmartins do you mind rebasing this PR? sorry I know it's quite old

@SethTisue
Copy link
Member

SethTisue commented Jan 30, 2020

I'll add one more possible name on here: @eed3si9n

@eed3si9n
Copy link
Member

I'd be happy to review and get this to finish line.

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2015, Michael Lewis
* All rights reserved.
Copy link
Member

Choose a reason for hiding this comment

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

This seems problematic. If we're doing Lightbend CLA the copy right needs to transfer to Lightbend.

@eed3si9n
Copy link
Member

This happens because all the examples in have the same fully qualified name that comes from the scenario outline description.

I don't know anything about Cucumber, but this sounds like their bug? I feel uneasy compromising the overall contract of testframework for all junit-interface users just to workaround Cucumber bug/oddity.

@gaeljw
Copy link

gaeljw commented Apr 14, 2020

This happens because all the examples in have the same fully qualified name that comes from the scenario outline description.

I don't know anything about Cucumber, but this sounds like their bug? I feel uneasy compromising the overall contract of testframework for all junit-interface users just to workaround Cucumber bug/oddity.

IMHO It doesn't feel like a bug in Cucumber, the same case works absolutely fine in Scala+Maven.
You can see the issue I just created this morning and two project samples (one with sbt, one with Maven). cucumber/cucumber-jvm-scala#22

@mpkorstanje
Copy link

mpkorstanje commented Apr 14, 2020

@eed3si9n

I don't know anything about Cucumber, but this sounds like their bug? I feel uneasy compromising the overall contract of testframework for all junit-interface users just to workaround Cucumber bug/oddity.

JUnit uses the Description object to determine the identity of tests. Internally Description implements equals and hashcode by delegating to Serializable uniqueId.

Cucumber is currently using Description.createTestDescription(String className, String name, Serializable uniqueId) to create descriptions for each example. While the class name and name may not be unique, the unique id is.

So rather then depending on the class and method name to determine test identity the Description.equals() and Description.hashcode() method should be be used.

"org.scalatest" %% "scalatest" % "3.0.1" % "test",
"io.cucumber" % "cucumber-core" % "2.0.0" % "test",
"io.cucumber" %% "cucumber-scala" % "2.0.0" % "test",
"io.cucumber" % "cucumber-jvm" % "2.0.0" % "test",

Choose a reason for hiding this comment

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

This is a pom dependency and not required.


libraryDependencies ++= Seq (
"org.scalatest" %% "scalatest" % "3.0.1" % "test",
"io.cucumber" % "cucumber-core" % "2.0.0" % "test",

Choose a reason for hiding this comment

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

This is a transitive dependency of cucumber-scala and not required.

libraryDependencies ++= Seq (
"org.scalatest" %% "scalatest" % "3.0.1" % "test",
"io.cucumber" % "cucumber-core" % "2.0.0" % "test",
"io.cucumber" %% "cucumber-scala" % "2.0.0" % "test",
Copy link

@mpkorstanje mpkorstanje Apr 14, 2020

Choose a reason for hiding this comment

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

private void postIfFirst(AbstractEvent e)
{
e.logTo(logger);
if(reported.add(e.fullyQualifiedName())) handler.handle(e);

Choose a reason for hiding this comment

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

reported now goes unused.

Copy link
Member

Choose a reason for hiding this comment

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

AbstractEvent should probably expose Description, and reported should use the description's identity to track whether the event has been posted or not.

@eed3si9n
Copy link
Member

JUnit uses the Description object to determine the identity of tests.

Thanks for the explanation. I guess the impedance mismatch here is that junit-interface (and sbt test frameworks in general) tries to lookup tests using a mechanism called fingerprint and it's either SubclassFingerprint or AnnotatedFingerprint. In case of the example used in this PR, I'm guessing that org.junit.runner.RunWith annotation fingerprint would picked up cucumber.CucumberApplicationSpec:

package cucumber

import cucumber.api.CucumberOptions
import cucumber.api.junit.Cucumber
import org.junit.runner.RunWith

@RunWith(classOf[Cucumber])
@CucumberOptions(
  features = Array("classpath:features"),
  glue = Array("com.waioeka.sbt"),
  strict = true,
)
class CucumberApplicationSpec

sbt would then send back the task definition for cucumber.CucumberApplicationSpec back to the runner exposed by junit-interface. sbt on the other end would be listening to the events for it.

So rather than depending on the class and method name to determine test identity the Description.equals() and Description.hashcode() method should be be used.

That makes sense. Currently it's testing for if(reported.add(e.fullyQualifiedName())), but reported should keep track of Description's identity instead.

@gaeljw
Copy link

gaeljw commented Jul 9, 2020

✔️ For anyone coming here, please note that starting from version 6.2.2 cucumber-junit now adds a unique number to workaround this issue (see cucumber/cucumber-jvm#2045).

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.

None yet

6 participants