-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Introduce configuration parameter for setting default test instance lifecycle semantics #905
Comments
Strong +1 for this one and not only from a Kotlin developer perspective, to me |
Since this issue has been postponed to 5.1 backlog (I can understand there is some concern introducing a different mode of execution of the tests based on configuration), I was wondering if we could find a better alternative solution. For example, can't we turn this issue into enabling automatically |
That's certainly an interesting idea. But I'm concerned that it would come as a surprise to developers who simply forgot to type @junit-team/junit-lambda What do the rest of you think? |
I agree - I think feature switches that change the default behavior should be specified explicitly. |
Ok, I understand. Is supporting |
I still think making it the default for test classes written in Kotlin would be a clear rule and solve your problem... @junit-team/junit-committers Thoughts? |
@marcphilipp I guess I missed your proposal, but indeed that would be even better, so big +1 for that !!! The code for detecting Kotlin classes is straightforward and does not need any dependencies: private static boolean isKotlinClass(Class<?> clazz) {
for (Annotation annotation : clazz.getDeclaredAnnotations()) {
if (annotation.annotationType().getName().equals("kotlin.Metadata")) {
return true;
}
}
return false;
} |
I think you meant to address the "JUnit Lambda" team. 😛 In any case, I don't have a problem with making it the default for classes written in Kotlin. Kotlin developers could always explicitly revert back to per-method semantics if desired. |
@sdeleuze, thanks for the |
FYI: I just created #991 to enable per-class lifecycle semantics by default for Kotlin test classes. |
I read this in the release notes and was kind of surprised by this change. One of the things that I like about Junit over TestNG is that each test it executed in its own instance of the test. I don't want state to be shared between tests. I write a lot of my unit tests in Kotlin and this change would probably break many of my tests. Not only that but if a user were to go through and convert their Java tests to Kotlin they would end up seeing different results which could lead to quite a bit of confusion. Is there some reason why this should be the default for kotlin? Personally, I don't think this is the right decision. https://martinfowler.com/bliki/JunitNewInstance.html I would personally be fine with this being configurable but having this be the default for junit RC2 is enough to prevent me from moving my tests forward to this release. |
Just so everyone is on the same page, this is what it looks like to use @TestInstance(PER_METHOD)
class SimpleKotlinTestCase {
companion object {
@JvmStatic
@BeforeAll
fun beforeAll() {
println("beforeAll")
}
@JvmStatic
@AfterAll
fun afterAll() {
println("afterAll")
}
}
@BeforeEach
fun beforeEach(testInfo: TestInfo) {
println("beforeEach: " + testInfo)
}
@AfterEach
fun afterEach(testInfo: TestInfo) {
println("afterEach: " + testInfo)
}
@Test
fun firstTest() {
println("firstTest")
}
@Test
fun secondTest() {
println("secondTest")
}
} Having to declare the companion object and using It would be great to get a representative survey of all users who use Jupiter with Kotlin. Otherwise, it's very hard to decide this trade-off. Any ideas? @sdeleuze Did I state your main concerns with using |
@marcphilipp Yes If you prefer making it configurable via a global config or a static field, that's would be also fine to me and would be appreciated by a lot of users including non Kotlin ones IMO. What would be a pain would be to specify |
On the other hand, it's only 4 additional lines, and using |
How would the static field approach work? |
I 100% expect that this is what I would need to do in order to correctly use The problem with kotlin is that if you don't do this then you end up with lots of code like this: class `Some class with a nice name` {
lateinit val someList : MutableList<Int>
@BeforeEach
fun beforeEach() {
someList = mutableListOf(30)
}
@Test
fun `test that modifies someList`() {
// Change some list somehow
}
} VS The far simpler: class `Some class with a nice name` {
val someList = mutableListOf(30)
@Test
fun `test that modifies someList`() {
// Change some list somehow
}
} Having to put |
You could do something like mockito where they have a config switch that they put in a resource file:
in a file in: |
If we decide to go that route, we could introduce a general mechanism for reading default This file could look like this:
We could read the file when building @junit-team/junit-lambda Thoughts? |
Well I'm not @Team - however I will take the chance to chime in.
As I said in #991:
I myself would prefer a code based solution - i.e. Declare a static
variable TEST_LIFECYCLE; If doesn't exist the default JUnit semantics
exist; if does exist the declared semantics are used. I would make the
semantics per test runner launch.
I'm always troubled by config files because people often forget to look
there. At least the code based approach has slight better visibility.
Cheers
Mark
…On Tue, Aug 1, 2017 at 2:03 PM, Marc Philipp ***@***.***> wrote:
If we decide to go that route we could introduce a general mechanism for
reading default ConfigurationParameters from a Properties file, e.g.
junit-platform-config.properties.
This file could look like this:
junit.extensions.autodetection.enabled = true
junit.testinstance.lifecycle.default = PER_CLASS
We could read the file when building LauncherConfigurationParameters. Any
property passed explicitly to LauncherDiscoveryRequestBuilder (e.g. from
an IDE) would override those from the file.
@junit-team/junit-lambda
<https://github.com/orgs/junit-team/teams/junit-lambda> Thoughts?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#905 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAImZsXPDHsb50kD5Aj1wUFXMyrqhhN1ks5sT2hYgaJpZM4OJj_E>
.
--
[image: headshot-square-300x300]
<http://www.flickr.com/photos/36331075@N00/9674877046/> *Mark Levison* | 1
(877) 248-8277 | Twitter <https://twitter.com/mlevison> | LinkedIn
<http://ca.linkedin.com/in/marklevison> | Facebook
<https://www.facebook.com/agilepainrelief>
Certified ScrumMaster Training: Vancouver
<http://agilepainrelief.com/courses/vancouver> | Edmonton
<http://agilepainrelief.com/courses/edmonton> | Ottawa
<http://agilepainrelief.com/courses/ottawa> | Montreal
<http://agilepainrelief.com/courses/montreal> | Toronto
<http://agilepainrelief.com/courses/toronto>
Certified Product Owner & Private Training also available ~ Our Training
Schedule <http://agilepainrelief.com/courses/certified-scrum-agile-training>
Agile Pain Relief Consulting <http://agilepainrelief.com/> | Notes from a
Tool User <http://agilepainrelief.com/notesfromatooluser>
Proud Sponsor of Agile Tour Gatineau Ottawa <http://goagiletour.ca/> and Agile
Coach Camp Canada <http://agilecoachcampcanada.wordpress.com/>
|
@sbrannen thanks for the explanation I'm not to trilled with the idea of specifying the lifecycle semantics via a system property. That would likely lead to the possibility the setting being different when tests are run via a build tool vs when debugging in an IDE. Using a config file stored as a Java resource would be preferable. Regardless, a warning in the docs might be a good idea. |
@JLLeitschuh FYI: I created #1006 to track my proposal in #905 (comment) |
See junit-team/junit5#905 I will configure PER_CLASS by default when available
FYI: for anyone interested in the progress on this issue... Here's the code: a916e47 All that's left is documentation. |
In a Gradle project like https://github.com/sdeleuze/spring-kotlin-functional, what would be the recommended way to change the default to PER_CLASS with this improvement? Is there a way to set the configuration parameter at Gradle level? Or should I set a system property? |
Hi @sdeleuze, Unfortunately there is currently no native support for setting a configuration parameter via the console launcher, Maven Surefire plugin, or Gradle plugin. Thus, the only option from the build perspective is to set a system property. For the JUnit Platform Gradle Plugin, you can achieve that as discussed here: #475 (comment). |
Prior to this commit, the test instance lifecycle mode could only be changed from the default per-method value to per-class by annotating every single test class or test interface with @testinstance(PER_CLASS). This commit addresses this issue by introducing a new configuration parameter that allows the default test instance lifecycle semantics to be set on a per-project basis (e.g., for a build). Specifically, the default test instance lifecycle mode can now be set via a configuration parameter or JVM system property named `junit.jupiter.testinstance.lifecycle.default` with a value equal to one of the enum constants in TestInstance.Lifecycle. Issue: #905
Prior to this commit, the test instance lifecycle mode could only be changed from the default per-method value to per-class by annotating every single test class or test interface with @testinstance(PER_CLASS). This commit addresses this issue by introducing a new configuration parameter that allows the default test instance lifecycle semantics to be set on a per-project basis (e.g., for a build). Specifically, the default test instance lifecycle mode can now be set via a configuration parameter or JVM system property named `junit.jupiter.testinstance.lifecycle.default` with a value equal to one of the enum constants in TestInstance.Lifecycle. Issue: #905
Resolved in |
How does that constant work when running tests in IntelliJ? Will IntelliJ pickup that the gradle plugin has that default configured? |
Unless IntelliJ provides explicit support for setting configuration parameters to pass to the JUnit Platform
Nope. There's currently no explicit support for setting configuration parameters in the Gradle plugin (although there is a work-around). That will be addressed in #1015. However, the best (i.e., the only robust) solution is the use of the JUnit Platform configuration file which I'll be committing soon in conjunction with #1003. 😉 |
Now that I've resolved #1003, you can give the configuration file approach a try against the latest snapshots. If you do try it out, please let us know how it works for you. Cheers |
@sbrannen Works as expected, and seems a good outcome, thanks !!! sdeleuze/spring-kotlin-functional@7aef220 |
Cool! Thanks for letting us know. |
Prior to this commit, the test instance lifecycle mode could only be changed from the default per-method value to per-class by annotating every single test class or test interface with @testinstance(PER_CLASS). This commit addresses this issue by introducing a new configuration parameter that allows the default test instance lifecycle semantics to be set on a per-project basis (e.g., for a build). Specifically, the default test instance lifecycle mode can now be set via a configuration parameter or JVM system property named `junit.jupiter.testinstance.lifecycle.default` with a value equal to one of the enum constants in TestInstance.Lifecycle. Issue: junit-team#905
Overview
For teams that prefer per-class test instance lifecycle semantics, in order to prevent such teams from having to copy-n-paste
@TestInstance(Lifecycle.PER_CLASS)
across the code base, it would be beneficial to introduce a configuration flag (e.g., system property) that allows the default test instance lifecycle semantics to be set on a per-project basis (e.g., for a build).Switching the default semantics would remain an opt-in decision but would be considerably less intrusive with the configuration flag.
See #419 (comment) for background information.
In addition, we could introduce support for setting
ConfigurationParameters
via a properties file (e.g., ajunit.properties
file in the root of the classpath). This would allow such configuration to be contained in the project itself (and checked into a VCS) as opposed to having to set such a flag in the build script as well as in the IDE (perhaps on a per test run basis).Related Issues
Deliverables
junit.jupiter.testinstance.lifecycle.default
configuration parameter for setting default test instance lifecycle semantics.org.junit.jupiter.engine.Constants
.TestInstance.Lifecycle
, ignoring case.INFO
message if the test instance lifecycle mode has been set via the configuration parameter.@TestInstance
.The text was updated successfully, but these errors were encountered: