gradle test phases? - testing

Is there a way to build custom test phases in gradle?
I have a series of tests, namely
/unit
/local
/remote
which is running JUnit managed tests for a couple different purposes. I'd love to be able to run these as test phases, such as gradle test:unit, or something like that. Ideally, I could also specify a description for each test phase, so gradle tasks describes the role of each of the tests.
Is this possible? If so, how?
I tried this:
sourceSets {
unit {
java.srcDir file('src/test/groovy/local')
resources.srcDir file('src/local/resources')
}
}
dependencies {...}
task unitTest(type: Test){
testClassesDir = sourceSets.local.output.classesDir
classpath = sourceSets.local.runtimeClasspath
}
...as copied from withIntegrationTests in the provided samples, but when I run gradle unitTest, no tests run.

You just need to add three Test tasks (testUnit, testLocal, testRemote) and configure them accordingly. (Instead of introducing testUnit, you could also reuse the test task that comes with the Java plugin.) If the sources are in different source folders, it also makes sense to add additional source sets. For the details, have a look at samples/java/withIntegrationTests in the full Gradle distribution.

Related

Why can't JUnit Platform find my cucumber tests?

I am currently running my cucumber scenarios like this with JUnit 4:
#RunWith(Cucumber::class)
#CucumberOptions(
features = ["src/features"],
tags = "not #ignored"
)
class RunCucumberTest
I am trying to get the same working on JUnit Platform, and currently have:
#Suite
#IncludeEngines("cucumber")
#SelectDirectories("src/features")
#ConfigurationParameter(key = Constants.PLUGIN_PROPERTY_NAME, value = "pretty")
#ConfigurationParameter(key = Constants.GLUE_PROPERTY_NAME, value = "garden.ephemeral.rocket")
class RunCucumberTest
I have updated the stuff on the Gradle side as well:
tasks.withType<Test> {
useJUnitPlatform {
// TODO: Not needed? Doesn't seem to work with or without.
includeEngines("cucumber")
}
jvmArgs("--add-modules=jdk.incubator.vector")
// Workaround. Gradle does not include enough information to disambiguate
// between different examples and scenarios.
// TODO: Move to cucumber.properties?
systemProperty("cucumber.junit-platform.naming-strategy", "long")
// TODO: Move to junit-platform.properties?
systemProperty("junit.jupiter.execution.parallel.enabled", "true")
}
When I run Gradle, the :test task runs, but the test report is empty.
When I try to run the test class from IDEA, I get:
> No tests found for given includes: [garden.ephemeral.rocket.RunCucumberTest](--tests filter)
How do I make this work?
Investigation so far:
I also tried moving the features into the resources and using #SelectClasspathResource("features") instead, but got the same result.
I tried cloning this project and it does run its scenarios, but everything is written in Java instead of Kotlin. Other than that, everything is mostly the same between the two. That project uses #SelectClasspathResource instead of #SelectDirectories, but I already tried that. I also tried using #SelectDirectories over in that project, and that works too.
If I breakpoint inside DiscoverySelectors.selectDirectory, it doesn't seem to stop there. Best guess is, maybe JUnit isn't even finding and running the suite? Or maybe breakpointing inside JUnit just doesn't work.
Best current idea is to convert that skeleton project to Kotlin and see if it still runs.
At a glance this doesn't look right:
useJUnitPlatform {
// TODO: Not needed? Doesn't seem to work with or without.
includeEngines("cucumber")
}
With the #Suite annotation you are using the JUnit Platform Suite engine to kick of the Cucumber engine. By setting the included engines to cucumber you exclude the suite engine from gradles discovery process.
Note that the skeleton project uses:
tasks.withType<Test> {
useJUnitPlatform()
// Work around. Gradle does not include enough information to disambiguate
// between different examples and scenarios.
systemProperty("cucumber.junit-platform.naming-strategy", "long")
}

How do I separate gradle unit tests from integration tests in the same source set?

The problem is that we are an IntelliJ shop and this issue has been a thorn in our sides. It basically means that everything has to be in ./test/ in order to work. ./it/ isn't acceptable because IntelliJ picks it up as the wrong kind of source every time you try to do anything. So.... how do I separate integration tests from unit tests so that they can be run separately in Gradle if they are in the same source set? Anyone have an example?
We use the *Test*.java and *ITCase*.java naming conventions, if that helps. Anothing thing we were thinking of is some kind of use of JUnit's #Category annotation.
P.S. Please vote for this issue. It will be a thorn in the side of any IntelliJ shop considering Gradle that has integration tests in a different directory from unit tests.
I can't speak to IntelliJ configuration, but in build.gradle, if you have:
test {
if (! project.hasProperty("ITCASE")) {
exclude "**/*ITCase*"
}
}
then the following command-line would include the integration tests:
gradle test -PITCASE=true
then and the standard would exclude them:
gradle test

Running Scala tests automatically either after test change or tested class change

I'm wondering if there is any solution to let Scala tests run automatically upon change of test class itself or class under the test (just to test automatically pairs Class <---> ClassTest) would be a good start.
sbt can help you with this. After you setup project, just run
~test
~ means continuous execution. So that sbt will watch file system changes and when changes are detected it recompiles changed classes and tests your code. ~testQuick can be even more suitable for you, because it runs only tests, that were changed (including test class and all it's transitive dependencies). You can read more about this here:
http://code.google.com/p/simple-build-tool/wiki/TriggeredExecution
http://php.jglobal.com/blog/?p=363
By the way, ~ also works with other tasks like ~run.

JUnit testing custom Eclipse builders

I have created an extra builder for Java projects.
I'm trying to test it automatically via JUnit test that changes and refreshes a project file and expects automatic builder to kick in. Unfortunately this doesn't happen.
I can access and modify Workspace from that test but I don't know how to deal with builders (or GUI elements). I also tried to check "Run in UI thread" in junit test's debug configuration but no success.
What's the proper way to do this kind of testing? (I'd like to avoid learning TPTP, if possible -- looks too heavy).
How to initiate "Project -> Clean" command from my tests? Or how to execute any UI command? I suppose there are some threading issues to take care of.
I think you are looking for the command:
ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
and
ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null);
The first will initiate a clean, and then a build on the entire workspace. The second will initiate only a clean.
Alternatively, if you have access to an IProject object, you can call build on that.

Maven make phase conditional

I want to make some phases optional say if compile fails or test fails and complete other phases like checkstyle, findbugs. Can i do that in maven, i have done it in ant not sure how to go about in maven
Maven has no means to dynamically add or remove goals or lifecycle phases. Yes, you could probably achieve functionality like that by writing a plugin and using the <extension> mechanism, but you would be breaking standard conventions.
But all plugins you talk about have parameters you can set to not fail the build:
compiler:compile has the failOnError parameter
surefire:test has the testFailureIgnore parameter
findbugs:check has the failOnError parameter
checkstyle:check has the failsOnError parameter
My suggestion would be to have a profile where you add configurations with all of these parameters, so you can toggle all of them with a single command.
You will probably need to write your own small plugin for Maven in order to handle this. You may want to see this thread:
http://www.mail-archive.com/users#maven.apache.org/msg95552.html
Maven encourage you to play with "goal-to-phase assignments", instead of explicit instructions about when to run what. Maven lifecycle is your roadmap, which you can't change. And on every milestone (phase) in this roadmap you can do certain operations (goals). In other words, you have to forget Ant and start using Maven :)