Maven SCR Plugin - Not generating OSGI-INF folder - maven

I have been having trouble getting my SCR plugin working. I have searched as much as I could bur only found examples that were not similar to the structure I am required to use. Snippets of POMs below. These are pretty much the default generated by the CQ project archetype. All dependencies are there, so it is probably not that. Here is the output of the build:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building project Bundle 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) # project-bundle ---
[INFO] Deleting C:\project-path\target
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) # bundle ---
[debug] execute contextualize
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\project-path\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) # project-bundle ---
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 4 source files to C:\project-path\target\classes
[INFO]
[INFO] --- maven-scr-plugin:1.7.4:scr (generate-scr-descriptor) # project-bundle ---
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) # project-bundle ---
[debug] execute contextualize
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\project-path\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) # project-bundle ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:9c6abc2:test (default-test) # project-bundle ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-bundle-plugin:2.3.6:bundle (default-bundle) # project-bundle ---
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) # project-bundle ---
[INFO] Installing C:\project-path\target\project-bundle-1.0-SNAPSHOT.jar to C:\user-path\.m2\repository\com\project\cq\project-bundle\1.0-SNAPSHOT\project-bundle-1.0-SNAPSHOT.jar
[INFO] Installing C:\project-path\pom.xml to C:\user-path\.m2\repository\com\project\cq\project-bundle\1.0-SNAPSHOT\project-bundle-1.0-SNAPSHOT.pom
[INFO]
[INFO] --- maven-bundle-plugin:2.3.6:install (default-install) # project-bundle ---
[INFO] Installing com/project/cq/project-bundle/1.0-SNAPSHOT/project-bundle-1.0-SNAPSHOT.jar
[INFO] Writing OBR metadata
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.189s
[INFO] Finished at: Wed Apr 17 10:29:17 CDT 2013
[INFO] Final Memory: 15M/221M
[INFO] ------------------------------------------------------------------------
The key part of the output is the [INFO] --- maven-scr-plugin:1.7.4:scr (generate-scr-descriptor) # project-bundle ---. It appears that it is not generating anything even though the annotations exist on the class.
Parent POM Snippet:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<version>1.7.4</version>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.6</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- use version 2.3.2 to have java 1.5 as the default -->
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
<version>2.3.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<version>2.0.6</version>
</plugin>
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>content-package-maven-plugin</artifactId>
<version>0.0.13</version>
</plugin>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the
Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<versionRange>[1.7.4,)</versionRange>
<goals>
<goal>scr</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
Child POM Snippet:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>generate-scr-descriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>project.project-bundle</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<configuration>
<slingUrl>http://${crx.host}:${crx.port}/apps/project/install</slingUrl>
<usePut>true</usePut>
</configuration>
</plugin>
</plugins>
</build>
Code being built:
package com.project.cq.examples.dictionaryservice.impl;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import com.project.cq.examples.dictionaryservice.DictionaryService;
#Component(immediate = true, metatype = true, label = "Service Implementation", description = "The implementation for the Service")
#Service
public class DictionaryServiceServletImpl implements DictionaryService {
#Property(label = "Words", description = "The list of words.")
private static final String PROP_WORDS = "words";
// The set of words
private String[] words;
private boolean active;
private boolean modified;
#Override
public boolean checkWord(String word) {
word = word.toLowerCase();
// This is very inefficient
for (int i = 0; i < words.length; i++) {
if (words[i].equals(word)) {
return false;
}
}
return true;
}
protected void activate(ComponentContext context) {
active = true;
dictionary = (String[]) context.getProperties().get(
PROP_WORDS);
}
protected void deactivate(ComponentContext context) {
dictionary = null;
active = false;
}
protected void modified(ComponentContext context) {
modified = true;
dictionary = (String[]) context.getProperties().get(
PROP_WORDS);
}
}
Any help is greatly appreciated.

I'm guessing you're using <packaging>bundle</packaging>, if so I got this working by upgrading maven-scr-plugin to 1.9.0, with org.apache.felix.scr.annotations # 1.7.0
I put a tarball of a working version here: https://dl.dropboxusercontent.com/u/2465717/com.stackoverflow.osgi.scr.tgz
Note: you can enable the Eclipse m2e lifecycle mapping - it works well (Juno SR2), generating SCR component errors in the normal Problems console. Change the action <ignore/> to:
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
<runOnConfiguration>true</runOnConfiguration>
</execute>
</action>
Also while the spec indicates the SCR runtime will search for overloaded de/activate methods - as personal preference I would use #Activate, #Deactive and #Modified on the respective methods to make the intent explicit (in code and generated XML). But each to their own.

I suggest that you
upgrade to the latest version of the maven-scr-plugin
generate debug with -X, e.g. mvn -X compile

Upgrading to 1.9.0 worked for me. Are we saying plugin v1.7.4 does not generate descriptors. Why would it be so, isn't that the core task of maven-scr-plugin.

Related

Maven does not see testng tests when testing Spring Boot Application is running

I setup simple Spring Boot project to serve basic HTML pages. I wrote a kind of integration tests with testNG. Now, I want to run my tests with maven does not see my tests.
STR:
Run mvn spring-boot:run
Run mvn test
Output:
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------------< vznd:selenium >----------------------------
[INFO] Building selenium 1.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) # selenium ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 0 resource
[INFO] Copying 27 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) # selenium ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) # selenium ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] skip non existing resourceDirectory C:\Users\vladyslav.kovalenko\OneDrive - FORM.com\Documents\den\selenium-webdriver-tests\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) # selenium ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:3.0.0-M6:test (default-test) # selenium ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.963 s
[INFO] Finished at: 2022-05-09T13:03:51+01:00
[INFO] ------------------------------------------------------------------------
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>vznd</groupId>
<artifactId>selenium</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven-surefire-plugin.version>3.0.0-M6</maven-surefire-plugin.version>
<testng.version>7.5</testng.version>
<selenium-java.version>3.141.59</selenium-java.version>
<commons-io.version>2.11.0</commons-io.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-java.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<webdriver.chrome.driver>/tmp/chromedriver/chromedriver</webdriver.chrome.driver>
</systemPropertyVariables>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
testng.xml:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="SeleniumApp Tests" parallel="false">
<test name="Selenium Test">
<classes>
<class name="vznd.selenium.AlertsControllerTest"/>
<class name="vznd.selenium.GettingBrowserInformationTest"/>
<class name="vznd.selenium.FramesTest"/>
<class name="vznd.selenium.BrowserNavigationTest"/>
<class name="vznd.selenium.KeyboardActionsTest"/>
<class name="vznd.selenium.WindowsTest"/>
</classes>
</test>
</suite>
Test example:
package vznd.selenium;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class FramesTest extends BaseTest {
#BeforeMethod
public void openPageWithIframes() {
driver.get(HTMLPath.FRAMES);
}
#Test
public void switchToFrameUsingWebElement() {
WebElement greenFrame = driver.findElement(By.id("first-iframe"));
driver.switchTo().frame(greenFrame);
WebElement table = driver.findElement(By.cssSelector("table[id='green-table']"));
Assert.assertNotNull(table, "The table WebElement object was null!");
}
}
Spring Boot Application:
package vznd.selenium;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SeleniumApp {
public static void main(String[] args) {
SpringApplication.run(SeleniumApp.class, args);
}
}
Controller example:
package vznd.selenium.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class FramesController {
#GetMapping("/iframes")
public String iframes() {
return "iframes";
}
}
I tried to google about similar problems, but most answers is about naming test classes with *Test suffix and that is not my case.
The tests are executed in IDEA by right-click on the project -> Run -> All tests.
Please, advice me how I can get tests executed with maven.
If you see the logs surefire is not detecting TestNG.
Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
If you remove SpringBoot will be: Using auto detected provider org.apache.maven.surefire.testng.TestNGProvider
Try adding TestNG dependency to surefire plugin:
<project>
...
<dependencies>
...
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
<version>3.0.0-M5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<systemPropertyVariables>
<webdriver.chrome.driver>/tmp/chromedriver/chromedriver</webdriver.chrome.driver>
</systemPropertyVariables>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
<version>3.0.0-M5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

Cucumber and SpringBootTest via Failsafe plugin

I'm having issues getting my cucumber tests to be invoked. I'm using SpringBootTest for these and invoking them via the maven failsafe plugin. I know for a fact that the features path is correct because 1. If I run the tests directly using Intellij's runner, it runs all the tests and 2. If I run via Maven and use the wrong path Cucumber itself throws exceptions.
Please find relevant project excerpts below:
CucumberIT.java
#RunWith(Cucumber.class)
#CucumberOptions(
features = {
"src/test/resources/features/"
},
glue = {
"classpath:com.company.pkg.integration.steps"
}
)
public class CucumberIT {}
CucumberContextLoader to load the Spring Context for all features to access
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
#ContextConfiguration(initializers = ConfigInitializer.class)
public class CucumberContextLoader {
#Before // Note this is Cucumbers Before, not JUnits.
public void setUp() {
}
}
pom.xml Profile for running integration tests:
<profile>
<id>integration-test</id>
<properties>
<skip.surefire.tests>true</skip.surefire.tests>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
The output that this all gives me is:
[INFO] --- maven-failsafe-plugin:3.0.0-M4:integration-test (default) # my-rest-service ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
Mar 02, 2020 1:19:56 PM io.cucumber.junit.Cucumber <init>
WARNING: By default Cucumber is running in --non-strict mode.
This default will change to --strict and --non-strict will be removed.
You can use --strict or #CucumberOptions(strict = true) to suppress this warning
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 23.971 s
[INFO] Finished at: 2020-03-02T13:19:57-05:00
[INFO] ------------------------------------------------------------------------

Jacoco + JUnit 5.0 DynamicTest not working

I am trying to generate a code coverage report using Jacoco with JUnit 5 and Spring Boot. And I"m trying to use the DynamicTest feature of JUnit 5. It runs successfully but the Dynamic Tests are not covered in the test coverage report generated by jacoco. Is JUnit 5 Dynamic Test not covered by Jacoco at the moment?
Here is the code:
#RunWith(JUnitPlatform.class)
#SelectPackages("com.troll.jpt.abc.model")
#SelectClasses({Status.class})
public class DynamicModelTester {
private Status status;
#BeforeEach
public void setUp() {
status = new Status();
}
#TestFactory
public Stream<DynamicTest> checkDynamicTestsFromStream() {
List<String> input = Arrays.asList("abc");
List<String> output = Arrays.asList("abc");
status.setCode(input.get(0));
return input.stream().map(str -> DynamicTest.dynamicTest("status test", () -> {
assertEquals(output.get(0), status.getCode());
}));
}
}
The jacoco plugin I'm using is as :
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2-SNAPSHOT</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>target/jacoco.exec</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>target/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
It runs successfully but the Dynamic Tests are not covered in the test coverage report generated by jacoco.
jacoco-maven-plugin:report doesn't display coverage in tests, it displays coverage of a target of a test - in your case target seems to be class Status, whose definition is completely absent. For future I highly recommend to read https://stackoverflow.com/help/mcve and follow its recommendations, especially part about "Complete":
Make sure all information necessary to reproduce the problem is included
Generic answer on questions like "does JaCoCo support JUnit 5 Dynamic Test?" is: JaCoCo records fact that code was executed independently from the way how it was executed - via JUnit 4 or JUnit 5, or even manually or whatever the other way of execution.
And generic answer on questions like "why some code is not marked as covered?" is: make sure that code is actually executed, in case of automatic tests this means - make sure that these tests are actually executed.
But let's give a try with JUnit 5 Dynamic Test. In absence of src/main/java/Status.java I'll assume that it is something like
public class Status {
private String code;
public void setCode(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
No idea why you need systemPropertyVariables, snapshot version of jacoco-maven-plugin, multiple executions of report and redundant specification of dataFile with its default value, so will also assume that complete pom.xml after slight cleanup looks like
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.1</version>
<configuration>
<outputDirectory>target/jacoco-ut</outputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
After placing
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
#RunWith(JUnitPlatform.class)
#SelectPackages("com.troll.jpt.abc.model")
#SelectClasses({Status.class})
public class DynamicModelTester {
private Status status;
#BeforeEach
public void setUp() {
status = new Status();
}
#TestFactory
public Stream<DynamicTest> dynamicTestsFromStream() {
List<String> input = Arrays.asList("abc");
List<String> output = Arrays.asList("abc");
status.setCode(input.get(0));
return input.stream().map(str -> DynamicTest.dynamicTest("status test", () -> {
assertEquals(output.get(0), status.getCode());
}));
}
}
into src/test/java/DynamicModelTester.java and execution of mvn clean verify:
[INFO] --- maven-surefire-plugin:2.21.0:test (default-test) # example ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) # example ---
[INFO] Building jar: /private/tmp/jacoco/target/example-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.1:report (default) # example ---
[INFO] Skipping JaCoCo execution due to missing execution data file.
Last line is quite suspicious as well as absence of number of tests executed by maven-surefire-plugin together with absence of target/surefire-reports/.
Let's rename DynamicModelTester into DynamicModelTest and execute mvn clean verify again:
[INFO] --- maven-surefire-plugin:2.21.0:test (default-test) # example ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running DynamicModelTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.023 s - in DynamicModelTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) # example ---
[INFO] Building jar: /private/tmp/jacoco/target/example-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- jacoco-maven-plugin:0.8.1:report (default) # example ---
[INFO] Loading execution data file /private/tmp/jacoco/target/jacoco.exec
[INFO] Analyzed bundle 'example' with 1 classes
Compared to previous attempt test was executed this time. And coverage report target/jacoco-ut/default/Status.html looks like:
I believe that the reason of the fact that test is not executed lies in a default value of includes of maven-surefire-plugin :
A list of elements specifying the tests (by pattern) that
should be included in testing. When not specified and when the test
parameter is not specified, the default includes will be
<includes>
<include>**/Test*.java</include>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
<include>**/*TestCase.java</include>
</includes>
DynamicModelTester.java doesn't match any of these patters, while DynamicModelTest.java matches second, but I'll leave verification of this as a little exercise.

Firefox driver won't connect using Serenity

I'm trying to run a simple test with Firefox, using Serenity.
This is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>serenity.test</groupId>
<artifactId>firefox</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<serenity.version>1.4.0</serenity.version>
<serenity.maven.version>1.4.0</serenity.maven.version>
<webdriver.driver>firefox</webdriver.driver>
<surefire.rerunFailingTestsCount>0</surefire.rerunFailingTestsCount>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18</version>
<configuration>
<includes>
<include>**/features/**/*.java</include>
</includes>
<systemProperties>
<webdriver.driver>${webdriver.driver}</webdriver.driver>
<surefire.rerunFailingTestsCount>${surefire.rerunFailingTestsCount}</surefire.rerunFailingTestsCount>
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>net.serenity-bdd.maven.plugins</groupId>
<artifactId>serenity-maven-plugin</artifactId>
<version>${serenity.maven.version}</version>
<dependencies>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-core</artifactId>
<version>${serenity.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>serenity-reports</id>
<phase>post-integration-test</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-core</artifactId>
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-screenplay</artifactId>
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-screenplay-webdriver</artifactId>
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-junit</artifactId>
<version>${serenity.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.18</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
And this is my test class:
public class FirefoxTest {
#Managed
WebDriver driver;
private Actor actor;
#Before
public void setup(){
actor = Actor.named("Firefox user");
actor.can(BrowseTheWeb.with(driver));
}
#Test
public void open_browser(){
actor.attemptsTo(Open.url("www.google.com"));
}
}
Running "mvn verify" I get the following log:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building firefox 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) # firefox ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) # firefox ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) # firefox ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\work\verso3\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) # firefox ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.20:test (default-test) # firefox ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running features.FirefoxTest
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.629 s <<< FAILURE! - in features.FirefoxTest
[ERROR] open_browser(features.FirefoxTest) Time elapsed: 0.58 s <<< ERROR!
java.lang.NullPointerException
at features.FirefoxTest.open_browser(FirefoxTest.java:31)
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR] FirefoxTest.open_browser:31 ยป NullPointer
[INFO]
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
[INFO]
[ERROR] There are test failures.
Please refer to C:\work\verso3\target\surefire-reports for the individual test results.
Please refer to dump files (if any exist) [date]-jvmRun[N].dump, [date].dumpstream and [date]-jvmRun[N].dumpstream.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) # firefox ---
[INFO] Building jar: C:\work\verso3\target\firefox-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- serenity-maven-plugin:1.4.0:aggregate (serenity-reports) # firefox ---
[INFO] current_project.base.dir: C:\work\verso3
[INFO] Generating test results for 0 tests
[INFO] 0 requirements loaded after 27 ms
[INFO] 0 related requirements found after 27 ms
[INFO] Generating test outcome reports: false
[INFO] Starting generating reports: 38 ms
[INFO] Configured report threads: 80
[INFO] Finished generating test results for 0 tests after 316 ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.337 s
[INFO] Finished at: 2017-06-08T13:20:18+03:00
[INFO] Final Memory: 17M/274M
[INFO] ------------------------------------------------------------------------
Process finished with exit code 0
So what's going on here? Why am I getting that null pointer exception? What am I doing wrong here?
The Firefox version I'm using is 53.0.3 (64-bit).
It is probably an incompatible version of Firefox or gecko. But why are you managing the WebDriver instance yourself?

Missing jacoco.exec file when using jacoco offline instrumentation with Powermock

Despite apparently this post showed a solution to using powermock and jacoco, I haven't been able to make it work in a pretty simple project (available on GitHub).
In my case, the test executes correctly but the jacoco.exec file is missing so jacoco doesn't check coverage.
Test class:
#RunWith(PowerMockRunner.class)
#PrepareOnlyThisForTest(Util.class)
#PowerMockIgnore("org.jacoco.agent.rt.*")
public class UtilTest {
#Test
public void testSay() throws Exception {
PowerMockito.mockStatic(Util.class);
Mockito.when(Util.say(Mockito.anyString())).thenReturn("hello:mandy");
Assert.assertEquals("hello:mandy", Util.say("sid"));
}
}
Util.java
public class Util {
private Util() {}
public static String say(String s) {
return "hello:"+s;
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.codependent.jacocopower</groupId>
<artifactId>jacoco-powermock</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>default-instrument</id>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>default-restore-instrumented-classes</id>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>CLASS</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<powermock.version>1.5.4</powermock.version>
<jacoco.version>0.7.4.201502262128</jacoco.version>
</properties>
</project>
Maven execution trace, complaining that no jacoco.exec file was found:
>> mvn clean verify
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building jacoco-powermock 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) # jacoco-powermock ---
[INFO] Deleting C:\SoftDesarrollo\6-Workspaces\libertyGecon\jacoco-powermock\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) # jacoco-powermock ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) # jacoco-powermock ---
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 1 source file to C:\SoftDesarrollo\6-Workspaces\libertyGecon\jacoco-powermock\target\classes
[INFO]
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:instrument (default-instrument) # jacoco-powermock ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) # jacoco-powermock ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) # jacoco-powermock ---
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[INFO] Compiling 1 source file to C:\SoftDesarrollo\6-Workspaces\libertyGecon\jacoco-powermock\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.18.1:test (default-test) # jacoco-powermock ---
[INFO] Surefire report directory: C:\SoftDesarrollo\6-Workspaces\libertyGecon\jacoco-powermock\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.codependent.jacoco.UtilTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.239 sec - in com.codependent.jacoco.UtilTest
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:restore-instrumented-classes (default-restore-instrumented-classes) # jacoco-powermock ---
[INFO]
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:report (default-report) # jacoco-powermock ---
[INFO] Skipping JaCoCo execution due to missing execution data file:C:\SoftDesarrollo\6-Workspaces\libertyGecon\jacoco-powermock\target\jacoco.exec
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) # jacoco-powermock ---
[INFO] Building jar: C:\SoftDesarrollo\6-Workspaces\libertyGecon\jacoco-powermock\target\jacoco-powermock-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- jacoco-maven-plugin:0.7.4.201502262128:check (default-check) # jacoco-powermock ---
[INFO] Skipping JaCoCo execution due to missing execution data file:C:\SoftDesarrollo\6-Workspaces\libertyGecon\jacoco-powermock\target\jacoco.exec
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.987s
[INFO] Finished at: Thu Jan 21 09:13:55 CET 2016
[INFO] Final Memory: 23M/331M
[INFO] ------------------------------------------------------------------------
UPDATE: (here on GitHub)
With the answer provided by Lencalot the jacoco.exec file is generated but the following scenario keeps saying that the ServiceImpl class coverage is 0%:
ServiceImpl
public class ServiceImpl implements Service{
public String operation() {
return Util.say("Hi!");
}
}
ServiceTest
#RunWith(PowerMockRunner.class)
#PrepareForTest({Util.class})
public class ServiceTest {
private Service service = new ServiceImpl();
#Test
public void testOperation() throws Exception {
PowerMockito.mockStatic(Util.class);
Mockito.when(Util.say(Mockito.anyString())).thenReturn("Bye!");
Assert.assertEquals("Bye!", service.operation());
}
}
Trace:
[WARNING] Rule violated for class com.codependent.jacoco.ServiceImpl: lines covered ratio is 0.00, but expected minimum is 0.50
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
<append>true</append>
</configuration>
<executions>
<execution>
<id>default-instrument</id>
<goals>
<goal>instrument</goal>
</goals>
<configuration>
<includes>
<include>**/*test*</include>
</includes>
</configuration>
</execution>
<execution>
<id>default-restore-instrumented-classes</id>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
<configuration>
<includes>
<include>**/*test*</include>
</includes>
</configuration>
</execution>
<execution>
<id>Prepare-Jacoco</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<excludes>
<exclude>**/*test*</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
you can remove Check for now, we can try to get it working with out that first.
Update your Jacoco dependency to look like this
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
Make you maven surefire plugin look like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${argLine}</argLine>
</configuration>
</plugin>
in your properties section Add this as, and change your jacoco Version:
<jacoco.version>0.7.5.201505241946</jacoco.version>
<jacoco.outputDir>${project.basedir}/target/jacoco.exec</jacoco.outputDir>
#codependent Heres an example of why you want to mock.
Lets assume your Util.class has a lot more code, a lot of instantiations and maybe it even touches some server side stuff, hell maybe even its a UI. You don't want to instantiate User.class just to test a single method in some other class called UtilUser.class
protected class UtilUser {
protected UtilUser() {}
public Boolean checkSay(String s) {
String expectedString = "hello:" + s;
String actualString = Util.say(s);
if (expectedString.equals(actualString){
return true;
} else {
return false;
}
}
}
To unit test UtilUser, you want to hit all branches. So in your test you would mock the Util.class, and in one unit test force it to return the correct string, and in another test have it return an incorrect string. You don't care about testing User.class, you know it will behave accordingly or you will have another test to take care of that. For unit testing UtilUser, you can expect Util to either return a correct string or an incorrect string, and you want to test both possibilities.
Theres a time and a place for mocks and they are a great tool to know, but DO NOT think they should be used often. Please refer to the following article, it will give you good insight into when you should use mocks: When To Mock

Resources