Gradle: How to write tasks in Kotlin which runs another task? - kotlin

I want there to be a lot of test tasks, all of which are based on a "parent task".
The parent task should start the client application to be tested and then the one special
Call test class. The background is that e.g. I currently call my client manually as follows
must "./gradlew client: run --args = 'profile = default_client'" and then start all test classes at once with "./gradlew test"
(by the way: these tests connect to the running client via RMI connection.
My approach so far looks like this
open class Testing : DefaultTask() {
#get:Input
var profileName = "client"
#TaskAction
fun testIt() {
// 1. run/start the client
dependsOn(":client:run --args='profile=" + profileName + "'")
// this won't work: Cannot call Task.dependsOn(Object...) on task ':testing01' after task has started execution.
// 2. run a SPECIFIC testsuit via gradle
// ???
}
}
tasks.register<Testing>("testing01") {
profileName = "client-tests"
}
Unfortunately I don't know what to do next and how to fix the running of different tasks.

Related

Test Suite in kotest

I don't know if I am missing something but I could not find anything that says how to do a test suite like in JUnit. Can someone help me? I saw that documentation offers grouping tests, but when I run from Gradle, the logs are really large, and not very useful
You can group your tests using Tags, see https://kotest.io/docs/framework/tags.html.
For example, to group tests by operating system you could define the following tags:
object Linux : Tag()
object Windows: Tag()
Test cases can then be marked with tags using the config function:
import io.kotest.specs.StringSpec
class MyTest : StringSpec() {
init {
"should run on Windows".config(tags = setOf(Windows)) {
// ...
}
"should run on Linux".config(tags = setOf(Linux)) {
// ...
}
"should run on Windows and Linux".config(tags = setOf(Windows, Linux)) {
// ...
}
}
}
Then you can tell Gradle to run only tests with specific Tags, see https://kotest.io/docs/framework/tags.html#running-with-tags
Example: To run only test tagged with Linux, but not tagged with Database, you would invoke Gradle like this:
gradle test -Dkotest.tags="Linux & !Database"
Tags can also be included/excluded in runtime (for example, if you're running a project configuration instead of properties) through the RuntimeTagExtension:
RuntimeTagExpressionExtension.expression = "Linux & !Database"

Integrationtest IHost TestServer won't shutdown

I wrote some integration tests for an aspnetcore 3.1 application using xunit.
Tests show successful, but process is still running. After some time I get:
The process dotnet:1234 has finished running tests assigned to it, but is still running. Possible reasons are incorrect asynchronous code or lengthy test resource disposal [...]
This behavior does even show with boilerplate code like:
[Fact]
public async Task TestServer()
{
var hostBuilder = new HostBuilder()
.ConfigureWebHost(webHost =>
{
// Add TestServer
webHost.UseTestServer();
webHost.Configure(app => app.Run(async ctx =>
await ctx.Response.WriteAsync("Hello World!")));
});
// Build and start the IHost
var host = await hostBuilder.StartAsync();
}
Same if I add await host.StopAsync()...
I am on an Ubuntu 18.04 machine.
Try to dispose the host at the end of the test. Most likely, the error is caused just because you don't dispose disposable resource.
I would recommend you to use WebApplicationFactory for testing instead of HostBuilder. You may find more in the docs
I had the same problem. Since i was working with NUnit the suggested change was not an option (it is based on xunit). So i was digging into it and the root cause of it was quite simple:
I created a long running task in the Startup.cs which was doing some monitoring throughout all the hosting's lifetime. So i had to stop this task, and then also the instance of the TestHost was disposed properly.

Can gradle tasks be created that subset the tests in a project?

I am using the gradle tooling api to kick off tests based on receiving a webhook.
I don't see a way to pass parameters to the tooling API. I can run tests with something like:
String workingDir = System.getProperty("user.dir");
ProjectConnection connection = GradleConnector.newConnector()
.forProjectDirectory(new File(workingDir))
.connect();
try {
connection.newBuild().forTasks("test").run();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
connection.close();
}
But I don't see a way to run something like "gradle test --tests=xxx" so I was hoping I could make gradle tasks that were subsets of tests like "gradle dev_tests", "gradle int_tests".
Does anyone know if this is possible and if so, how to do it?
Per the gradle docs, newBuild() functions, conveniently ,as a builder pattern.
You can set several parameters before calling run() on it .
//select tasks to run:
build.forTasks( "test");
//include some build arguments:
build.withArguments("--tests=xxx");
...
build.run();
Source:
https://docs.gradle.org/current/javadoc/org/gradle/tooling/BuildLauncher.html

How to log from Debug Adapter Protocol implementation (vscode debugger extension)?

Intro: Hi folks, I'd like to ask some questions about extension developing. I'd like to create a remote lua debuger extension (for linux user, haven't found any working lua debugger). When I touch the launch button, the debug server should be started to listen (on e.g. 0.0.0.0:8723) for waiting debugger connection. And on the other side sould communicate through the DAP (debug adapter protocol) with vscode.
Problem: I'm starting to implement the my own debuger extension... But I am new in this topic and with Node.js also. My question is: How can I log (or debug) my LoggingDebugSession (where the DAP is implemented)?
I looked at the MockDebug extension example project.And tried to rewrite...
Try to log into console, my file luaDebugSession.ts:
export class LuaDebugSession extends LoggingDebugSession {
public constructor() {
super("remote-lua-debug-log.txt");
this.sendEvent(new OutputEvent("Try to log"));
console.log("Try log into console")
}
protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void {
this.sendEvent(new OutputEvent("Try to log 2"));
console.log("Try log into console 2")
// do something
this.sendEvent(new InitializedEvent());
}
// next code...
}
In console should be the logged output.

Automatically re-run failed only scenario in cucumber java+testng

How can I make only failed scenarios to be run again automatically on failure ?
Here is some clue on what I am doing:
Pass TestRunner class from command line through cucumber-testng.xml file at run-time.
I am able to see rerun.txt file after scenario failed, with feature/GM/TK/payment.feature:71 (pointing to failed scenario) but failed scenario is not automatically re-run.
The "TestRunner" java file
#RunWith(Cucumber.class)
#CucumberOptions(strict = true,
features = { "src/test/resources/" }, //feature file location
glue = { "com/test/stepdefs", "com.test.cucumber.hooks" }, //hooks and stepdef location
plugin = { "json:target/cucumber-report-composite.json", "pretty", "rerun:target/rerun.txt"}
)
public class CucumberTestRunner extends AbstractTestNGCucumberTests
{
}
The "RunFailedTest" Class to re-run from rerun.txt file
#RunWith(Cucumber.class)
#CucumberOptions(
strict = false,
features = { "#target/rerun.txt" }, //rerun location
glue = { "com/test/stepdefs", "com.test.cucumber.hooks" }, //hooks and stepdef location
plugin = {"pretty", "html:target/site/cucumber-pretty", "json:target/cucumber.json"}
)
class RunFailedTest
{
}
you can achieve it by using gherkin with qaf it generates testng XML configuration for failed scenarios that you can use for rerun. It also support scenario rerun on fail by setting retry.count property.
using Cucumber + Maven + TestNG
first, you don't need "#RunWith(Cucumber.class)" as you have mentioned in your question, if you are using TestNG, only "#CucumberOptions" is required.
When you start your test execution, all scenario failures will be written to file "target/rerun.txt" as per the configuration mentioned in your Runner file.
Now, you need to create one more Runner file (for example - "FailureRunner") and in this file provide the path of "#target/rerun.txt" ( this already have the details of the failure scenarios ) as -> features = { "#target/rerun.txt" }
Now, you need to UPDATE your TestNG.xml file and include the "FailureRunner" as below-
<class name="Class path of Your First Runner Class name" />
<class name="class path of FailureRunner Class" />
Once you do all the above steps and run your execution, the first execution will write the failure scenarios in the "target/rerun.txt" and After that, the "FailureRunner" Class will be executed which will pick up the "#target/rerun.txt" file and Hence, Failure scenarios will be executed.
I have executed in the same way and it works fine, let me know if it helps !!