How to run integration task after run task in gradle? - java

My Application is Spring boot application exposing some rest api
To run my integration tests , , first the application need to be up and running , as my application gradle based , how to make sure when i execute gradle command from command prompt , first application run and the integration tests will run .
task integration(type: Test, description: 'Runs the integration tests.', group: 'Verification') {
testClassesDir = sourceSets.integration.output.classesDir
classpath = sourceSets.integration.runtimeClasspath
outputs.upToDateWhen { false }
}
task appRunAndIntegrtationTest {
dependsOn 'run'
dependsOn 'integration'
tasks.findByName('integration').mustRunAfter 'run'
}
i added above code to build.gradle , but application up and running , thats it , it stayed their only , integration tests are not running , can anyone has idea on this please .
update : #Strelok , as mentioned , the application started up and integration task is not running .
update 1 : i found one gradle plugin
https://github.com/marc0der/gradle-spawn-plugin
i am trying to use like below
task startServer(type: SpawnProcessTask, dependsOn: 'assemble') {
command "java -jar ${projectDir}/build/libs/example.jar"
ready 'Started Application'
}
task stopServer(type: KillProcessTask)
but am getting below exception
*> Could not get unknown property 'SpawnProcessTask' for root project 'example-api' of type org.gradle.api.Project.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.*
please someone please suggest on this

I suggest a different approach: start and stop your application from your test framework. Test frameworks support setup and cleanup steps for your test suite (e.g. BeforeClass and AfterClass in JUnit), start the application in the setup step and stop it in the cleanup step. This approach will make your tests more self-contained, their success/failure will not depend on factors outside the test code.
Even if you prefer to run the application outside the test framework, I suggest wrapping this logic (i.e. starting the app, running the tests, stopping the app) in a Java class, and executing this class from Gradle via a task of type JavaExec. It will be much more clear than handling all this via Gradle tasks.
Finally, if you still insist on Gradle tasks, it's like the commenters said: the "run" task probably blocks execution while the app is running. Tha only sane way to handle this is to have a task that starts the app in the background, and another that stops it after the tests finished (use finalizedBy).

You should declare that the integration test task needs to depend on your app run task.
appRun is just an example please use the name of the task that is the precursor for the integration test.
integration.dependsOn appRun
integration.mustRunAfter appRun
Also, it might be like your app is running and blocking the progress of your Gradle build, does the build actually finish or it just hangs until the app stops running?

Related

How do I make an alias for a Gradle task?

As a part of a TDD workflow, I want to be able to check if my Java codebase compiles, but not if the tests pass.
Currently, if I run gradle build it runs the compile tasks (for source and tests) and then also executes the test task (and returns a non-zero exit code since the tests fail).
So I find that I have to run gradle build -x test to exclude the test task, and get a successful zero exit code.
What do I add to my build.gradle to define a new task, say compile that is an alias for build x test?
So far I have this, but it doesn't seem like dependsOn takes any arguments to customize the build task I want to execute:
task compile {
dependsOn build
}
I've been reading the docs here, I see different kinds of dependency chaining mechanisms, but not to disable/exclude a particular task. How does the -x flag even work then? I assumed there would be a way to control it programmatically too.
Thanks to Bjørn Vester's answer and reading the docs, I have implemented my task as follows:
task compile {
dependsOn classes
dependsOn testClasses
}
There are lots of different tasks you can run individually. For instance:
gradle classes: Will compile your "main" code.
gradle testClasses: Will compile your "main" code as well as test code.
gradle jar: Will compile your "main" code and assemble it into a jar.
None of the above will run your unit tests. On the other hand, the build task depends on all of the above, as well as the test task and more.
In general, if you like to run a particular set of tasks, you do that by defining a new task and then make dependencies to those other tasks you like to run with it. You tried that already, but instead of build you should have used something like compileJava or classes whatever other tasks you need. But always check if there isn't one already that satisfies your needs, like there are in this case. You can read about what tasks are available in Java projects in the documentation for the Gradle java plugin.

Debugging Elasticsearch Plugin Integration Tests using IntelliJ and Gradle

I am building an Elasticsearch plugin based on this example. The plugin uses Gradle for building, testing, integration testing, etc. I want to use IntelliJ to set a breakpoint in an Elasticsearch integration test and debug it. I don't care if I run the Gradle build from within IntelliJ or outside of IntelliJ, but right now in both cases I'm running into issues. I'll describe my setup and the problems below:
First I download and build/test the example project via CLI:
$ pip install cookiecutter
$ cookiecutter gh:spinscale/cookiecutter-elasticsearch-ingest-processor
$ # keep all default settings when prompted...
$ gradle build # (also runs the test and integTest tasks)
This runs fine and the tests pass. I generate the IntelliJ project using Gradle ($ gradle idea) and open it in IntelliJ (shows a green Gradle icon on the directory). I use the default gradle-wrapper option and keep all other defaults when opening.
First problem: I open IntelliJ's Gradle window (view > Tool Windows > Gradle), but I don't see any of the Gradle tasks which I know are defined in the project. This doesn't seem to be a huge deal, but it would be nice to have them.
Now I want to run the tests within IntelliJ, so I open the tests in org.elasticsearch.plugin.ingest.awesome.AwesomeProcessorTests. This class extends the ESTestCase class from Elasticsearch but doesn't directly test any Elasticsearch API interaction.
Second problem: I run this test class using the little green triangles next to the class name. This fails with the error java.lang.RuntimeException: unable to install test security manager.
I figured out I can get around this by editing the run configuration and adding the VM argument -Dtests.security.manager=false. Now the simple tests run and pass, and I can also set breakpoints and debug them.
Now I want to directly test some Elasticsearch functionality, so I write a new integration test class that extends the class ESIntegTestCase. The test should hit the Elasticsearch _cat/plugins endpoint and check that the response string is non-empty.
public class SimpleIT extends ESIntegTestCase {
private RestClient restClient;
#Before
public void setUp() throws Exception {
super.setUp();
this.restClient = getRestClient();
}
#Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singletonList(IngestAwesomePlugin.class);
}
public void testPluginInstallation() throws IOException {
Response response = restClient.performRequest("GET", "_cat/plugins");
String body = EntityUtils.toString(response.getEntity());
assertTrue(body.length() > 0);
}
}
When I run this via CLI (gradle integTest), the test passes. If I add a purposely-failing assertion (e.g. assertTrue(body.length() < 0), then the test fails. So that seems to work.
Third problem: When I run the same test from within IntelliJ (little green triangles), I get the error:
java.lang.IllegalArgumentException: no hosts provided
at __randomizedtesting.SeedInfo.seed([6F620686489164F5:270C27B7060A2BA1]:0)
at org.elasticsearch.client.RestClientBuilder.<init>(RestClientBuilder.java:68)
at org.elasticsearch.client.RestClient.builder(RestClient.java:124)
at org.elasticsearch.test.ESIntegTestCase.createRestClient(ESIntegTestCase.java:2261)
at org.elasticsearch.test.ESIntegTestCase.createRestClient(ESIntegTestCase.java:2248)
at org.elasticsearch.test.ESIntegTestCase.createRestClient(ESIntegTestCase.java:2242)
at org.elasticsearch.test.ESIntegTestCase.getRestClient(ESIntegTestCase.java:2236)
at org.elasticsearch.plugin.ingest.awesome.SimpleIT.setUp(SimpleIT.java:36)
This maps to the line where I call getRestClient(), meaning IntelliJ is blocking the Gradle/Elasticsearch integration testing setup which otherwise works from the CLI.
FWIW, I can still set a breakpoint on this line and debug the test class in IntelliJ and it will stop at the line.
Now I try to run the integration tests via CLI, set a breakpoint in IntelliJ, and use IntelliJ's remote debugger to attach to the tests.
I setup a new "Remote" run configuration, keeping the defaults (transport socket, debugger mode attach, host localhost, port 5005). On the "Search sources using module's classpath" option, I've tried all the possible settings.
I set a breakpoint on the getRestClient() line, and run Gradle with remote debugging options via CLI:
$ GRADLE_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005" gradle integTest
Fourth problem: As expected, the Gradle process suspends, showing Listening for transport dt_socket at address: 5005. I start the new remote task in IntelliJ, and then the Gradle process continues running. Unfortunately it runs all the way through and doesn't stop at the breakpoint. The tests still pass.
I've searched online extensively for different ways to attach to the Gradle debugger. I've seen many things about disabling the daemon, and I've also tried using --system-prop to pass the debug parameters, but nothing solves this problem so far.

run stop tomcat task if test task fails in gradle project

I am working on a gradle project. I have written few tests for it.
In build.gradle, I have written three tasks for it: tomcatStart, tomcatEnd and test.
Inside test task, i am executing tomcatStart in doFirst and tomcatStop in doLast.
It all works fine if there is no test failure.
But if a test fails, the tomcat keeps on running.
I want to know if there is any way, i can stop tomcat even if test task fails.
Try to use finalizebBy property of the test task. It's well described in the official documentation. According to it:
Finalizer tasks are useful in situations where the build creates a resource that has to be cleaned up regardless of the build failing or succeeding. An example of such a resource is a web container that is started before an integration test task and which should be always shut down, even if some of the tests fail.
And here is an example from the docs:
task taskX {
doLast {
println 'taskX'
throw new RuntimeException()
}
}
task taskY {
doLast {
println 'taskY'
}
}
taskX.finalizedBy taskY

Execute gradle task when its dependency is still running

I have to run a jar file and exec npm tests on it, but using gradle tasks. I'm using dependsOn to run the npm test after the jar is running.
These are my gradle tasks:
task runServer1 (type: Exec) {
// Run the jar file
}
task runNpmTest (type: Exec, dependsOn: ':runServer1') {
// Run npm tests
}
The problem is that when I execute gradle runNpmTest gradle stops at runServer1, which makes sense, because the server is still running. But my NPM tests will never run.
Any ideas?
It will not work this way, since runServer1 task is still running - it's a process. What you need is to run a server in background - so it won't block the main thread - and then run the tests. This probably should be done in a single task and configured via actions. Please have a look here and here to catch some useful knowledge.

How to enable debug on my JUnit through Gradle test task

I get into trouble while I try to run my JUnit test through Gradle test task. While I run the test in eclipse directly with Run As -> JUnit test, everything is ok, the test succeeds. But through test task, test always fails. Probably some trouble with the encoding of my resource txt file. So I would like to enable debug while I am launching the test with Gradle
in build.gradle, my test task now looks like:
test {
tasks.withType(Compile) {
options.encoding = 'UTF-8'
}
}
So what should I do to enable debug? I run Gradle tasks from Gradle panel in Eclipse, not from the console. Thanks!
To debug tests the following argument should be used: --debug-jvm
For example: gradle test --debug-jvm
Gradle will suspend execution right before running tests and wait for debugger connection on port 5005.
For executing only specific tests see Simple name pattern
For additional options see Debugging when running tests.
As explained under 23.12. Test in the Gradle User Guide, executing gradle test -Dtest.single=MyTestClass -Dtest.debug will suspend the test JVM upon start, and allows to connect an external debugger (such as the Eclipse debugger) on port 5005.
Putting this here as --debug-jvm did not work for me, I was able to do this by setting:
org.gradle.daemon=true
org.gradle.jvmargs=... -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=10999
in
~/.gradle/gradle.properties
But when I connect with eclipse debugger for the project none of the breakpoints I've set compile/trigger... I am connected via the debugger, I can see action in the Debug view, whenever I run gradle test from command line, like new threads starting/stopping, but can't get breakpoints to trigger, trying to resolve this now...
Fyi to stop deamon run gradle --stop
Other solution
Leaving above as reference, this worked for triggering break points in tests, I turned off deamon as I could not get it to work properly:
Using directions from this article: http://blogs.steeplesoft.com/posts/2013/gradle-tip-attaching-a-debugger.html
test {
if (System.getProperty('DEBUG', 'false') == 'true') {
jvmArgs '-Xdebug',
'-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=10999'
}
}
Executed via gradle test -DDEBUG=true
Solution when using the JUnit Platform Gradle plugin
The solution above won't work when using org.junit.platform.gradle.plugin.
Instead it should be replaced by:
junitPlatformTest {
if (System.getProperty('DEBUG', 'false') == 'true') {
jvmArgs '-Xdebug',
'-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=10999'
}
}
I'm on 4.6 (gradle) and I'm able to debug my tests when I have this in my build.gradle file:
test {
debug true
}
Link - https://docs.gradle.org/4.6/userguide/userguide_single.html#sec:java_test

Categories

Resources