Customize Junit 4 XML report - java

Background:
TestNG supports adding your own Reporter classes in order to modify the reports being generated or generating new reports as needed.
However, JUnit doesn't have such a functionality, so a brute-force way would be to write your own Runner and then generate your own custom report.
But, I ask this question in order to find if there is something better?
Basically, I want to add custom attribute to every executed method.
<testcase name="test_test_something" classname="some.class.name" time="0.069" my-own-attribute="somevalue"/>
So my question is:
How is this XML report generated by JUnit and Gradle?
Is there a way to modify this process of report generation to add custom data to the report while doing minimal changes?

How is this XML report generated by JUnit and Gradle?
It’s eventually generated by the Gradle internal class org.gradle.api.internal.tasks.testing.junit.result.JUnitXmlResultWriter.
Basically, I want to add custom attribute to every executed method.
<testcase name="test_test_something" classname="some.class.name" time="0.069" my-own-attribute="somevalue"/>
[…]
Is there a way to modify this process of report generation to add custom data to the report while doing minimal changes?
Unfortunately, there is no way to add further attributes to the <testcase/> element. This code shows how the element and its attributes are currently created; there is no way to hook into that creation process.
If you can live with a hacky solution, then you could try writing your custom data to StdOut/StdErr during the test and set the outputPerTestCase property as follows:
// (configuring the default `test` task of the `java` plugin here; works with
// any task of Gradle’s `Test` type, though)
test {
reports {
junitXml {
outputPerTestCase = true
}
}
}
The written output will then end up at least somewhere within the <testcase/> element and you might be able use it from there somehow.

Related

loading classes from custom dependency in a custom gradle plugin

I have a custom Gradle plugin, that works well, I have published a couple of versions already.
I have a new requirement, where I want to allow the plugin's users to provide an optional list of dependencies, in which they would provide classes, that can be loaded during the plugin execution.
Looking at the documentation, it seems to be quite close to what is described in https://docs.gradle.org/current/userguide/implementing_gradle_plugins.html#providing_default_dependencies_for_plugins (in my case there's no default though - or said differently, the default should be an empty list of extra dependencies), but I struggle to adapt it to my use case.
right now, my plugin can be configured like this :
archUnit {
preConfiguredRules = ["sample.SampleRule"]
}
the plugin already contains some rules, but I want to allow users to provide their own rules, they should be able to provide something like
dependencies {
archUnitDeps 'org.example:archunit-custom-rules:1.0'
}
if the provided class (sample.SampleRule) is in that extra dependency that we configure, the plugin should load it and apply it, just like it does with the rules that are currently packaged with the plugin.
Following the docs, I create a configuration in my plugin :
Configuration deps = project.getConfigurations().create("archUnitDeps", c -> {
c.setVisible(false);
c.setCanBeConsumed(false);
c.setCanBeResolved(true);
c.setDescription("The packaged extra rules you may want to add ");
});
but then what should I do ?
I've tried something like this, to get the dependencies that the user configures, and add them at project level :
DependencyHandler dependencies = project.getDependencies();
deps.getAllDependencies().stream().forEach( extraDep -> dependencies.create(extraDep));
but when using it in a project, deps.getAllDependencies() is empty, even though I configure the org.example:archunit-custom-rules:1.0 dependency as above. So nothing gets loaded, and I end up with a java.lang.ClassNotFoundException: sample.SampleRule.
what am I missing ? do you have a readily available example of a plugin that does something similar, that I could get inspiration from ?
Finally was able to solve this, thanks to the help I got on https://discuss.gradle.org/t/class-loaded-through-configuration-is-not-found-when-task-runs/42945/3
I am quite surprised there's not a simpler solution, but one way of doing, is to use Gradle worker API, which takes 2 main steps :
in the task, get access to the workQueue, and submit the parameters required for the task execution :
WorkQueue queue = getWorkerExecutor().classLoaderIsolation(spec -> spec.getClasspath().from(getClasspath()));
queue.submit(WorkerAction.class, params -> {
params.getMainClassesPath().set(someValue);
params.getTestClassesPath().set(someOtherValue);
etc..
})
.collect(Collectors.toList()));
});
On the worker side, get back those parameters, and launch what you were initially doing in the task :
public abstract class WorkerAction implements WorkAction<WorkerActionParams> {
#Override
public void execute() {
WorkerActionParams params = getParameters();
....
}
The parameters you pass need to be serializable - I was not able to make that part fully work with my original parameters, so I had to create new "wrapper" ones.
full example is available here : https://github.com/societe-generale/arch-unit-gradle-plugin/pull/24/files

How to manipulate the order of the Before-/AfterScenarios in JBehave?

In our project we are currently encountering multiple Before-/AfterScenarios, which all by definition get executed before/after every Scenario. However some of the methods are dependent on the execution of the others.
More precisely: A third party framework uses BeforeScenario in their code, that should always be executed before our BeforeScenario. JBehave has a way of prioritizing steps when it comes to chosing the correct step for execution.
#Then(value="the value returned is empty", priority=1)
public void theValueIsEmpty()
#Then("the value returned is $value")
public void theValueIs(String value)
Is there something similar for the Before-/AfterScenario annotation?
There is no way to order execution of #BeforeScenario/#AfterScenrio in JBehave. But you can try using new Lifecycle functionality:
Lifecycle:
Before:
Scope: SCENARIO
[steps to be executed before each scenario]
After:
Scope: SCENARIO
[steps to be executed after each scenario]
More details can be found in the official documentation: Lifecycle
Alternative approach: file a new JIRA ticket for Before/After prioritizing and implement it or wait for implementation from JBehave contributors.

How to mark a feature file with #manualTesting such that scenarios inside it are never run

I have a case for a feature file where we have to test emails and we can't. So we decided to mark the whole feature file as #manualTesting so that people know that it has to be manually tested.
I know how to create an annotation to be executed before or after but is there a way that when we mark some feature file with #manualTesting it never gets executed.
Note:- I don't want to add any #excluded or #disabled annotation.
Tags in cucumber options will be the best way to do it.
If u r using 2.x version of cucumber tags dependency in your project then
tags={ "not #manualtesting"}
And if you are using 1x version then use
tags={"~#manualtesting"}
This will skip all features or scenarios tagges with #manualtesting.
You could use the "tags" attribute of the CucumberOptions annotation to exclude that tag from being executed:
#CucumberOptions(..., tags = {"not #manualTesting", ...},...)

Copying multiple files from various sources to various destinations via Spring Integration

I am presented with the following use case.
I am receiving a Message<Foo> object on my input channel, where Foo object has 2 properties
public class Foo {
...
public String getSourcePathString();
public String getTargetPathString();
...
}
sourcePathString is a String which denotes where the source file is located, while targetPathString is a place where the file should be copied to.
Now, I do know how to use file:outbound-channel-adapter to copy the file to a custom target location via FileNameGenerator, however, I am not sure how I can provide the location where to read the file from in file:inbound-channel-adapter and how to activate the reading when the message is received only.
What I have so far is a custom service activator where I perform copying in my own bean, however, I'd like to try and use Spring Integration for it.
So, is there a way to implement triggerable file copying in Spring Integration with already present components?
You cannot currently change the input directory dynamically on the inbound channel adapter.
The upcoming 4.2 release has dynamic pollers which would allow this.
However, it seems the adapter is not really suitable for your use case - it is a polled adapter, whereas you want to fetch the file on demand.
You could minimize your user code by configuring a FileReadingMessageSource, set the directory and call receive() to get the file.

Automatically remove the file generated by Java 7 Annotation Processor when delete the annotation in source file

I am writing a java annotation processor for java 7 source code.
And surely, I can use javax.annotation.processing.filer to help me generate the file under project directory automatically.
ex: annotation is #becare
public interface test {
#becare
int compare(int a, int b);
}
my annotation processor's job is when it detects the given annotation #becare, it will generate the file for me.
My Question is that if I remove the annotation from the previous code snippet, can I let annotation processor to be aware that and delete the file it just created?
Or is there any workaround to help me achieve this ?
Thanks in advance.
When you create the generated file you declare that it's linked to your 'test' interface like this:
Elements eltUtils = processingEnv.getElementUtils();
filer.createSourceFile("testGenerated", eltUtils.getTypeElement("test"));
When the source is deleted, the processor will remove generated file like javadoc says:
If there are no originating elements, none need to be passed. This information may be used in an incremental environment to determine the need to rerun processors or remove generated files. Non-incremental environments may ignore the originating element information.

Categories