I'm using Cucumber for my API tests and save the shared context in ScenarioContext class which is marked with #ScenarioScoped and #Injected per Steps class. Of course some features use steps from cross-classes as well (which causes the bug described below, but I dont want to change that due to DRY).
TestS run fine when I do them sequentially however they mix up the token Im saving in scenarioContext when I run them parallelly.
Has anyone faced this issue before? I tried with separate runners and 1 runner however the result was the same. Here's my pom.xml corresponding config:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<includes>
<include>**/*Suite.java</include>
</includes>
<forkCount>8C</forkCount>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
</plugins>
</build>
Above configuration should give the highest level of separation but my tests still fail at random (which does NOT happen with sequential run).
I've read following documentations and didnt find corresponding answers:
https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html
https://maven.apache.org/surefire/maven-surefire-plugin/examples/process-communication.html
https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html
#Alexey R. - Im adding additional code :)
So my ScenarioContext class looks as follows:
#ScenarioScoped
public class ScenarioContext extends Base {
Map<String, Object> scenarioContext;
public ScenarioContext() throws Exception {
this.scenarioContext = new HashMap<>();
}
public void setContext(Context key, Object value) {
scenarioContext.put(key.toString(), value);
}
public Object getContext(Context key) {
return scenarioContext.get(key.toString());
}
- some other general shortcut methods
}
And in my Steps classes aforementioned scenarioContext is called as follows:
public class myStepsClass extends Base {
#Inject
private ScenarioContext scenarioContext;
public myStepsClass(ScenarioContext scenarioContext) throws Exception {
this.scenarioContext = scenarioContext;
}
+[gherkin steps getting/setting values to scenarioContext]
I have also added a System.out.println("New scenario Context") in Scenario Context constructor and it seems to be printed out once per thread however I still get different results when tests are run in parallel :(
Related
I run my JUnit and Mockito tests in a big project. I use them for testing my server-side components that connect to web-service. All these connections require some time and it is not neccessary for them to be executed during the build.
I would like that my tests would be ignored during the build.
I have about 10 classes with tests. So the obvious way is to annotate all the classes with #Ignore. However I should do this every time I commit my code to the project and then re-annotate all tests. Not the very best solution I think.
So is this possible somehow simply ignore all package (let say com.example.tests) with the tests?
Or what might be the solution to ignore tests in the build in a simple way?
You can mention on your build.gradle what packages to exclude from tests
test {
exclude '**/*IntegrationTest*'
}
same for maven:
must consider this notation:
By default, the Surefire Plugin will automatically include all test classes with the following wildcard patterns:
"**/Test*.java" - includes all of its subdirectories and all Java filenames that start with "Test".
"**/*Test.java" - includes all of its subdirectories and all Java filenames that end with "Test".
"**/*Tests.java" - includes all of its subdirectories and all Java filenames that end with "Tests".
"**/*TestCase.java" - includes all of its subdirectories and all Java filenames that end with "TestCase".
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<excludes>
<exclude>*com.example.tests*/*Test.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
Another option is the old
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
or even when call it
mvn install -DskipTests
Using Categories seems to be an option that can come in handy
This is how you may add these to your Gradle script.
test {
useJUnit {
includeCategories 'org.gradle.junit.CategoryA'
excludeCategories 'org.gradle.junit.CategoryB'
}
}
A sample can be found here, adding it for a quick reference.
public interface FastTests
{
/* category marker */
}
public interface SlowTests
{
/* category marker */
}
public class A
{
#Category(SlowTests.class)
#Test public void a()
{
}
}
#Category(FastTests.class})
public class B
{
#Test public void b()
{
}
}
#RunWith(Categories.class)
#IncludeCategory(SlowTests.class)
#ExcludeCategory(FastTests.class)
#SuiteClasses({ A.class, B.class })
public class SlowTestSuite
{
}
I have found the solution for my case.
To disable all the tests during the build or even in any other context that you want the Spring annotation #IfProfileValue can be used. All tests with this annotation will be executed only in wanted context.
The example is this:
#IfProfileValue(name="enableTests", value="true")
public class DemoApplicationTests {
#Test
public void contextLoads() {
...
}
}
In my IDE I can edit the configuration and set the variable by:
-DenableTests=true
This annotation can be used on the level of a class or on the level of a test also.
All classes or tests annotated with such #IfProfileValue will be executed only in my environment and will be ignored during the build.
This approach is the best for me because it is not convenient in my project to change main pom.xml for my own test needs.
Addition.
Also in Spring or Spring Boot you should add Runner.
For example in Spring:
#RunWith(SpringJUnit4ClassRunner.class)
#IfProfileValue(name="enableTests", value="true")
#ContextConfiguration(classes = { YourClassConfig.class })
YourClassConfig might be empty:
#Configuration
public class YourClassConfig {
}
I've been trying for quite some time to implement my own custom Java rule(s) on SonarQube. However, it seems like no matter what I try, I can't get the new rule to show up on the SonarQube UI.
I only have one rule at the moment, a security rule that checks to see if text output is sanitized. The rule extends BaseTreeVisitor and implements JavaFileScanner. It overrides visitMethodInvocation to do some checks on String arguments for the relevant methods. Here is the rule definition annotation:
#Rule(key = "Sanitize_HTML",
name = "HTML Responses Should be Sanitized",
tags = {"security", "owasp-a3"},
priority = Priority.CRITICAL)
#ActivatedByDefault
#SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.SECURITY_FEATURES)
#SqaleConstantRemediation("10min")
public class SanitizeHTMLCheck extends BaseTreeVisitor implements JavaFileScanner{...}
After writing the rule, I wanted to test it, but quickly realized I had to wrap it in a plugin in order to do so. I wrote three additional classes for this, based entirely on the provided example plugin. Here's the base class:
public class SecurityPlugin extends SonarPlugin{
public List getExtensions(){
return Arrays.asList(
JavaClasspath.class,
JavaTestClasspath.class,
Java.class,
SecurityRulesDefinition.class,
SonarComponents.class,
DefaultJavaResourceLocator.class);
}
}
The classes in the list are all irrelevant (added in desperation) except for SecurityRulesDefinition. It mirrors the structure of the MyJavaRulesDefinition class from the example:
public class SecurityRulesDefinition implements RulesDefinition{
public void define(Context context){
NewRepository repository = context
.createRepository(RulesList.REPOSITORY_KEY, Java.KEY)
.setName("Security Rules");
AnnotationBasedRulesDefinition.load(repository, Java.KEY, RulesList.getChecks());
for(NewRule rule : repository.rules()){
rule.setInternalKey(rule.key());
}
repository.done();
}
}
Finally, just like the example, here's RulesList, where all of my rule classes are supposed to go:
public class RulesList {
public static final String REPOSITORY_KEY = "security_java";
private RulesList(){}
public static List<Class> getChecks(){
return ImmutableList.<Class>builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
}
//Add all checks to here...
public static List<Class<? extends JavaCheck>> getJavaChecks(){
return ImmutableList.<Class<? extends JavaCheck>>builder()
.add(SanitizeHTMLCheck.class)
.build();
}
//Put all test checks here
public static List<Class<? extends JavaCheck>> getJavaTestChecks(){
return ImmutableList.<Class<? extends JavaCheck>>builder()
.build();
}
}
Like I said, these are all pretty much ripped from the example plugin, so I have no idea what could be wrong with them.
I'm using Eclipse with M2E to try and build the plugin. As suggested by the documentation's Coding A Plugin page, I've added the following plugin tag to my POM.xml:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-packaging-maven-plugin</artifactId>
<version>1.13</version>
<extensions>true</extensions>
<configuration>
<pluginKey>securityrules</pluginKey>
<pluginClass>org.myOrg.sonar_analysis.security_rules_java.SecurityPlugin</pluginClass>
<pluginName>Sonar Java Custom Security Rules</pluginName>
<pluginDescription>Implements several checks against OWASP-Top-10 vulnerabilities.</pluginDescription>
</configuration>
</plugin>
</plugins>
</build>
Now, according to everything I've read, I should be able to build the project (right-click on the project > Run As > Maven Build (with goal "package") and drop the resulting .jar into SONAR_HOME/extensions/plugins, and when I restart the server, the rule (and repository) should be there. However, no matter what I try, it's never there. I've spent hours combing the internet and trying anything I find, but the rule never shows up in the UI.
Am I missing something? Have I done something wrong? Is my code incorrect or missing anything?
Thank you for reading this monster post. Any advice you have is valuable, as I'm out of ideas.
The structure of the code seems right for me (more or less).
In the SecurityPlugin class, you return many classes (JavaClasspath.class, JavaTestClasspath.class and so on)... What are they for? What do they implement/extend?
In my expirience you need to return there:
- a "RulesDefinition" (to see the rule in SonarQube) and
- a CheckRegistrar (to let the checks being used).
Maybe my small rules project will give you some ideas (https://github.com/arxes-tolina/sonar-plugins ; one rule with two checks).
If you are still struggling with the rules try to set the sonar.log.level-property (./conf/sonar.properties) to DEBUG and watch the start-up of SonarQube.
As stated in the documentation of rest-dispatch, the rest application path must be configured in the GIN module via a constant, here "/api/v1":
public class DispatchModule extends AbstractGinModule {
#Override
protected void configure() {
RestDispatchAsyncModule.Builder dispatchBuilder =
new RestDispatchAsyncModule.Builder();
install(dispatchBuilder.build());
bindConstant().annotatedWith(RestApplicationPath.class).to("/api/v1");
}
}
I would like to make the "/api/v1" constant be resolved at compile time, based on an environment variable set by the build system depending on the target environment (prod, dev, etc...), and on other criteria (the build artifact major version...).
The problem is I do not manage to rely on a compile time variable.
Neither TextResource/CssResource nor GWT's deferred binding won't help here, since GWT.create() cannot be used in GIN module. Another option I considered is using a custom Generator, but this seems to be too complex for this very simple need.
How do you solve this problem ?
If you use Maven as your build system, you could leverage the templating-maven-plugin to generate a Java class that will contain static variables defined in your POM file. That generated class will be used by your GWT code.
For example, you would want to populate a BuildConstants class template
public class BuildConstants {
// will be replaced by Maven
public static final String API_VERSION = "${myapi.version}";
}
and using a Maven property:
<myapi.version>v1</myapi.version>
that will be compiled to
public class BuildConstants {
// will be replaced by Maven
public static final String API_VERSION = "v1";
}
and you could reference those constants from within your DispatchModule:
bindConstant().annotatedWith(RestApplicationPath.class).to("/api/" + BuildConstants.API_VERSION);
Here's a sample config of the templating-maven-plugin that I use in a project:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0-alpha-3</version>
<executions>
<execution>
<id>filter-src</id>
<goals>
<goal>filter-sources</goal>
</goals>
<configuration>
<sourceDirectory>${basedir}/src/main/java-templates</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java-templates
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
There's no reason you couldn't replace the bindConstant() with a #Provides method (or other bind().toProvider(), which would let you use a TextResource and/or deferred-binding, or whatever.
Asn an example (untested though), the code below uses JSNI to read the value from the host page, which makes it runtime dependent (rather than compile-time):
#Provides #RestApplicationPath native String provideRestApplicationPath() /*-{
return $wnd.restApplicationPath;
}-*/;
Following Thomas Broyer suggestion and Simon-Pierre, you could even bind different root .gwt.xml files depending on your maven profile. Then you choose the appropriate Gin module class where your constants are bound.
That is what we do inside the CarStore companion project of GWTP do do Form factors for example.
For supporting purposes I need to add a version and build identifier to our Java library. The library itself is a toolkit without user interaction which is used in different environments (stand alone Java applications, web applications, Eclipse applications, Maven dependency, ...).
What I want, is a class with some constants giving me the above described information (such as MyAppVersion.BUILD, ...), so that they can be shown e.g. in dialogs, command line output, etc. After my research, there seem to be the following approaches:
add versioning to file name, such as myLibrary-0.1.2.jar; not feasible in our case, since I have no control over the file name when deployed
add information to the MANIFEST.MF and read it programmatically, like described here. I'm not sure however, how robust this approach is in respect to different class loaders (Eclipse, OSGi, application servers, ...) and if the JAR file gets re-packaged, this information is lost
use a version.properties file holding the version, as described here and use a script during build to update the version.properties file
hard code the version information into the class directly and use a script to update this information
Are there any other approaches? The last option seems most "robust" to me, are there any objections against this variant? Is there a Maven plugin which would support updating this information in a MyAppVersion.java file during build?
I would suggest to use the templating-maven-plugin which is created exactly for such purposes.
You create at best a separate module which contains a template class like this (or within your module):
public final class Version {
private static final String VERSION = "${project.version}";
private static final String GROUPID = "${project.groupId}";
private static final String SVN = "${project.scm.developerConnection}";
private static final String SVN_BRANCH = "${scmBranch}";
private static final String REVISION = "${buildNumber}";
public static String getVersion() {
return VERSION;
}
public static String getGroupId() {
return GROUPID;
}
public static String getSVN() {
return SVN;
}
public static String getRevision() {
return REVISION;
}
public static String getSVNBranch() {
return SVN_BRANCH;
}
}
Which you simply put into src/main/java-templates folder plus an appropriate package name. Furthermore you configure the templating-maven-plugin like the following in your pom file:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0-alpha-3</version>
<executions>
<execution>
<goals>
<goal>filter-sources</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This will generate a class Version which can be used by others and contains the given version. In the above template class you can use any property which is available in your build (things like JENKINS_ID etc.) or things your might define by yourself.
The result is that this class is compiled and packaged into your jar file.
Apart from that you can combine that with the buildnumber-maven-plugin to create the buildNumber which needs to be added to your pom file like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<revisionOnScmFailure>UNKNOWN</revisionOnScmFailure>
<getRevisionOnlyOnce>true</getRevisionOnlyOnce>
</configuration>
<executions>
<execution>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
The last option of hardcoding the version is the most robust which seems to be important to you.
If you build using ant, you can write a class (let's call it VersionGenerator) that will generate a java file with version:
package my.cool.package;
public interface Version {
String VERSION = "1.2.3";
}
Call VersionGenerator from ant
And then compile all your code and roll it into a jar. And your jar will contain a freshly generated and compiled Version.class!
VersionGenerator will have the logic of how to name and increase versions
I have following tests structure:
public class WorkerServiceTest {
public class RaiseErrorTest extends AbstractDbUnitTest{
#Test
public void testSomething(){
}
...
}
...
}
It's done because I don't want to create a separate class file for every test case extending AbstractDbUnitTest.
The problem is that mvn test doesn't run test from my inner class. Is there is a way how to configure Maven to run such tests? Of course I can create methods in the parent class calling the inner class methods but I want a clearer way.
Yes, this is possible using the new (well, it's not new anymore) Enclosed runner (since JUnit 4.5) that runs all static inner classes of an outer class.
To use it, just annotate the outer class with #RunWith(Enclosed.class) and make the inner classes static.
#RunWith(Enclosed.class)
public class WorkerServiceTest {
public static class RaiseErrorTest extends AbstractDbUnitTest{
#Test
public void testSomething(){
}
...
}
...
}
And mvn test will run them.
I explain (a little more) the solution that I found...
Maven (AFAIK) uses by default the plugin "maven-surefire-plugin" to run any tests defined at your maven project. According to the documentation of this plugin, by default, it excludes tests that are enclosed at inner static classes (or at least it was with version that i'm using - 2.18.1).
So what i did was to put a empty exclude rule; resulting with a pom's build section like this:
<build>
<plugins>
...
<!-- ~~~~~~~~~~ SUREFIRE -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<excludes>
<exclude></exclude>
</excludes>
</configuration>
</plugin>
...
</plugins>
</build>