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

Add extension to disable per test name to be able to disable parameterized tests #175

Merged
merged 23 commits into from
Jun 20, 2020

Conversation

nishant-vashisth
Copy link
Contributor

@nishant-vashisth nishant-vashisth commented Feb 19, 2020

Additional extension to be able to skip tests based on test name
This is particularly helpful when dealing with Parameterized or Dynamically Registered tests

#163


I hereby agree to the terms of the JUnit Pioneer Contributor License Agreement.

@nipafx
Copy link
Member

nipafx commented Mar 3, 2020

Sorry @nishantvas, I didn't have time to look at this and I'm pretty busy the next weeks. I will get to it eventually, I promise! :)

@nishant-vashisth
Copy link
Contributor Author

I didn't really add this to be merged (yet) it was more to indicate the Idea I was trying to indicate with my Issue

@nipafx
Copy link
Member

nipafx commented Mar 26, 2020

Hey @nishantvas, this is a pretty cool proof-of-concept! I wasn't aware that the conditional extension is executed for each parameterized test run - very clever to make use of that and the test display name. 👍 Keep working on it, it is definitely going into the right direction.

Copy link
Member

@nipafx nipafx left a comment

Choose a reason for hiding this comment

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

Just a quick comment. Let me know when you fleshed it out and are interested in a detailed review.

@nipafx
Copy link
Member

nipafx commented Mar 26, 2020

Of course we still need examples, documentation, and commit message. In case you prefer only writing the code, that's ok as well, just let me know.

@nipafx
Copy link
Member

nipafx commented Mar 26, 2020

One more note, should it be @DisableIfDisplayName?

@Bukama
Copy link
Member

Bukama commented Mar 26, 2020

One more note, should it be @DisableIfDisplayName?

I vote for this so it's clear by the annotation name that the display name is taken into account and not the "coded name"

@Bukama
Copy link
Member

Bukama commented Mar 26, 2020

Of course we still need examples, documentation, and commit message. In case you prefer only writing the code, that's ok as well, just let me know.

Want to add Javadoc at least for the annotation interface

@nishant-vashisth
Copy link
Contributor Author

nishant-vashisth commented Mar 26, 2020

One more note, should it be @DisableIfDisplayName?

Sure, makes sense and is more readable.

I can also work on finalising this(the code is more of less in it's final form) and add more examples, documentations.

How do you mean commit messages? Should I renamed the current commit messages? Is there any standard format?

@Bukama
Copy link
Member

Bukama commented Mar 27, 2020

One more note, should it be @DisableIfDisplayName?

Sure, makes sense and is more readable.

I can also work on finalising this(the code is more of less in it's final form) and add more examples, documentations.

That would be great!

How do you mean commit messages? Should I renamed the current commit messages? Is there any standard format?

Only the text for the final commit is needed as all the previous commits will get squashed while merging the branch into master - most probably done by @nicolaiparlog when you call it finished.

@nipafx
Copy link
Member

nipafx commented Mar 29, 2020

I can also work on finalising this(the code is more of less in it's final form) and add more examples, documentations.

Great, let me know when you're done and I'll review the PR then.

How do you mean commit messages? Should I renamed the current commit messages? Is there any standard format?

As Bukama mentioned, all commits will be squashed into one and then applied to master. That commit's message has a standard format, yes. You can propose a message if you want or I can write it if you prefer - your choice. :)

@nishant-vashisth
Copy link
Contributor Author

I've added documentation and some more examples. Also updated the extension's name

It made more sense to be able to have control to disable multiple tests in a set of Parameterized tests.
However, when I tried to make it a repeatable annotation, the Extension seem to get registered multiple times and was posing problems.

Unfortunately, I'll be away for a while (PC access) @nicolaiparlog , @Bukama If there is something amiss, it's perfectly fine if you guys want to pick that up.. Otherwise, i can take care of it next week or so.

Copy link
Member

@Bukama Bukama left a comment

Choose a reason for hiding this comment

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

Some minior improvement suggestions. Please take a look at them :)

@@ -0,0 +1,42 @@
:page-title: @DisableIfDisplayName
:page-description: JUnit Jupiter extensions to selectively disable Parameterized tests
Copy link
Member

Choose a reason for hiding this comment

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

(multiple) Parameterized ==> parameterized

:page-title: @DisableIfDisplayName
:page-description: JUnit Jupiter extensions to selectively disable Parameterized tests

The `@DisableIfDisplayName` annotation Junit Jupiter extension that can be selectively used to disable Parameterized tests which are dynamically registered on runtime basis their display name.
Copy link
Member

Choose a reason for hiding this comment

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

This reads wired. What about this:

The @DisableIfDisplayName annotation can be used to selectivevly disable parameterized....

The `@DisableIfDisplayName` annotation Junit Jupiter extension that can be selectively used to disable Parameterized tests which are dynamically registered on runtime basis their display name.
The annotations is only supported on test method level for Parameterized tests.
Unlike the `@Disabled` API provided in Junit which disables the test on first encounter of the annotation
`@DisableIfDisplayName` is validated before each `@ParameterizedTest` so that each test (name) can be individually evaluated
Copy link
Member

Choose a reason for hiding this comment

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

Missing . at the end of the sentence.

@@ -16,3 +16,5 @@
url: /docs/temp-directory/
- title: "Vintage @Test"
url: /docs/vintage-test/
- title: "@DisableIfDisplayName"
Copy link
Member

Choose a reason for hiding this comment

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

Please move up so it's sorted in alphabetically order


/**
* {@code @DisableIfDisplayName} is a JUnit Jupiter extension which can be used to
* selectively disable {@link ParameterizedTest} basis their {@link ExtensionContext#getDisplayName()}
Copy link
Member

Choose a reason for hiding this comment

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

basis their

Do you mean based on their ?

* If it is required that we wish to disable selective tests out of the plethora of dynamically
* registered Parameterized tests, then we can utilize the following
*
* Each repeatable annotation will be processed for each test, and Test will be skipped if
Copy link
Member

Choose a reason for hiding this comment

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

and the test will be

* registered Parameterized tests, then we can utilize the following
*
* Each repeatable annotation will be processed for each test, and Test will be skipped if
* any of them evaluate to be true against the display name
Copy link
Member

Choose a reason for hiding this comment

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

evaluates true against the display name.

@ExtendWith(DisableIfNameExtension.class)
public @interface DisableIfDisplayName {

/**
Copy link
Member

Choose a reason for hiding this comment

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

Displaynames of the tests cases to be disabled. The whole test case name can be stored as well as sub strings of it. The values will be evaluated [...] by default.
If {code regex} is provided, the string will be evaluated as ... display name.

@return Test case display name

/**
* @return if the {@code value} is to be evaluated as regular expression or sub-string
*/
boolean regex() default false;
Copy link
Member

Choose a reason for hiding this comment

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

Suggest to rename it to isRegEx. The name regex suggests that this field holds the regular expression itselfs, which will be confusing as a boolean can't hold such.

} else {
toDisable = context.getDisplayName().contains(details.value());

Optional<DisableIfDisplayName> disableIf = findAnnotation(testMethod, DisableIfDisplayName.class);
Copy link
Member

Choose a reason for hiding this comment

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

Please update to the new methods, provided by #187 after it is merged

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will wait for #187 to be merged to resolve all the other comments then

Copy link
Member

Choose a reason for hiding this comment

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

We just merged it, @nishantvas.

@nipafx
Copy link
Member

nipafx commented Apr 7, 2020

Since @Bukama already a close look at this, I'm gonna abstain until his comments were addressed. Let me know when that's done, so I can give a final review.

@Bukama
Copy link
Member

Bukama commented Apr 26, 2020

Hey @nishantvas,
do you know if you may find a moment to address my comments / requested changes?

@nishant-vashisth
Copy link
Contributor Author

Hi @Bukama, apologies I've been occupied in some other things. And didn't have access to my PC.
I'll have this for review by tomorrow.
I appreciate your patience.

@Bukama
Copy link
Member

Bukama commented Apr 27, 2020

Everything fine, take your time!

Copy link
Member

@Bukama Bukama left a comment

Choose a reason for hiding this comment

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

Thanks for the update. Just some small typos to correct and I would call this fine 👍


/**
* {@code @DisableIfDisplayName} is a JUnit Jupiter extension which can be used to
* selectively disable {@link ParameterizedTest} based on their {@link ExtensionContext#getDisplayName()}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* selectively disable {@link ParameterizedTest} based on their {@link ExtensionContext#getDisplayName()}
* selectively disable {@link ParameterizedTest} based on their {@link ExtensionContext#getDisplayName()}.

* selectively disable {@link ParameterizedTest} based on their {@link ExtensionContext#getDisplayName()}
*
* <p>
* The extension is an {@link ExecutionCondition} which validates dynamically registered tests
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* The extension is an {@link ExecutionCondition} which validates dynamically registered tests
* The extension is an {@link ExecutionCondition}, which validates dynamically registered tests.

Comment on lines 31 to 32
* This is highly useful since current {@link Disabled} or {@link DisabledIf} annotations disable
* the whole test but not the Parameterized tests selectively
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* This is highly useful since current {@link Disabled} or {@link DisabledIf} annotations disable
* the whole test but not the Parameterized tests selectively
* This is highly useful since current {@link Disabled} or {@link DisabledIf} annotations disable
* the whole test, but not the Parameterized tests selectively.

* the whole test but not the Parameterized tests selectively
*
* If it is required to disable selective tests out of the plethora of dynamically
* registered Parameterized tests, then we can utilize the following
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* registered Parameterized tests, then we can utilize the following
* registered Parameterized tests, then we can utilize the following.

Comment on lines 37 to 38
* Each repeatable annotation will be processed for each test and test will be skipped if
* any of them evaluates true against the display name
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Each repeatable annotation will be processed for each test and test will be skipped if
* any of them evaluates true against the display name
* Each repeatable annotation will be processed for each test and the test will be skipped if
* any of them evaluates true against the display name.

Comment on lines 50 to 51
* Display names of the test cases to be disabled. The whole test case name can be passed as well as sub string
* The values will be evaluated with {@link String#contains(CharSequence)} by default
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Display names of the test cases to be disabled. The whole test case name can be passed as well as sub string
* The values will be evaluated with {@link String#contains(CharSequence)} by default
* Display names of the test cases to be disabled. The whole test case name can be passed as well as a sub string.
* The values will be evaluated with {@link String#contains(CharSequence)} by default.

nishant-vashisth and others added 3 commits April 27, 2020 16:49
Co-Authored-By: Matthias Bünger <Bukama@users.noreply.github.com>
…ioneer into parameterized

� Conflicts:
�	src/main/java/org/junitpioneer/jupiter/DisableIfDisplayName.java
Copy link
Member

@Bukama Bukama left a comment

Choose a reason for hiding this comment

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

Thanks!

@nishant-vashisth
Copy link
Contributor Author

@Bukama, thanks for the proof checking.

@sonarcloud
Copy link

sonarcloud bot commented May 19, 2020

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 0 Security Hotspots to review)
Code Smell A 1 Code Smell

100.0% 100.0% Coverage
0.0% 0.0% Duplication

@nipafx
Copy link
Member

nipafx commented May 19, 2020

Thanks @nishantvas for the extension, this is really nifty. I added a bunch of changes to the PR, most notably that we can now distinguish between deactivating the test container and the individual invocations. While the code looked like it checked that (with getTestMethod) that didn't work for me. If you're ok with my changes, there are two more things that need to be discussed/done:

  1. This belongs into the params package, but that's a problem because it uses our internal utilities. We (i.e. @junit-pioneer/junit-pioneer-team) have to come up with a solution for this.
  2. Instead of value and isRegExp I'd prefer attributes contains and matches, e.g. @DisableIfDisplayName(contains = { "1", "2" }) or @DisableIfDisplayName(matches = ".*disabled?\\s.*"). What do you think?

@nishant-vashisth
Copy link
Contributor Author

@nicolaiparlog

if (!context.getUniqueId().contains("test-template-invocation"))
			return enabled("Never disable parameterized test method itself");

This does look relatively neater than using the getTestMethod(), didn't know about it. Thanks.

Also, the matches / contains do make sense. But I didn't want to do that instead of value because in this case, we'll have to default both or one of these to { } , which can lead to people adding the annotation on a test with it doing nothing or us having to make one of these fields mandatory. The neater solution to do this would be to have two annotations which felt like an overkill at the time

Also, not using the keyword value does make it a bit more readable but the annotation name is descriptive to it's means
@DisableIfDisplayName("something") However, of course
@DisableIfDisplayName(contains = { "1", "2" }) looks equally if not perhaps more descriptive.

@sonarcloud
Copy link

sonarcloud bot commented Jun 20, 2020

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 0 Security Hotspots to review)
Code Smell A 4 Code Smells

92.3% 92.3% Coverage
0.0% 0.0% Duplication

@nipafx
Copy link
Member

nipafx commented Jun 20, 2020

Regarding my two points:

  1. I moved the classes and found a working, yet ugly solution for the utils problem. Not great, but better than exposing internal APIs to our users. Unless somebody has another idea how to keep utils package-visible without duplicating a lot of code (and tests?), I'll stick with this.
  2. I implemented contains and matches attributes and think that it really helped with usability, although it does make the implementation a bit more cumbersome. We do get a nice feature on top, though: We can not combine substring search and regexp matching. Let me know what you think.

If nobody requires any further changes, I'm ok with this as it is and we can merge it. (Finally, sorry for taking so long with this.) Proposed commit message:

Disable parameterized test invocations by display name (#163 / #175)

Jupiter's `@Disabled`-based annotations disable entire test template
methods and can thus not be used to disable individual parameterized
test invocations. This extension adds that capability by matching
based on display name. Display names can be evaluated by searching
for substrings or matching against regular expressions (or both).

Because this extension belongs into the `params` package but also
needs to access `PioneerAnnotationUtils`, we needed to find a way
to make them accessible without making the class public. To prevent
duplication, we went with a (clever? abominable?) reflection hack.

Closes: #163
PR: #175

@Bukama
Copy link
Member

Bukama commented Jun 20, 2020

As said in stream chat I agree with Pioneer. So I'm fine with the current state of the PR too.

@Bukama Bukama self-requested a review June 20, 2020 15:09
Copy link
Member

@Bukama Bukama left a comment

Choose a reason for hiding this comment

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

(Renewing acceptance)

@nishant-vashisth
Copy link
Contributor Author

Yea the code change seems perfectly alright. The run time check for no values with annotation usage is quite alright. As long as it's documented. Otherwise it can be a tad misleading.

But I'm happy with this. Thanks for the changes

@Bukama Bukama merged commit 6c4056d into junit-pioneer:master Jun 20, 2020
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

3 participants