Why is inclusion of Kafka breaking my Spring controller's unit test? - spring

I am creating a Spring Boot web application that will utilise Kafka. I have created a trivial controller that will return a string.
// src/main/groovy/RootController.groovy
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ResponseBody
/**
* Controller to serve the index page
*/
#Controller
class RootController {
/**
* Serves the index page
*
* #return A string to appear on the index page
*/
#GetMapping("/")
#ResponseBody
String loadPage() {
return "root/index"
}
}
I have a unit test for this that uses Spock.
// src/test/groovy/RootControllerTest.groovy
import org.springframework.test.context.web.WebAppConfiguration
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import spock.lang.Specification
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
#WebAppConfiguration
class RootControllerTest extends Specification {
MockMvc mockMvc
// Setup for tests happens here˚
void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(new RootController()).build()
}
// Cleanup for tests happens here
void cleanup() {}
def "LoadPage should return the string root/index"() {
when: 'the loadPage endpoint is hit'
def response = mockMvc.perform(get("/"))
then: 'the method loadPage returns the string root/index'
response.andExpect(status().isOk())
.andExpect(content().string("root/index"))
}
}
When run, this test passes. I have the following build.gradle file that will build and run the tests.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.1.RELEASE")
}
}
plugins {
id 'org.springframework.boot' version '1.5.1.RELEASE' // Spring Boot
}
group 'dummy'
version '1.0-SNAPSHOT'
task wrapper(type: Wrapper) {
gradleVersion = '3.1'
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}
apply plugin: 'groovy'
sourceCompatibility = 1.8
def kafkaVersion = '0.10.0.0'
repositories {
maven {
name "confluent"
url "http://packages.confluent.io/maven/"
}
mavenCentral()
}
dependencies {
compile "org.codehaus.groovy:groovy-all:2.4.4" // Groovy version
compile "org.springframework.boot:spring-boot-starter-thymeleaf" // For thymeleaf
//compile "org.apache.kafka:kafka_2.11:${kafkaVersion}-cp1" // Kafka, as produced by confluent, hence -cp1 suffix
// Testing dependencies go here
testCompile "org.springframework:spring-test:4.3.6.RELEASE"
testCompile "org.spockframework:spock-core:1.0-groovy-2.4" // Spock (Mandatory)
}
However, when I uncomment the Kafka dependency, the build fails like this:
$ gradle clean test
:clean
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
:compileTestJava UP-TO-DATE
:compileTestGroovy
:processTestResources UP-TO-DATE
:testClasses
:test
RootControllerTest > LoadPage should return the string root/index FAILED
java.lang.ExceptionInInitializerError at RootControllerTest.groovy:21
Caused by: java.lang.IllegalStateException at RootControllerTest.groovy:21
1 test completed, 1 failed
:test FAILED
FAILURE: Build failed with an exception.
What is it that is causing the failure please?

Related

how to use a plugin inside a groovy plugin

I am trying to migrate tasks from build.gradle to a plugin that do it.
In my build.gradle I do this:
plugins {
//id 'java'
id 'war'
//https://plugins.gradle.org/plugin/org.gretty
id 'org.gretty' version '3.0.1'
id "com.github.dkorotych.gradle-maven-exec" version "2.2.1"
}
apply plugin: 'maven'
....
....
prepareFrontEnd (type: MavenExec, dependsOn: build) {
goals 'vaadin:prepare-frontend'
}
task buildFrontEnd (type: MavenExec, dependsOn: prepareFrontEnd) {
goals 'vaadin:build-frontend'
}
Now I am moving this stuff to a plugins:
package com.github.mdre.hgvaadinplugin
import org.gradle.api.Plugin;
import org.gradle.api.Project;
//import com.github.dkorotych.gradle.maven.exec.MavenExec;
class HGVaadinPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
println "Hybrid Gradle Vaaadin plugin."
project.plugins.apply('com.github.dkorotych.gradle-maven-exec')
// project.getPluginManager().apply('gradle-maven-exec-plugin')
project.task('prepareFrontEnd', type: MavenExec){
dependsOn build
doLast {
goal 'vaadin:prepare-frontend'
}
}
}
}
If I try to import the class MavenExec I get this error:
> Task :compileGroovy FAILED
startup failed:
/home/mdre/Proyectos/HGVaadinPlugin/src/main/groovy/com/github/mdre/hgvaadinplugin/HGVaadinPlugin.groovy: 5: unable to resolve class com.github.dkorotych.gradle.maven.exec.MavenExec
# line 5, column 1.
import com.github.dkorotych.gradle.maven.exec.MavenExec;
^
and if I comment the import line, I get this error in the project that use the plugin:
What went wrong:
A problem occurred evaluating root project 'VaadinFlowLab'.
Failed to apply plugin [id 'com.github.mdre.hgvaadinplugin']
No such property: MavenExec for class: com.github.mdre.hgvaadinplugin.HGVaadinPlugin
How could I do this?
Thanks.
Well, I fix it!
I forget to include the dependency class in the final jar. So all of I need was to add this to the build.config:
configurations {
// configuration that holds jars to include in the jar
extraLibs
}
dependencies {
....
....
//necesario para crear un fatJar
extraLibs "gradle.plugin.com.github.dkorotych.gradle.maven.exec:gradle-maven-exec-plugin:2.2.1"
configurations.compile.extendsFrom(configurations.extraLibs)
}
jar {
from {
configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) }
}
}
and now it is working!!

TestFX Spock Gradle Project Openjdk 11 - Zero Test Results

Why is my Spock test not executed and I get zero test results when I execute:
./gradlew clean test
with my TestFX Spock Gradle Project with Openjdk 11?
Here's the zero test results:
My Spock test class gets compiled OK but not executed.
Here's my console:
Working Directory: /home/~/EclipseProjects/gradleTestfxSpock
Gradle user home: /home/~/.gradle
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 5.0
Java Home: /usr/lib/jvm/jdk-11.0.2+9
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
Gradle Tasks: clean test
> Configure project :
Found module name 'mtd'
> Task :clean
> Task :compileJava
> Task :compileGroovy NO-SOURCE
> Task :processResources
> Task :classes
> Task :compileTestJava NO-SOURCE
> Task :compileTestGroovy
> Task :processTestResources
> Task :testClasses
> Task :test
BUILD SUCCESSFUL in 6s
6 actionable tasks: 6 executed
Here's my build.gradle:
plugins {
id 'org.openjfx.javafxplugin' version '0.0.7'
id 'application'
id 'groovy'
}
mainClassName = 'mtd/gradleTestfxSpock.Main'
sourceCompatibility = 11
targetCompatibility = 11
repositories {
jcenter()
}
dependencies {
implementation 'org.testfx:testfx-spock:4.0.15-alpha'
testCompile 'org.testfx:testfx-core:4.0.15-alpha'
testCompile (group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5')
testCompile ('org.codehaus.groovy:groovy-all:2.5.6')
testRuntime(
'com.athaydes:spock-reports:1.2.7',
'cglib:cglib-nodep:3.2.4'
)
}
javafx {
version = "11.0.2"
modules = [ 'javafx.controls',
'javafx.fxml',
'javafx.web'
]
}
compileJava {
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'javafx.controls',
'--add-modules', 'javafx.fxml',
'--add-modules', 'javafx.web'
]
}
}
test {
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'ALL-MODULE-PATH',
'--add-exports', 'javafx.graphics/com.sun.javafx.application=org.testfx'
]
}
}
Here's my module-info.java:
module mtd {
requires javafx.controls;
requires javafx.fxml;
requires transitive javafx.graphics;
requires javafx.web;
requires org.testfx;
requires testfx.spock;
opens gradleTestfxSpock to javafx.graphics;
exports gradleTestfxSpock;
}
Here's my Spock test code:
package gradleTestfxSpock;
import org.testfx.framework.spock.ApplicationSpec;
import javafx.stage.Stage
public class MainTest extends ApplicationSpec{
def "Main Test 01"() {
expect:
println("you are in Main test 01");
}
#Override
public void start(Stage arg0) throws Exception {
// TODO Auto-generated method stub
}
}
Here's my JavaFX code:
package gradleTestfxSpock;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("/fxml/sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
and controller:
package gradleTestfxSpock;
public class Controller {
}
Here's my eclipse gradle project structure:
In other eclipse gradle projects I have successfully executed a TestFX Junit4 test without Spock:
and separately I have successfully executed the same Spock Test without TestFX and without JUnit:
I did notice some warnings on this Spock test:
Working Directory: /home/~/EclipseProjects/gradleSpock
Gradle user home: /home/~/.gradle
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 5.0
Java Home: /usr/lib/jvm/jdk-11.0.2+9
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
Gradle Tasks: clean test
> Task :clean
> Task :compileJava
> Task :compileGroovy NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes
> Task :compileTestJava NO-SOURCE
> Task :compileTestGroovy
> Task :processTestResources NO-SOURCE
> Task :testClasses
> Task :test
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.codehaus.groovy.vmplugin.v7.Java7$1 (file:/home/dm/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int)
WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.vmplugin.v7.Java7$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
BUILD SUCCESSFUL in 9s
4 actionable tasks: 4 executed
Conclusion
If TestFX with JUnit works, and Spock alone works, but TestFX with Spock doesn't work then is there something wrong with configuring:
'org.testfx:testfx-spock:4.0.15-alpha'
Any ideas or help greatly appreciated.
ps Forgot to say that I also created the TestFX/Spock project in Netbeans duplicating the eclipse project, and I got the same result!
More Tests
More combinations of testing following Leonard Bruenings very good suggestions in comments below unfortunately didn't work.
My amended module-info.java looks like:
module mtd {
requires javafx.controls;
requires javafx.fxml;
requires transitive javafx.graphics;
requires javafx.web;
requires org.testfx.junit;
requires org.testfx;
requires testfx.spock;
requires spock.core;
requires junit;
opens gradleTestfxSpock to javafx.graphics, org.testfx, testfx.spock, spock.core, junit, org.testfx.junit;
exports gradleTestfxSpock;
}
And I added this to my gradle.build dependencies just in case:
implementation 'org.testfx:testfx-junit:4.0.15-alpha'
Still no joy...
Solution
I found that this plugin was the problem and was stopping successful execution of my Spock test:
`plugins {
id 'org.openjfx.javafxplugin' version '0.0.7'
}`
When I removed it from my build.gradle my TestFX Spock test worked OK.
With this reworked build.gradle and module-info.java I can successfully execute my Spock test:
plugins {
id 'application'
id 'groovy'
}
ext {
moduleName = "mtd"
mainQualifiedClassName = "gradleTestfxSpock.Main"
}
application {
mainClassName = "$moduleName/$mainQualifiedClassName"
}
sourceCompatibility = 11
targetCompatibility = 11
repositories {
jcenter()
}
dependencies {
implementation("org.openjfx:javafx-fxml:11:linux")
implementation("org.openjfx:javafx-web:11:linux")
implementation("org.openjfx:javafx-media:11:linux")
implementation("org.openjfx:javafx-base:11:linux")
implementation("org.openjfx:javafx-graphics:11:linux")
implementation("org.openjfx:javafx-controls:11:linux")
testImplementation ('org.testfx:testfx-spock:4.0.15-alpha')
testImplementation ('org.testfx:testfx-core:4.0.15-alpha')
testImplementation (group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5')
testImplementation ('org.codehaus.groovy:groovy-all:2.5.6')
testRuntimeOnly (
'com.athaydes:spock-reports:1.2.7',
'cglib:cglib-nodep:3.2.4'
)
}
compileJava {
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'javafx.controls',
'--add-modules', 'javafx.fxml',
'--add-modules', 'javafx.web'
]
}
}
run {
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--patch-module', "$moduleName=" + files(sourceSets.main.output.resourcesDir).asPath,
'--module', mainClassName
]
}
}
I needed to add into the run section of the build.gradle:
'--module', mainClassName
-so that the mainClassName can be found
'--patch-module', "$moduleName=" + files(sourceSets.main.output.resourcesDir).asPath
-to provide access to resource files eg getClass().getResource("/fxml/sample.fxml")
module mtd {
requires javafx.controls;
requires javafx.fxml;
requires transitive javafx.graphics;
requires javafx.web;
exports gradleTestfxSpock;
}
I'm no expert in any of this, which is probably why it's taken me ages and ages to get to this point, but FWIW I thought I might just mention that I have managed to get it working: by "it" I mean: Java 11, JavaFX, TestFX-Spock, and using the javafxplugin. One guy who helped me, José Pereda, appears to recommend using it if you can. So I just thought I'd show my files stripped down to the bare minimum. There's no module-info.java, and I'm using Groovy for my app code as well as for Spock and Gradle.
(stripped-down) build.gradle:
plugins {
id 'java-library'
id 'groovy'
id 'eclipse'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories {
mavenCentral()
}
dependencies {
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:27.0.1-jre'
// although not using JUnit I think it's best to leave this line
// (included at start by Gradle):
testImplementation 'junit:junit:4.12'
implementation 'org.codehaus.groovy:groovy-all:2.5.8'
testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
testImplementation 'org.testfx:testfx-spock:4.0.15-alpha'
}
mainClassName = 'core.App'
group 'Project'
version '1.0'
sourceCompatibility = 11
javafx {
version = "13"
modules = [ "javafx.controls", "javafx.fxml" ]
}
src/main/groovy/core/main.groovy:
package core
// (imports omitted)
public class App extends Application {
void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"))
primaryStage.title = "Hello World"
primaryStage.scene = new Scene(root, 300, 275)
primaryStage.show()
}
def main(String[] args) {
launch( App.class, args)
}
}
class Controller {
#FXML
TextField inputField
#FXML
Label label
#FXML
Button applyButton
public void applyButtonClicked () {
label.text = inputField.text
}
}
src/test/groovy/core/test.groovy:
package core
// (imports omitted)
class FuncSpec extends ApplicationSpec {
void init() throws Exception {
FxToolkit.registerStage { new Stage() }
}
def cleanup() {
FxToolkit.hideStage()
// as explained for org.testfx.robot.KeyboardRobot, passing an
// empty array of the appropriate type releases all keys/mouse buttons
// NB this is how you create an empty typed array in Groovy
release(new KeyCode[0])
release(new MouseButton[0])
}
#Override
public void start(Stage stage) throws Exception {
Parent mainNode = FXMLLoader.load( App.class.getResource("sample.fxml"))
stage.scene = new Scene(mainNode)
stage.show()
stage.toFront()
}
def "test English input"(){
when:
Label label = lookup("#label").query()
clickOn("#inputField")
write("This is a test!")
clickOn("#applyButton")
then:
label.text == "This is a test!"
}
}
src/main/resources/core/sample.fxml // NB note inclusion of "core" (package name)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane alignment="center" hgap="10" vgap="10"
xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/8.0.111"
fx:controller="core.Controller">
<children>
<TextField layoutX="15.0" layoutY="25.0" fx:id="inputField" />
<Label layoutX="15.0" layoutY="84.0" text="TEXT GOES HERE"
fx:id="label" />
<Button layoutX="124.0" layoutY="160.0" mnemonicParsing="false"
text="Apply" onAction="#applyButtonClicked" fx:id="applyButton" />
</children>
</GridPane>

Gradle: how to make rule-created ZipTask as maven publication artifact

I want to create a maven publication from inside a RuleSource that will be published via the maven-publish plugin. The artifacts of the publication are the outputs from a series of Zip tasks that are created from rules. When I try to add the artifacts, I get a circular rule exception.
Here is my very simple build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
}
}
task wrapper(type: Wrapper) {
gradleVersion = '3.3'
}
apply plugin: 'groovy'
apply plugin: 'testpub'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.7'
}
The testpub plugin exists in the buildSrc directory. To be able to apply it as above, it requires the following properties file:
// buildSrc/src/main/resources/META_INF/gradle-plugins/testpub.properties
implementation-class=TestPubPlugin
Here is the very simple plugin file:
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.model.RuleSource
import org.gradle.api.Task
import org.gradle.model.Mutate
import org.gradle.model.Finalize
import org.gradle.api.tasks.bundling.Zip
import org.gradle.model.ModelMap
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
class TestPubPlugin implements Plugin<Project> {
void apply(Project project) {
project.configure(project) {
apply plugin: 'maven-publish'
publishing {
repositories {
maven {
url "someUrl"
}
}
}
}
}
static class TestPubPluginRules extends RuleSource {
#Mutate
public void createSomeTasks(final ModelMap<Task> tasks) {
5.times { suffix ->
tasks.create("someTask${suffix}", Zip) {
from "src"
destinationDir(new File("build"))
baseName "someZip${suffix}"
}
}
}
#Mutate
public void configurePublishingPublications(final PublishingExtension publishing, final ModelMap<Task> tasks) {
// Intention is to create a single publication whose artifacts are formed by the `someTaskx` tasks
// where x = [0..4]
publishing {
publications {
mavPub(MavenPublication) {
tasks.matching {it.name.startsWith('someTask')}.each { task ->
artifact(task)
}
}
}
}
}
}
}
The plugin creates a number of tasks called someTaskx where x=[0..4]. They simply zip up the src directory. I want to add the output files as artifacts to the single MavenPublication. However, I get the following exception:
* What went wrong:
A problem occurred configuring root project 'testpub'.
> A cycle has been detected in model rule dependencies. References forming the cycle:
tasks
\- TestPubPlugin.TestPubPluginRules#createSomeTasks(ModelMap<Task>)
\- MavenPublishPlugin.Rules#realizePublishingTasks(ModelMap<Task>, PublishingExtension, File)
\- PublishingPlugin.Rules#tasksDependOnProjectPublicationRegistry(ModelMap<Task>, ProjectPublicationRegistry)
\- projectPublicationRegistry
\- PublishingPlugin.Rules#addConfiguredPublicationsToProjectPublicationRegistry(ProjectPublicationRegistry, PublishingExtension, ProjectIdentifier)
\- publishing
\- TestPubPlugin.TestPubPluginRules#configurePublishingPublications(PublishingExtension, ModelMap<Task>)
\- tasks
What is wrong and how do I fix it?
I don't fully understand why is this a "cycle", but the rule methods always have one mutable part (the subject) and zero or more immutable (the inputs). In your second method, you are passing the publishing as the subject you want to change and the tasks as the input. I thought that would be ok, but obviously it isn't.
You might have tried to switch the method arguments, pass the tasks first and then the PublishingExtension, but you would likely not be able to change it (as gradle docs say it's immutable).
I am not sure what exactly is your use case and there might be an easier solution that doesn't use the rules, or plugin at all. Maybe you could ask another question with the original requirement instead of this specific problem.
But back to your issue. The solution to your problem might be something like this:
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.bundling.Zip
import org.gradle.model.Defaults
import org.gradle.model.ModelMap
import org.gradle.model.Mutate
import org.gradle.model.RuleSource
class TestPubPlugin implements Plugin<Project> {
void apply(Project project) {
project.configure(project) {
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
groupId 'com.example'
artifactId 'artifact'
}
}
repositories {
maven {
url "someUrl"
}
}
}
}
}
static class TestPubPluginRules extends RuleSource {
static final def buffer = []
#Defaults
public void createSomeTasks(final ModelMap<Task> tasks) {
5.times { suffix ->
tasks.create("someTask${suffix}", Zip) {
from "src"
destinationDir(new File("build"))
baseName "someZip${suffix}"
}
}
tasks.each { task ->
if (task.name.startsWith('someTask'))
buffer << task
}
}
#Mutate
public void configurePublishingPublications(PublishingExtension extension) {
MavenPublication p = extension.publications[0]
buffer.each { task ->
p.artifact(task)
}
}
}
}
The hack here is to run the mutator of the tasks first (#Defaults phase should run before #Mutate) and save the tasks, so we don't need to ask for them later. Rules can include static final fields, so we use a list here.
Then we run the publication enhancer. The code you have used won't work. It works in the config part, but not in the groovy class. So I have prepared the publication and then just added the artifacts from the buffer.
I ran gradlew publish and got:
Execution failed for task ':publishMavenPublicationToMavenRepository'.
> Failed to publish publication 'maven' to repository 'maven'
> Invalid publication 'maven': artifact file does not exist: 'build\someZip0.zip'
So it seems it's working.

Unable to run a TestNG with Gradle

I have a simple code which runs with TestNG, but I am unable to run the same with Gradle, as it says no main method is found, which is, well, not surprising since I am using annotations.
But in such a scenario, how to run the code if I must use Gradle.
Kindly note, I am very new to Gradle, and do not harbour much knowledge about the same.
Code:
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class tryTestNG
{
#BeforeClass
public void setup()
{
System.out.println("I am in Setup");
}
#Test
public void test()
{
System.out.println("I am in Test");
}
#AfterClass
public void tearDown()
{
System.out.println("I am in tearDown");
}
}
The above code runs perfectly with TestNG Library. However not with Gradle.
Here is my Gradle Build setup:
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'tryTestNG'
sourceCompatibility = 1.7
targetCompatibility = 1.7
version = '1.0'
repositories {
mavenCentral()
}
test {
useTestNG()
}
dependencies {
compile group: 'org.testng', name: 'testng', version: '6.9.10'
}
The Gradle returns that there is no Main Method.
Working Directory: /home/avirup/MyWorkspace/JavaWorkspace/TestNGGradle
Gradle User Home: /home/avirup/.gradle
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 2.9
Java Home: /usr/lib/jvm/java-8-oracle
JVM Arguments: None
Program Arguments: None
Gradle Tasks: run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:runError: Main method not found in class tryTestNG, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':run'.
> Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 0.514 secs
Thanks for your help.
There's no need to use application plugin to run tests.
The build.gradle should be:
apply plugin: 'java'
sourceCompatibility = 1.7
targetCompatibility = 1.7
version = '1.0'
repositories {
mavenCentral()
}
test {
useTestNG()
}
dependencies {
compile group: 'org.testng', name: 'testng', version: '6.9.10'
}
And the command: gradle test. Also, put tryTestNG under src/test/java and name it with capital letter.
Here is a demo.
Also mind that println statements from tests won't be visible in console. To view them navigate to test report. It's under: <project_dir>/build/reports/tests/index.html.

Not able to execute Jbehave with Gradle using Serenity Framewrok

I am using Serenity - JBehave framework. After creation of sample script, I am able to execute Junit runner class from eClipse however when I am trying to execute any of the below command from command prompt it is giving me error.
$gradle clean test aggregate
$gradle clean test
$gradle clean build
The error message is same in all cases, as below:
org.gradle.TestRunnerClass > initializationError FAILED
java.lang.RuntimeException
Caused by: java.lang.RuntimeException
Caused by: java.lang.IllegalArgumentException
Caused by: java.lang.ClassNotFoundException
1 test completed, 1 failed
:test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///C:/$ /build/reports/tests/index.html
Below are the details:
Test Runner class:
package org.gradle;
import net.serenitybdd.jbehave.SerenityStories;
public class TestRunnerClass extends SerenityStories{}
Sample Step Definition class:
package org.gradle.stepDef;
import net.thucydides.core.annotations.Step;
import net.thucydides.core.annotations.Steps;
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
public class StepDefSticky {
#Given("User is on Sticky note home page")
public void givenUserIsOnStickyNoteHomePage() {
System.out.println("I am in Given");
}
#When("User clicks on Add Note button")
public void whenUserClicksOnAddNoteButton() {
System.out.println("I am in When");
}
#Then("Sticky note pop up should get open")
public void thenStickyNotePopUpShouldGetOpen() {
System.out.println("I am in Then");
}
}
Please see the package structure carefully.
Below is the build.gradle I am using
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'net.serenity-bdd.aggregator'
apply plugin: 'com.jfrog.bintray'
sourceCompatibility = 1.8
version = '1.0'
def poiVersion = "3.10.1"
repositories {
maven { url "repoUrl" }
}
buildscript {
repositories {
maven { url "repoURL" }
}
dependencies {
classpath("net.serenity-bdd:serenity-gradle-plugin:1.0.47")
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:0.6'
classpath 'org.ajoberstar:gradle-git:0.12.0'
}
}
ext {
bintrayBaseUrl = 'https://api.bintray.com/maven'
bintrayRepository = 'maven'
bintrayPackage = 'serenity-cucumber'
projectDescription = 'Serenity Cucumber integration'
if (!project.hasProperty("bintrayUsername")) {
bintrayUsername = 'wakaleo'
}
if (!project.hasProperty("bintrayApiKey")) {
bintrayApiKey = ''
}
serenityCoreVersion = '1.0.47'
cucumberJVMVersion = '1.2.2'
}
dependencies {
testCompile('junit:junit:4.11')
testCompile('org.assertj:assertj-core:1.7.0')
testCompile('org.slf4j:slf4j-simple:1.7.7')
//JBehave jar files
testCompile 'net.serenity-bdd:core:1.0.47'
testCompile 'net.serenity-bdd:serenity-jbehave:1.0.21'
testCompile 'net.serenity-bdd:serenity-junit:1.0.47'
// Apache POI plugin for excel read
compile "org.apache.poi:poi:${poiVersion}"
compile "org.apache.poi:poi-ooxml:${poiVersion}"
compile "org.apache.poi:ooxml-schemas:1.1"
}
gradle.startParameter.continueOnFailure = true
uploadArchives {
repositories { flatDir { dirs 'repos' } }
}
task wrapper(type: Wrapper) { gradleVersion = '2.3' }
I have stored the .story file under the src/test/resources package.
Please help me to understand where I am making mistake. Thanks for your help on this.
Enable standard out and standard error in your build.gradle file:
test {
testLogging {
showStandardStreams = true
}
}
And to make sure all your stories run, add a TestSuite class:
#RunWith(Suite.class)
#SuiteClasses({ Story1.class, Story2.class})
public class TestSuite { }
Note: Story1 & Story2 are the names of the test runners to match a JBehave Gherkin files named Story1.story & Story2.story & step files names Story1Steps.java & Story2Steps.java according to Serenity naming conventions.

Resources