I am using Jacoco plugin to calculate the code coverage for spring boot application. The Jacoco configuration from the build.gradle looks like this:
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination file("${buildDir}/jacocoHtml")
}
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it,
exclude: ['**/models/**',
'**/config/**',
'**/constants/**',
'**/Application.class'])
})
}
}
and
jacocoTestCoverageVerification {
violationRules {
rule {
element = 'PACKAGE'
excludes = ['some packages']
limit {
counter = 'BRANCH'
minimum = 0.7
}
}
}
}
When I run the coverage from the IntelliJ then it shows the correct result but when I run it with gradlew clean buils, it fails with coverage 0.0.
I have written an example class and here are the jacoco report snapshots-
report:
class:
And the test I wrote for the SomeClass is
public class SomeClassTest {
private SomeClass someClass;
#Before
public void setUp() throws Exception {
someClass = new SomeClass(12, 23);
}
#Test
public void shouldSumTwoValues() {
assertThat(someClass.sum()).isEqualTo(35);
}
}
Can someone please help me with this?
Given src/main/java/SomeClass.java
class SomeClass {
private Integer value1;
private Integer value2;
SomeClass(Integer value1, Integer value2) {
this.value1 = value1;
this.value2 = value2;
}
Integer sum() {
return value1 + value2;
}
}
src/test/java/SomeClassTest.java
import org.junit.*;
import static org.junit.Assert.*;
public class SomeClassTest {
private SomeClass someClass;
#Before
public void setUp() throws Exception {
someClass = new SomeClass(12, 23);
}
#Test
public void shouldSumTwoValues() {
assertEquals(35, (int) someClass.sum());
}
}
and build.gradle
apply plugin: "java"
apply plugin: "jacoco"
dependencies {
testCompile "junit:junit:4.12"
}
repositories {
mavenCentral()
}
execution of gradle test jacocoTestReport produces following report in build/reports/jacoco/test/html/index.html
Addition to build.gradle of
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination file("${buildDir}/jacocoHtml")
}
afterEvaluate {
classDirectories = files(classDirectories.files.collect {
fileTree(dir: it,
exclude: ['**/models/**',
'**/config/**',
'**/constants/**',
'**/Application.class'])
})
}
}
jacocoTestCoverageVerification {
violationRules {
rule {
element = 'PACKAGE'
excludes = ['some packages']
limit {
counter = 'BRANCH'
minimum = 0.7
}
}
}
}
doesn't change result/report, except of change of directory with report on build/jacocoHtml.
In my case I discovered that it is due to the fact that I set minimum = 1. When I change it to 0.9 all of the sudden it works
Related
Having an activity which has some functions need to be coverage tested.
class HandlerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle ) {
System.out.println("enter HandlerActivity.onCreate()")
doSomething(intent)
}
}
//////////////
#RunWith(RobolectricTestRunner::class)
class HandlerActivityTest {
#Test
fun test_activity() {
val conextSpy = spyk(ApplicationProvider.getApplicationContext())
var testEx: Throwable? = null
try {
val intent = Intent(this, HandlerActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
conextSpy.startActivity(intent)
Shadows.shadowOf(Looper.getMainLooper()).idle()
} catch (ex: Throwable) {
testEx = ex
}
junit.framework.Assert.assertNull(testEx)
io.mockk.verify { contextSpy.startActivity(any()) }
}
The test passed, but the HandlerActivity.onCreate() is not called.
How to unit test a onCreate() of an activity?
I have custom action filter and i want to write unit test for that in dotnet core weabpi.
please help.
public class ApplicationIdValidationAttribute: IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
var param = context.ActionArguments["Id"];
var modelState = context.ModelState;
if (param!=null && string.IsNullOrEmpty(param.ToString()))
{
modelState.AddModelError("id", "Application id is required");
context.Result = new BadRequestObjectResult(new ModelStateRequestValidationAdaptor(modelState));
return;
}
if (!Guid.TryParse(param?.ToString(), out Guid applicationGuid))
{
modelState.AddModelError("id", "Application id is not a valid Guid");
context.Result = new BadRequestObjectResult(new ModelStateRequestValidationAdaptor(modelState));
return;
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
I need to disable execution of one unit test on local environment. We run unit tests in local with local-test profile
-Dspring.profiles.active=local-test
I need to execute my test at all profiles except local-test How can I achieve this?
Here is my test, if I put value = "!local-test" it does not work
#IfProfileValue(name = "spring.profiles.active", value = "local-test")
#RunWith(SpringRunner.class)
public class EnvironmentTests {
#Test
public void TestNightTimeFormatCorrect() {
throw new RuntimeException("test exception");
}
}
I found a solution, hope it will be useful for somebody.
In this case TestNightTimeFormatCorrect will be executed every time when there is no local-test profile. It will be alse executed when no profile is set.
#RunWith(SpringJUnit4ClassRunner.class)
#ProfileValueSourceConfiguration(EnvironmentTests.ProfileProfileValueSource.class)
#IfProfileValue(name = "local-test", value = "false")
public class EnvironmentTests {
#Test
public void TestNightTimeFormatCorrect() {
throw new RuntimeException("test exception");
}
public static class ProfileProfileValueSource implements ProfileValueSource
{
#Override
public String get(String string)
{
final String systemProfiles = System.getProperty("spring.profiles.active", System.getProperty("SPRING_PROFILES_ACTIVE", ""));
final String[] profiles = systemProfiles.split(",");
return Arrays.asList(profiles).contains(string) ? "true" : "false";
}
}
}
I did search a lot and this is the closest answer that I got but does not solve my problem. TestNG retrying failed tests doesn't output the correct test results
But I need the above problem to extend from TestNG onto Maven. Please help.
My Project stack: TestNG, Maven surefire plugin, Maven. I am running the tests from command line - "mvn clean compile test". I am using a retryanalyzer to re-run the failed tests, that are passing the second time. I have been able to use a CustomListener to update the results stored in the TestNG's testcontext (based on solutions in stackoverflow). This was confirmed when I ran the tests as TestNG suite.
But when I run "mvn clean compile test", all the retries are counted as separate tests and build always fails. How do I make TestNG send only the final Suite results to Maven Surefire plugin ?
TESTNG EXECUTION:
============================================
DefaultTest
Total tests run: 4, Failures: 2, Skips: 0
============================================
============================================
DefaultSuite
Total tests run: 2, Failures: 0, Skips: 0
============================================
MAVEN EXECUTION:
Tests run: 4, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.292 sec <<< FAILURE!
Results :
Failed tests:
test1(foo.TestClass1)
test1(foo.TestClass1)
Tests run: 4, Failures: 2, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
The build passed because of the retry. How do I reflect the TestNG retry Suite results onto Maven ?
Finally got it. I use this code:
ListenerApadter:
public class MyTestListenerAdapter extends TestListenerAdapter {
#Override
public void onTestFailure(ITestResult result) {
if (result.getMethod().getRetryAnalyzer() != null) {
MyRetryAnalyzer retryAnalyzer = (MyRetryAnalyzer)result.getMethod().getRetryAnalyzer();
if(retryAnalyzer.isRetryAvailable()) {
result.setStatus(ITestResult.SKIP);
} else {
result.setStatus(ITestResult.FAILURE);
}
Reporter.setCurrentTestResult(result);
}
}
#Overrride
public void onFinish(ITestContext context) {
Iterator<ITestResult> failedTestCases =context.getFailedTests().getAllResults().iterator();
while (failedTestCases.hasNext()) {
System.out.println("failedTestCases");
ITestResult failedTestCase = failedTestCases.next();
ITestNGMethod method = failedTestCase.getMethod();
if (context.getFailedTests().getResults(method).size() > 1) {
System.out.println("failed test case remove as dup:" + failedTestCase.getTestClass().toString());
failedTestCases.remove();
} else {
if (context.getPassedTests().getResults(method).size() > 0) {
System.out.println("failed test case remove as pass retry:" + failedTestCase.getTestClass().toString());
failedTestCases.remove();
}
}
}
}
}
RetryAnalizer:
public class MyRetryAnalyzer implements IRetryAnalyzer {
private static int MAX_RETRY_COUNT = 3;
AtomicInteger count = new AtomicInteger(MAX_RETRY_COUNT);
public boolean isRetryAvailable() {
return (count.intValue() > 0);
}
#Override
public boolean retry(ITestResult result) {
boolean retry = false;
if (isRetryAvailable()) {
System.out.println("Going to retry test case: " + result.getMethod() + ", " + (MAX_RETRY_COUNT - count.intValue() + 1) + " out of " + MAX_RETRY_COUNT);
retry = true;
count.decrementAndGet();
}
return retry;
}
}
POM.xml -> Surefire Configuration:
This is where you should configure "overwrite" surefire listener wich has their own counters.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<suiteXmlFiles><suiteXmlFile>${basedir}/testng.xml</suiteXmlFile></suiteXmlFiles>
<properties>
<property>
<name>listener</name>
<value>Utils.MyTestListenerAdapter,Utils.MyRetryAnalizer</value>
</property>
</properties>
Some suit info is incorrect, but maven surefire works properly
maven-surefire-plugin 2.16
testng 6.8.8
// ===== InvokedMethodListener =====
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
public class InvokedMethodListener implements IInvokedMethodListener {
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
RetryAnalyzer retryAnalyzer = (RetryAnalyzer)testResult.getMethod().getRetryAnalyzer();
if (retryAnalyzer == null || retryAnalyzer.isFailed()) {
return;
}
if (testResult.getStatus() == ITestResult.FAILURE) {
testResult.setStatus(ITestResult.SUCCESS);
}
}
}
// ===== RetryAnalyzer =====
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import org.testng.Reporter;
public class RetryAnalyzer implements IRetryAnalyzer {
private int count = 0;
private int maxCount = 2;
#Override
public boolean retry(ITestResult result) {
if (!result.isSuccess()) {
if (count < maxCount) {
count++;
return true;
}
}
return false;
}
public boolean isFailed() {
return count >= maxCount;
}
}
// ===== BaseTest =====
#Listeners({ ..InvokedMethodListener.class })
public abstract class BaseTest {
...
#BeforeSuite(alwaysRun = true)
public void beforeSuite(ITestContext context) {
for (ITestNGMethod method : context.getAllTestMethods()) {
method.setRetryAnalyzer(new RetryAnalyzer());
}
}
}
I am updating unit tests in a Grails project. We were originally using version 1.3.9 and now we are updating to version 2.3.9. I am using Spock.
I keep getting this error:
results:
junit.framework.AssertionFailedError: Condition not satisfied:
controller.edit() == [filterCategoryInstance: filterCategoryInstance]
| | | |
| null false John
com.xxxxxx.xxxxx.FilterCategoryController#20574000
Here is the controller code:
#Secured(["hasAnyRole('CM_ADMIN')"])
def edit() {
def filterCategoryInstance = FilterCategory.get(params.id)
if (!filterCategoryInstance) {
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'dpFilterCategory.label', default: 'FilterCategory'), params.id])}"
redirect(action: "list")
}
else {
return [filterCategoryInstance: filterCategoryInstance]
}
}
and here is the test code:
#Mock([FilterCategory, FilterCategoryTag])
#TestFor(FilterCategoryController)
#TestMixin(DomainClassUnitTestMixin)
class FilterCategoryControllerSpec extends ExtendedControllerSpec {
def 'edit action: existing FilterCategory'() {
setup:
mockI18N(FilterCategoryController)
params.id = filterCategoryInstance.id
expect:
controller.edit() == [filterCategoryInstance: filterCategoryInstance]
where:
tag = new FilterCategoryTag(name: 'tag1')
filterCategoryInstance = new FilterCategory(name: "John",
submissionText:"John", sortOrder:0, 'filterCategoryTags': [tag])
}
And here is the ExtendedControllerSpec code. I hope I have included enough code:
I have looked at the following web pages for guidance:
#Mixin(MetaClassMixin)
class ExtendedControllerSpec extends Specification {
def props
protected void setup() {
//super.setup()
props = new Properties()
File file = new File("grails-app/i18n/messages.properties")
if (file.exists()) {
def stream = new FileInputStream(file)
props.load stream
stream.close()
}
mockI18N(controller)
}
def mockI18N = { controller ->
controller.metaClass.message = { Map map ->
if (!map.code)
return ""
if (map.args) {
def formatter = new MessageFormat("")
if (props.getProperty(map.code)) {
formatter.applyPattern props.getProperty(map.code)
}
return formatter.format(map.args.toArray())
} else {
if (props && props.hasProperty(map.code)) {
return props.getProperty(map.code)
} else {
return map.code
}
}
}
}
/**
* add dynamic methods in test setup.
*/
protected void addDynamicMethods() {
registerMetaClass(String)
String.metaClass.mixin StringUtils
}
protected GrailsUser mockGrailsUser() {
return Mock(GrailsUser)
}
...
/**
* must call AFTER mockDpSercurityService
*/
protected void setHasRoleTrue() {
if (controller?.dpSecurityService?.metaClass) {
controller.dpSecurityService.metaClass.hasRole = {return true}
}
}
protected void setHasRoleFalse() {
if (controller?.dpSecurityService?.metaClass) {
controller.dpSecurityService.metaClass.hasRole = {return false}
}
}
protected void mockUserService() {
controller.dpUserService = new MockFor(UserService)
}
}
http://sanjaykanwar.blogspot.com/2012/07/grails-controller-test-with-spock.html
http://naleid.com/blog/2012/05/01/upgrading-to-grails-2-unit-testing
Looks like the if branch gets executed in edit() instead of the else branch because FilterCategory does not get saved and therfore does not get a proper id.