I cannot control muti-thread with Cucumber parallel execution - automation

I have configured Cucumber parallel execution successfully, but by default, 10 threads will be created at a time. So I tried maven command with -Ddataproviderthreadcount=2 and it worked. But when I tried define this option in POM file, it didn't work.
My POM:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<parallel>both</parallel>
<threadCount>2</threadCount>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<properties>
<property>
<name>dataproviderthreadcount</name>
<value>2</value>
</property>
</properties>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/${test.suite}.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</execution>
</executions>
My Cucumber test runner:
#CucumberOptions(features = "src/test/resources/features", glue = "StepDefinitions", plugin = "pretty")
class runnerOne extends AbstractTestNGCucumberTests {
#Override
#DataProvider(parallel = true)
public Object[][] scenarios() {
return super.scenarios();
}
}
My TestNG:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1">
<listeners>
<listener class-name="Utilities.Listener"></listener>
</listeners>
<test name="Test" >
<classes>
<class name="TestRunners.runnerOne" />
</classes>
</test>
</suite>

In order to take full benefit of TestNG with Cucumber, you should try using BDDTestFactory2 which is pure TestNG implementation. It considers each scenario as TestNG test and scenario outline with example as data driven test. So it is supporting different parallel configuration and parameters like thread-count, data provider thread count etc.
In your case you are using cucumber so to support step implementation in cucumber you will require QAF-Cucumber. Use BDDTestFactory2 that supports feature files written in Gherkin format or BDD2 format which is super set of Gherkin.

Related

How can i write a customized TestNGCucumberRunner with the latest io.cucumber.cucumber-testng version 4.2.6

I am trying to write a custom TestNGCucumberRunner (for the latest version cucumber 4.2.6) where I can filter the list of cucumberfeatures based on runtime arguments, in the getFeatures() method.
All the examples online are explained with info.cukes 1.2.5 version, where all the dependent classes and methods were public
I have never written a testrunner before. Can any one help please?
First - Update POM.xml with correct set of io.cucumber dependencies as per v 4.2.6
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.2.6</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>4.2.6</version>
</dependency>
Second - Customize TestNGRunner class as per your framework need
package com.jacksparrow.automation.suite.runner;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import com.jacksparrow.automation.steps_definitions.functional.BaseSteps;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
#CucumberOptions(features = "classpath:features/functional/",
glue = {"com.jacksparrow.automation.steps_definitions.functional" },
plugin = { "pretty","json:target/cucumber-json/cucumber.json",
"junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
tags = { "#BAMS_Submitted_State_Guest_User" },
junit ={ "--step-notifications"},
strict = false,
dryRun = false,
monochrome = true)
public class RunCukeTest extends Hooks {
}
Third - Implement Hooks.java
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import cucumber.api.testng.AbstractTestNGCucumberTests;
public class Hooks extends AbstractTestNGCucumberTests {
#Parameters({ "browser" })
#BeforeTest
public void setUpScenario(String browser){
BaseSteps.getInstance().getBrowserInstantiation(browser);
}
}
Note - I have not implemented this way. But as per my best knowledge, it may work. Please check and share your experience.
Fourth - Update TestNG.xml under /src/test/resources/ as per your TestNGRunner Class and framework need.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="1" name="Test" parallel="tests">
<parameter name="browser" value="chrome" />
<classes>
<class
name="com.jacksparrow.automation.suite.runner.RunCukeTest" />
</classes>
</test>
</suite>
Fifth - You shall be all set to run automation suite using TestNG in any of the following ways
- Run TestNG.xml directly from IDE
- From CMD - mvn test -Dsurefire.suiteXmlFiles=src/test/resources/testng.xml
- From POM.xml - Using Surefire Plugin
<profiles>
<profile>
<id>selenium-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

#MicronautTest does not start the embedded server

I am writing a Spock test for controllers in an app using Micronaut. When using #MicronautTest(application=Application), it throws exception with message #MicronautTest used on test but no bean definition for the test present..
On examining the code, I see the following 2 reasons why Micronaut throws this exception. From io.micronaut.test.extensions.spock.MicronautSpockExtension :
if (this.specDefinition == null) {
if (!this.isTestSuiteBeanPresent((Class)spec.getReflection())) {
throw new InvalidSpecException("#MicronautTest used on test but no bean definition for the test present. This error indicates a misconfigured build or IDE. Please add the 'micronaut-inject-java' annotation processor to your test processor path (for Java this is the testAnnotationProcessor scope, for Kotlin kaptTest and for Groovy testCompile). See the documentation for reference: https://micronaut-projects.github.io/micronaut-test/latest/guide/");
}
...
}
My POM configuration is:
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>addTestSources</goal>
<goal>addSources</goal>
<goal>compileTests</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.version}</version>
</path>
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-validation</artifactId>
<version>${micronaut.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
<executions>
<execution>
<id>test-compile</id>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
</plugin>
If I do not define the annotation the test #MicronautTest, it seems that the application doesn't even start.
Below is the spec code:
#MicronautTest(application= Application)
#PropertySource(value = [
#Property(name='spec.name', value = 'EndpointSpec'),
#Property(name = 'endpoints.health.details-visible', value = 'ANONYMOUS'),
#Property(name = MongoSettings.EMBEDDED, value = 'true'),
])
class EndpointSpec extends Specification {
#Inject
EmbeddedServer embeddedServer
#Inject
ApplicationContext applicationContext
#Unroll
def "test health endpoint is working"() {
given: 'a RxHttpClient'
URL server = embeddedServer.getURL()
RxHttpClient client = new DefaultHttpClient(server, new DefaultHttpClientConfiguration(), '/management')
when: '/health is called'
HttpResponse response = client.toBlocking().exchange('/health')
then: 'response is 200 OK and contains valid headers'
response.status == HttpStatus.OK
response.headers.size() == 5
response.headers.contains('uber-trace-id')
response.headers.contains('Date')
response.headers.contains('content-type') && response.headers.get('content-type') == MediaType.APPLICATION_JSON
response.headers.contains('content-length')
response.headers.contains('connection')
//and: 'response contains valid HealthResult'
//HealthResult healthResult = response.body()
// Want to validate the health result here but nothing is present in body
}
}
How I can either defined the specDefinition value or mark the test in such a way that it is present as a bean definition and what is the reason for such a behavior. Any help would be greatly appreciated.
Micronaut-test makes the tests themselves beans. In order for a Groovy test to be a bean, you need to have micronaut-inject-groovy on the compilation path for test.
Yes, adding the micronaut-inject-groovy to your maven build will resolve the issue. Add the following.
<dependency>
<groupId>io.micronaut.test</groupId>
<artifactId>micronaut-test-spock</artifactId>
<scope>test</scope>
</dependency>

Has anyone used proguard to obfuscation of .war file and succeed?

Has anyone used proguard to obfuscation of .war file and succeed? if yes then please tell me the exact steps to obfuscation of war.
I am not finding any ideal document on web for my requirement.
I have created my web application in spring boot and jsp.
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<proguardVersion>5.3.3</proguardVersion>
<injar>${project.build.finalName}.jar</injar>
<outjar>${project.build.finalName}.jar</outjar>
<obfuscate>true</obfuscate>
<options>
<option>-dontshrink</option>
<option>-dontoptimize</option>
<option>-adaptclassstrings</option>
<option>-keepattributes
Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod</option>
<option>-keepnames interface **</option>
<option>-keepparameternames</option>
<option>-keep class
!com.slm.proguard.example.spring.boot.domain.**
{ *; }</option>
<option>-keep class com.slm.proguard.example.spring.boot.service {
*; }</option>
<option>-keep interface * extends * { *; }</option>
<option>-keepclassmembers class * {
#org.springframework.beans.factory.annotation.Autowired *;
#org.springframework.beans.factory.annotation.Value *;
}
</option>
</options>
<libs>
Include main JAVA library required.
<lib>${java.home}/lib/rt.jar</lib>
Include crypto JAVA library if necessary.
<lib>${java.home}/lib/jce.jar</lib>
</libs>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>5.3.3</version>
</dependency>
</dependencies>
</plugin>
I had problems with a JAR created by proguard, it seemed ok but tomcat didn't find anything inside. After a long search I found that unzipping and re-zipping with an ant-task the exact same file make a working one.
Here is the added configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>fixzip</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- ******************** ********* ******************** -->
<!-- ******************** IMPORTANT ******************** -->
<!-- ******************** ********* ******************** -->
<!-- It may seems strange to unzip and re-jar the file -->
<!-- but the JAR made by Proguard is somehow not readable -->
<!-- by Tomcat and Spring beans aren't recognized -->
<!-- *************************************************** -->
<!-- Fixing JAR. -->
<move file="target/${project.build.finalName}/WEB-INF/lib/${project.artifactId}-${project.version}.jar"
tofile="target/${project.artifactId}-${project.version}_proguard_base.jar" />
<jar destfile="target/${project.build.finalName}/WEB-INF/lib/${project.artifactId}-${project.version}.jar">
<zipfileset
src="target/${project.artifactId}-${project.version}_proguard_base.jar"
includes="**/*.*" />
</jar>
</tasks>
</configuration>
</execution>
</executions>
</plugin>

Generate classes with gradle and jaxb for tests with different configuration

I'm using
id "com.bmuschko.docker-java-application" version "3.0.7"
https://github.com/rackerlabs/gradle-jaxb-plugin
gradle plugin and this configuration:
jaxb {
xsdDir = "${project.projectDir}/src/main/xsd/"
bindingsDir = "${project.projectDir}/src/main/xsd/"
xjc {
taskClassname = "org.jvnet.jaxb2_commons.xjc.XJC2Task"
args = [
'-Xfluent-api'
]
}
}
sourceSets.main.java.srcDirs += "${generatedSources}"
compileJava.dependsOn xjc
for tests I want to add more arguments to xjc. And run this new task with regular gradle build (depending the test task on this one). Maven solves this with help of executions
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.1</version>
<executions>
<execution>
<id>prod</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
<execution>
<id>test</id>
<phase>process-test-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generateDirectory>target/generated-test-sources/xjc</generateDirectory>
<addCompileSourceRoot>false</addCompileSourceRoot>
<addTestCompileSourceRoot>true</addTestCompileSourceRoot>
<args>
<arg>-Xfluent-api</arg>
<arg>-Xinheritance</arg>
<arg>-Xannotate</arg>
<arg>-Xvalue-constructor</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
<arg>-XtoString</arg>
</args>
</configuration>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/xsd</schemaDirectory>
<bindingDirectory>src/main/xsd</bindingDirectory>
<removeOldOutput>true</removeOldOutput>
<extension>true</extension>
<verbose>true</verbose>
<readOnly>true</readOnly>
<args>
<arg>-Xfluent-api</arg>
</args>
</configuration>
</plugin>
But how to solve it in gradle? I want as result 2 sets of classes in different folders - one for production code and one for tests (with additional jaxb plugins enabled).
Simple
task tst(type: org.openrepose.gradle.plugins.jaxb.task.JaxbXjc) {
}
Requires separate configuration
> No value has been specified for property 'bindings'.
> No value has been specified for property 'episodeDirectory'.
> No value has been specified for property 'generatedFilesDirectory'.
> No value has been specified for property 'schemasDirectory'.
> No value has been specified for property 'xsds'.
different from dsl. How to reuse the dsl-based configuration?

How to attach an artifact with assembly-plugin during custom lifecycle

i'm trying to create a plugin with a custom lifecycle :
/**
* #goal my-goal
* #execute lifecycle="my-custom-lifecycle" phase="attach-foo"
*/
public class MyMojo extends AbstractMojo {
...
with src/main/resources/META-INF/maven/lifecycle.xml file :
<lifecycles>
<lifecycle>
<id>attach-foo</id>
<phases>
<phase>
<id>package</id>
<executions>
<execution>
<goals>
<goal>
org.apache.maven.plugins:maven-assembly-plugin:single
</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptor>adescriptor.xml</descriptor>
</descriptorRefs>
</configuration>
</execution>
</executions>
</phase>
</phases>
</lifecycle>
</lifecycles>
Assembly-plugin is called unfortunately the zip artifact generated is not attached and install in repo...
Any ideas ?
Thanks
Which version of the maven-assembly-plugin was used? Per the plugin docs, there is an optional parameter attach available in versions 2.2-beta-1 and later. The value defaults to true meaning the created artifact should end up in the repository.