Use Case: Writing tests for AEM application.
Current Issue: As your project and code base grows, it is really important to make sure that test coverage for code is there to maintain consistency and sanity of your code. Writing test cases for AEM is little bit different than writing conventional Java test cases, This makes it difficult for beginner to write test cases for AEM application.
Idea of this post to give different options available for writing unit test for AEM services.
Prerequisite:
Dependencies: It is recommended to have following dependencies in to your pom before start writing for tests for your application
Case 1: Writing test cases for Generic Helper class.
This is simplest use case where your generic helper class (For example StringUtils, DateUtils) is not using any AEM libraries. For this you can simply use Junit to write your unit test. https://www.tutorialspoint.com/junit
Here is very simple example:
Case 2: Writing test cases for AEM Helper class
This is second use case where you want to test AEM helper methods. For this you can use combination of Junit and Mockito. Use Mockito to Mock AEM services and methods and Junit for assertion.
Here is simple example
Case 3: Writing test cases for AEM services
Now it gets little bit tricky where you need to mock certain behavior of bundle and implicit object. That's why Sling has created Mock version of sling objects and wcm.io has created mock version of AEM objects. You can just use aem mock http://wcm.io/testing/aem-mock/ to achieve most of your use cases. (AEM mock extend Sling mock).
here are some of the common use cases you will come across while testing your service.
1) How can I mock content my service is running against ?
For this it is recommended to use contentLoader API http://wcm.io/testing/aem-mock/usage.html to either load existing json based resource (You can simply get it by creating resource in CRXDE and then using something like RESOURCEPATH.infinity.json to get json for that resource) or just create mock resource using ContentBuilder context.create().resource() or ResourceBuilder context.build().resource() http://wcm.io/testing/aem-mock/apidocs/
Note that if you are mocking Page object then you have to use aem mock using aemcontext.pageManager().create()
2) How Can I initialize properties in the bundle ?
You can use register and activate OSGI service with properties http://wcm.io/testing/aem-mock/usage.html#Registering_OSGi_service for that. Here is some example
3) How Can I inject other service for my service ?
You can either Mock service or use register service API for that http://wcm.io/testing/aem-mock/usage.html#Registering_OSGi_service
Note that when you inject a service to your service using Reference then you have to register this your injected service, otherwise your test will fail.
4) How Can I test sling model ?
You can use aemContext for that. http://wcm.io/testing/aem-mock/usage.html#Sling_Models
Case 4: Writing test cases for AEM servlets and filters
This is very similar to how you would do test cases for Service. For request and response you either have to mock request / response object using Mockito or Use Spy or use sling request and response mock. Since a lot of methods in filter and servlet do not return any result, Make Mockito verify your friend. Here is one example using simple mockito to test servlet
How can I measure my test coverage ?
You can use jococo test coverage plugin along with your build system to measure this coverage. You can have following plugin in to your parent pom
How Can I write Integration test in AEM ?
Very good example here https://github.com/sneakybeaky/AEM-Integration-Test-Example
It is based of sling test base https://sling.apache.org/documentation/development/sling-testing-tools.html
I know this information is not enough to have you set up for writing tests in AEM. Feel free to let me know if you have more question and I will add more stuff here.
Current Issue: As your project and code base grows, it is really important to make sure that test coverage for code is there to maintain consistency and sanity of your code. Writing test cases for AEM is little bit different than writing conventional Java test cases, This makes it difficult for beginner to write test cases for AEM application.
Idea of this post to give different options available for writing unit test for AEM services.
Prerequisite:
- Familiar with Java Junit test framework http://junit.org
- Familiar with Java Mockito test framework http://site.mockito.org/
- Optional: PowerMockito test framework http://powermock.github.io/
- Sling test framework (Mock and IT) https://sling.apache.org/documentation/development.html
- AEM Mock http://wcm.io/testing/aem-mock/ and http://wcm.io/testing/aem-mock/apidocs/
- WCMUse classes Mocking http://aempodcast.com/2015/testing/unit-testing-wcmuse-classes-using-mockito/#.WEmiUMMrJKc
Dependencies: It is recommended to have following dependencies in to your pom before start writing for tests for your application
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.8.2</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.slf4j</groupId> | |
<artifactId>slf4j-simple</artifactId> | |
<version>1.5.11</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>junit-addons</groupId> | |
<artifactId>junit-addons</artifactId> | |
<version>1.4</version> | |
<scope>test</scope> | |
</dependency> | |
<!-- Custom WCM Mock for AEM6 --> | |
<dependency> | |
<groupId>io.wcm</groupId> | |
<artifactId>io.wcm.testing.aem-mock</artifactId> | |
<version>1.3.0</version> | |
</dependency> | |
<!-- Sling Mocks --> | |
<dependency> | |
<groupId>org.apache.sling</groupId> | |
<artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId> | |
<version>1.1.4</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.sling</groupId> | |
<artifactId>org.apache.sling.testing.osgi-mock</artifactId> | |
<version>1.2.0</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.sling</groupId> | |
<artifactId>org.apache.sling.testing.sling-mock</artifactId> | |
<version>1.2.0</version> | |
</dependency> | |
<dependency> | |
<groupId>org.apache.sling</groupId> | |
<artifactId>org.apache.sling.testing.jcr-mock</artifactId> | |
<version>1.1.4</version> | |
</dependency> | |
<dependency> | |
<groupId>org.mockito</groupId> | |
<artifactId>mockito-core</artifactId> | |
<version>1.10.19</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.mockito</groupId> | |
<artifactId>mockito-all</artifactId> | |
<version>1.10.19</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.powermock</groupId> | |
<artifactId>powermock-module-junit4</artifactId> | |
<version>1.6.2</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.powermock</groupId> | |
<artifactId>powermock-api-mockito</artifactId> | |
<version>1.6.2</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>com.adobe.aem</groupId> | |
<artifactId>uber-jar</artifactId> | |
<version>6.1.2</version> | |
<classifier>apis</classifier> | |
<scope>provided</scope> | |
</dependency> |
This is simplest use case where your generic helper class (For example StringUtils, DateUtils) is not using any AEM libraries. For this you can simply use Junit to write your unit test. https://www.tutorialspoint.com/junit
Here is very simple example:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.wemblog.foundation.utility; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertFalse; | |
import static org.junit.Assert.assertTrue; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.junit.Test; | |
public class CommonStringUtilTest { | |
@Test | |
public void testIsEmpty() { | |
assertTrue(CommonStringUtil.isEmpty("")); | |
assertFalse(CommonStringUtil.isEmpty(" ")); | |
assertFalse(CommonStringUtil.isEmpty("test")); | |
assertFalse(CommonStringUtil.isEmpty(" test ")); | |
assertTrue(CommonStringUtil.isEmpty(null)); | |
} | |
@Test | |
public void testIsEmptyWithTrim() { | |
assertTrue(CommonStringUtil.isEmpty("", false)); | |
assertTrue(CommonStringUtil.isEmpty(" ", true)); | |
assertFalse(CommonStringUtil.isEmpty(" ", false)); | |
assertFalse(CommonStringUtil.isEmpty("test", true)); | |
assertFalse(CommonStringUtil.isEmpty(" test ", true)); | |
assertTrue(CommonStringUtil.isEmpty(null, true)); | |
assertTrue(CommonStringUtil.isEmpty(null, false)); | |
} | |
@Test | |
public void testConvertArrayToString() { | |
String[] test = { "test1", "test2" }; | |
assertEquals(CommonStringUtil.convertArrayToString(new String[1]), ""); | |
assertEquals(CommonStringUtil.convertArrayToString(null), ""); | |
assertEquals(CommonStringUtil.convertArrayToString(test), "test1,test2"); | |
test[1] = "test3 test4"; | |
assertEquals(CommonStringUtil.convertArrayToString(test), "test1,test3 test4"); | |
ArrayList<String> test1 = new ArrayList<String>(); | |
test1.add("test1 test2"); | |
test1.add("test3"); | |
assertEquals(CommonStringUtil.convertArrayToString(test1.toArray(new String[test1.size()])), | |
"test1 test2,test3"); | |
} | |
@Test | |
public void testConvertArrayListToString() { | |
List<String> test = new ArrayList<String>(); | |
assertEquals(CommonStringUtil.convertArrayListToString(null), ""); | |
assertEquals(CommonStringUtil.convertArrayListToString(test), ""); | |
test.add("test1"); | |
test.add("test2"); | |
assertEquals(CommonStringUtil.convertArrayListToString(test), "test1,test2"); | |
test.add("test3 test4"); | |
assertEquals(CommonStringUtil.convertArrayListToString(test), "test1,test2,test3 test4"); | |
} | |
} |
Case 2: Writing test cases for AEM Helper class
This is second use case where you want to test AEM helper methods. For this you can use combination of Junit and Mockito. Use Mockito to Mock AEM services and methods and Junit for assertion.
Here is simple example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.wemblog.util; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertFalse; | |
import static org.junit.Assert.assertNotNull; | |
import static org.junit.Assert.assertNull; | |
import static org.junit.Assert.assertTrue; | |
import static org.mockito.Mockito.mock; | |
import static org.mockito.Mockito.when; | |
import javax.servlet.http.Cookie; | |
import javax.servlet.jsp.PageContext; | |
import org.apache.sling.api.SlingHttpServletRequest; | |
import org.apache.sling.api.resource.NonExistingResource; | |
import org.apache.sling.api.resource.Resource; | |
import org.apache.sling.api.resource.ResourceResolver; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import org.mockito.Mock; | |
import org.mockito.runners.MockitoJUnitRunner; | |
import com.day.cq.commons.Externalizer; | |
@RunWith(MockitoJUnitRunner.class) | |
public class LiCommonRequestUtilsTest { | |
@Mock | |
SlingHttpServletRequest _httpServletRequest; | |
@Mock | |
ResourceResolver _resourceResolver; | |
@Mock | |
Resource _resource; | |
@Mock | |
Cookie _bCookie; | |
@Mock | |
Externalizer _externalizer; | |
@Before | |
public void setUp() { | |
when(_httpServletRequest.getServerName()).thenReturn("www.test.com"); | |
when(_httpServletRequest.getRequestURI()).thenReturn("/something/andsomething"); | |
} | |
/** | |
* 1. When there is Host header 2. No Host Header 3. Host Header Null 4. Host Header Empty | |
* | |
*/ | |
@Test | |
public void getServerNameTest() { | |
assertNull(LiCommonRequestUtils.getServerName(null)); | |
assertEquals(LiCommonRequestUtils.getServerName(_httpServletRequest), "www.test.com"); | |
when(_httpServletRequest.getHeader("Host")).thenReturn("www.test2.com"); | |
assertEquals(LiCommonRequestUtils.getServerName(_httpServletRequest), "www.test2.com"); | |
when(_httpServletRequest.getHeader("Host")).thenReturn(""); | |
assertEquals(LiCommonRequestUtils.getServerName(_httpServletRequest), "www.test.com"); | |
when(_httpServletRequest.getHeader("Host")).thenReturn(null); | |
assertEquals(LiCommonRequestUtils.getServerName(_httpServletRequest), "www.test.com"); | |
} | |
/** | |
* 1. Null test 2. With http header only 3. With http header and netscalar header 4. With https header 5. With https | |
* and null netscalar header | |
*/ | |
@Test | |
public void isHttpOrHttpsRequestTest() { | |
// For null input | |
assertFalse(LiCommonRequestUtils.isHTTPRequest(null)); | |
assertFalse(LiCommonRequestUtils.isHTTPSRequest(null)); | |
.thenReturn(LiCommonRequestUtils.HTTPS_PROTOCOL); | |
assertFalse(LiCommonRequestUtils.isHTTPRequest(_httpServletRequest)); | |
assertTrue(LiCommonRequestUtils.isHTTPSRequest(_httpServletRequest)); | |
when(_httpServletRequest.getProtocol()).thenReturn("HTTP/1.1"); | |
assertTrue(LiCommonRequestUtils.isHTTPRequest(_httpServletRequest)); | |
assertFalse(LiCommonRequestUtils.isHTTPSRequest(_httpServletRequest)); | |
// If it is https request | |
when(_httpServletRequest.getProtocol()).thenReturn("HTTPS/1.1"); | |
assertFalse(LiCommonRequestUtils.isHTTPRequest(_httpServletRequest)); | |
assertTrue(LiCommonRequestUtils.isHTTPSRequest(_httpServletRequest)); | |
} | |
@Test | |
public void getCompleteResourcePathTest() { | |
// Null check | |
assertNull(LiCommonRequestUtils.getCompleteResourcePath(null)); | |
// Exact Path check | |
when(_httpServletRequest.getRequestURI()).thenReturn("/content/test/test"); | |
when(_resource.getPath()).thenReturn("/content/test/test"); | |
when(_resourceResolver.resolve("/content/test/test")).thenReturn(_resource); | |
when(_httpServletRequest.getResourceResolver()).thenReturn(_resourceResolver); | |
assertEquals(LiCommonRequestUtils.getCompleteResourcePath(_httpServletRequest), "/content/test/test"); | |
// Vanity Path check | |
when(_httpServletRequest.getRequestURI()).thenReturn("/vanity/test/test"); | |
when(_resourceResolver.resolve("/vanity/test/test")).thenReturn(_resource); | |
assertEquals(LiCommonRequestUtils.getCompleteResourcePath(_httpServletRequest), "/content/test/test"); | |
// Non existance Resource check | |
when(_resourceResolver.resolve("/vanity/test/test")).thenReturn(new NonExistingResource(_resourceResolver, null)); | |
assertNull(LiCommonRequestUtils.getCompleteResourcePath(_httpServletRequest)); | |
} | |
/** | |
* 1. True 2. True 3. False 4. False 5. False 6. False 7. False | |
*/ | |
@Test | |
public void isValidIPAddressTest() { | |
// true for valid IPV4 | |
assertTrue(LiCommonRequestUtils.isValidIPAddress("199.101.162.221")); | |
// true for valid IPV6 | |
assertTrue(LiCommonRequestUtils.isValidIPAddress("2620:109:c00d:100::c765:a381")); | |
// false if IP is null | |
assertFalse(LiCommonRequestUtils.isValidIPAddress(null)); | |
// false if ip is blank | |
assertFalse(LiCommonRequestUtils.isValidIPAddress("")); | |
// false if its a random string | |
assertFalse(LiCommonRequestUtils.isValidIPAddress("1.3.1.1.1.1.1.1.1")); | |
// false if its a random string | |
assertFalse(LiCommonRequestUtils.isValidIPAddress("abc.f.ve.c")); | |
// false if its a random string | |
assertFalse(LiCommonRequestUtils.isValidIPAddress("test")); | |
} | |
/** | |
* 1. True 2. True 3. False 4. False 5. False 6. False 7. False 8. False | |
*/ | |
@Test | |
public void isIPV6AddressTest() { | |
// true for valid compressed IPV6 | |
assertTrue(LiCommonRequestUtils.isIPV6Address("2620:109:c00d:100::c765:a381")); | |
// true for valid standard IPV6 | |
assertTrue(LiCommonRequestUtils.isIPV6Address("3ffe:1900:4545:3:200:f8ff:fe21:67cf")); | |
// false if IP is null | |
assertFalse(LiCommonRequestUtils.isIPV6Address(null)); | |
// false if ip is blank | |
assertFalse(LiCommonRequestUtils.isIPV6Address("")); | |
// false if its a random string | |
assertFalse(LiCommonRequestUtils.isIPV6Address("1.3.1.1.1.1.1.1.1")); | |
// false if its a random string | |
assertFalse(LiCommonRequestUtils.isIPV6Address("abc.f.ve.c")); | |
// false if its a random string | |
assertFalse(LiCommonRequestUtils.isIPV6Address("test")); | |
// true for valid IPV4 | |
assertFalse(LiCommonRequestUtils.isIPV6Address("199.101.162.221")); | |
} | |
} |
Now it gets little bit tricky where you need to mock certain behavior of bundle and implicit object. That's why Sling has created Mock version of sling objects and wcm.io has created mock version of AEM objects. You can just use aem mock http://wcm.io/testing/aem-mock/ to achieve most of your use cases. (AEM mock extend Sling mock).
here are some of the common use cases you will come across while testing your service.
1) How can I mock content my service is running against ?
For this it is recommended to use contentLoader API http://wcm.io/testing/aem-mock/usage.html to either load existing json based resource (You can simply get it by creating resource in CRXDE and then using something like RESOURCEPATH.infinity.json to get json for that resource) or just create mock resource using ContentBuilder context.create().resource() or ResourceBuilder context.build().resource() http://wcm.io/testing/aem-mock/apidocs/
Note that if you are mocking Page object then you have to use aem mock using aemcontext.pageManager().create()
2) How Can I initialize properties in the bundle ?
You can use register and activate OSGI service with properties http://wcm.io/testing/aem-mock/usage.html#Registering_OSGi_service for that. Here is some example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Method 1, By using Inject Mock | |
@RunWith(PowerMockRunner.class) | |
@PrepareForTest(MyServiceImpl.class) | |
public class MyServiceImplTest { | |
@InjectMocks | |
MyServiceImpl _myService; | |
@Before | |
public void setUp() throws Exception { | |
_config = new HashMap<Object, Object>(); | |
_config.put("test1", "test1"); | |
_config.put("test2", "test3"); | |
} | |
@Test | |
public void someTest() { | |
myService.activate(_config); | |
assertEquals("test", something.yourMethod()); | |
} | |
} | |
//Method 2 using AEM context | |
public class MyServiceImplTest { | |
MyServiceImpl _myService; | |
@Rule | |
public final AemContext aemContext = new AemContext(); | |
@Before | |
public void setUp() throws Exception { | |
_config = new HashMap<Object, Object>(); | |
_config.put("test1", "test1"); | |
_config.put("test2", "test3"); | |
_myService = aemContext.registerInjectActivateService(new MyServiceImpl(), _config); | |
} | |
@Test | |
public void someTest() { | |
assertEquals("test", _myService.yourMethod()); | |
} | |
} |
3) How Can I inject other service for my service ?
You can either Mock service or use register service API for that http://wcm.io/testing/aem-mock/usage.html#Registering_OSGi_service
Note that when you inject a service to your service using Reference then you have to register this your injected service, otherwise your test will fail.
4) How Can I test sling model ?
You can use aemContext for that. http://wcm.io/testing/aem-mock/usage.html#Sling_Models
Case 4: Writing test cases for AEM servlets and filters
This is very similar to how you would do test cases for Service. For request and response you either have to mock request / response object using Mockito or Use Spy or use sling request and response mock. Since a lot of methods in filter and servlet do not return any result, Make Mockito verify your friend. Here is one example using simple mockito to test servlet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.wemblog.test; | |
import com.adobe.granite.xss.XSSAPI; | |
import com.google.gson.JsonArray; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.PrintWriter; | |
import static org.junit.Assert.*; | |
import static org.mockito.Mockito.any; | |
import static org.mockito.Mockito.mock; | |
import static org.mockito.Mockito.when; | |
import static org.mockito.Mockito.doThrow; | |
import static org.mockito.Mockito.doAnswer; | |
import io.wcm.testing.mock.aem.junit.AemContext; | |
import org.apache.sling.testing.mock.sling.ResourceResolverType; | |
import com.google.gson.JsonObject; | |
import com.google.gson.JsonParser; | |
import org.apache.sling.api.SlingHttpServletRequest; | |
import org.apache.sling.api.SlingHttpServletResponse; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.junit.Rule; | |
import org.junit.runner.RunWith; | |
import org.mockito.InjectMocks; | |
import org.mockito.Mock; | |
import org.mockito.invocation.InvocationOnMock; | |
import org.mockito.stubbing.Answer; | |
import org.mockito.runners.MockitoJUnitRunner; | |
@RunWith(MockitoJUnitRunner.class) | |
public class AEMServletTest { | |
private String answerFromDoGet = ""; | |
private int statusForDoGet = 0; | |
private JsonParser parser = new JsonParser(); | |
@Rule | |
public final AemContext _context = new AemContext(ResourceResolverType.RESOURCERESOLVER_MOCK); | |
@Mock | |
private AEMTreatmentService _aemTreatServe = mock(AEMTreatmentService.class); | |
SlingHttpServletRequest _httpServletRequest = mock(SlingHttpServletRequest.class); | |
SlingHttpServletResponse _httpServletResponse = mock(SlingHttpServletResponse.class); | |
XSSAPI _xssapi = mock(XSSAPI.class); | |
PrintWriter _respOut = mock(PrintWriter.class); | |
@InjectMocks | |
AEMTreatmentServlet _aemServlet; | |
@Before | |
public void setUp() { | |
_context.registerService(AEMTreatmentService.class, _aemTreatServe); | |
try { | |
when(_httpServletResponse.getWriter()).thenReturn(_respOut); | |
doAnswer(new Answer<Object>() { | |
public Object answer(InvocationOnMock invocation) throws IOException { | |
Object[] args = invocation.getArguments(); | |
answerFromDoGet = (String) args[0]; | |
return null; | |
} | |
}).when(_respOut).write(any(String.class)); | |
} catch (Exception e) { | |
} | |
} | |
@Test | |
public void testDoGet() { | |
try { | |
when(_httpServletRequest.getParameter(AEMTreatmentService.TREATMENT_PARAM)).thenReturn("foo"); | |
_aemServlet.doGet(_httpServletRequest, _httpServletResponse); | |
JsonObject result = parser.parse(answerFromDoGet).getAsJsonObject(); | |
assertEquals("correctly set status", SlingHttpServletResponse.SC_OK, | |
result.get(AEMTreatmentService.STATUS_KEY).getAsInt()); | |
} catch (Exception e) { | |
assertTrue("error running testDoGet: " + e.getMessage(), false); | |
} | |
} | |
/** | |
* Test that the servlet returns the correct error state when the user fails | |
* to provide a testKey parameter. | |
*/ | |
@Test | |
public void testDoGetNoTestKey() { | |
try { | |
when(_httpServletRequest.getParameter(AEMTreatmentService.TEST_PARAM)).thenReturn(""); | |
_aemServlet.doGet(_httpServletRequest, _httpServletResponse); | |
JsonObject result = parser.parse(answerFromDoGet).getAsJsonObject(); | |
assertEquals("correctly set status", SlingHttpServletResponse.SC_BAD_REQUEST, | |
result.get(AEMTreatmentService.STATUS_KEY).getAsInt()); | |
} catch (Exception e) { | |
assertTrue("error running testDoGet: " + e.getMessage(), false); | |
} | |
} | |
@Test | |
public void testDoGetQAMode() { | |
try { | |
when(_httpServletRequest.getParameter(AEMTreatmentService.QA_MODE_PARAM)).thenReturn("true"); | |
_aemServlet.doGet(_httpServletRequest, _httpServletResponse); | |
JsonObject result = parser.parse(answerFromDoGet).getAsJsonObject(); | |
assertEquals("correctly set QA override", true, result.get(AEMTreatmentService.QA_MODE_KEY).getAsBoolean()); | |
} catch (Exception e) { | |
assertTrue("error running testDoGet: " + e.getMessage(), false); | |
} | |
} | |
} |
How can I measure my test coverage ?
You can use jococo test coverage plugin along with your build system to measure this coverage. You can have following plugin in to your parent pom
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<plugin> | |
<groupId>org.jacoco</groupId> | |
<artifactId>jacoco-maven-plugin</artifactId> | |
<version>0.7.2.201409121644</version> | |
<executions> | |
<!-- Prepares the property pointing to the JaCoCo runtime agent | |
which is passed as VM argument when Maven the Surefire plugin is executed. --> | |
<execution> | |
<id>pre-unit-test</id> | |
<goals> | |
<goal>prepare-agent</goal> | |
</goals> | |
<configuration> | |
<!-- Sets the name of the property containing the settings for JaCoCo runtime agent. --> | |
<propertyName>surefireArgLine</propertyName> | |
</configuration> | |
</execution> | |
<!-- Ensures that the code coverage report for unit tests is created | |
after unit tests have been run. --> | |
<execution> | |
<id>post-unit-test</id> | |
<phase>test</phase> | |
<goals> | |
<goal>report</goal> | |
</goals> | |
<configuration> | |
<!-- Sets the output directory for the code coverage report. --> | |
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory> | |
</configuration> | |
</execution> | |
<execution> | |
<id>unit-test-check</id> | |
<goals> | |
<goal>check</goal> | |
</goals> | |
<configuration> | |
<rules> | |
<rule> | |
<element>BUNDLE</element> | |
<limits> | |
<limit> | |
<counter>LINE</counter> | |
<value>COVEREDRATIO</value> | |
<minimum>0.90</minimum> | |
</limit> | |
<limit> | |
<counter>BRANCH</counter> | |
<value>COVEREDRATIO</value> | |
<minimum>0.90</minimum> | |
</limit> | |
<limit> | |
<counter>METHOD</counter> | |
<value>COVEREDRATIO</value> | |
<minimum>0.90</minimum> | |
</limit> | |
<limit> | |
<counter>CLASS</counter> | |
<value>COVEREDRATIO</value> | |
<minimum>0.90</minimum> | |
</limit> | |
</limits> | |
</rule> | |
</rules> | |
</configuration> | |
</execution> | |
</executions> | |
</plugin> |
How Can I write Integration test in AEM ?
Very good example here https://github.com/sneakybeaky/AEM-Integration-Test-Example
It is based of sling test base https://sling.apache.org/documentation/development/sling-testing-tools.html
I know this information is not enough to have you set up for writing tests in AEM. Feel free to let me know if you have more question and I will add more stuff here.
It's A Really Nice Post.Thank You For sharing.....
ReplyDeleteBest Digital Marketing Courses in Bangalore
Hi DEAR..Thanks for sharing this post.I think it is a transcendent post. Such a wide number of an abundance of a dedication of appreciation is all together for this data. We Are Mobile Signal Booster
ReplyDeleteget in touch with us for mobile network solution
Hi DEAR ...It was actually wonderful reading this info and I think you are absolutely right and I truly appreciate the article post thanks for sharing... WE are WYOXSPORTS
ReplyDeleteweightlifting accessories contat us for all weightlifting accessories
Great Article… I love to read your articles because your writing style is too good, its is very very helpful for all of us and I never get bored while reading your article because, they are becomes a more and more interesting from the starting lines until the end. clark county detention center 24 hour bail bonds
ReplyDeleteGreat Article… I love to read your articles because your writing style is too good, its is very very helpful. yoga teacher training in rishikesh
ReplyDeleteyoga ttc in rishikesh
200 hours yoga teacher training in rishikesh
Thank you for sharing information.
ReplyDeleteSEO Company in Noida
Best SEO Company in Noida
Best SEO Services in Noida
I Really like your blog. Thanks for sharing..
ReplyDeleteWebsite Designing Company in Delhi
Zehra Global Services provides the best services Graphic Design, Software Development, Digital marketing and Mobile app development. It provides the best services to our customer.
ReplyDeleteMobile App Development
Graphic Design
Digital marketing
This comment has been removed by the author.
ReplyDeleteI found this article useful and looking forword for similar kind of blogs and if you want to know about TOP WEDDING PLANNERS CALGARY then u r at right place.
ReplyDeleteNice blogs and eagerly waiting for such blogs and if you looking forword for Affordable Web Development Services then you are right place.
ReplyDelete"Extraordinary Article… I want to peruse your articles on the grounds that your composition style is excessively great, its is extremely useful. I really value the article post a debt of gratitude is in order for sharing... WE are Ayurvedic Herbs Products get in touch with us for all Buy Wellness Products Online , Buy Ayurvedic Herbs Online
ReplyDeleteBuy Wellness Products"
Astrology vashikaran specialist
ReplyDeleteAstrologer for love solution
Ex love back vashikaran
ReplyDeleteBreakup problem solution
Astrologer for love solution
the best WordPress themes for business, blogging, and more. This accumulation of the Best Worpress Theme 2019 will enable you to build up a plan, Get your Best Matching Theme Now!
ReplyDeleteOn the off chance that u are Looking for another WordPress subject? Download the Best Wordpress Theme and layouts, Landing Page Templates , Free and Premium formats
Health is Wealth”, everyone have heard about this famous quote. When you have a healthy lifestyle, Lenalidomide Cost
ReplyDeleteThanks a lot for sharing this blog. I was searching for this topic for a while. Glad that I came across your blog. Great effort. Do share more.we are Wallpaper importer in Delhi
ReplyDeleteWorld's greatest astrologer Karan Sharma ji available at + 91-95777-44786 ; he is also Indian's best beneficial vashikaran expert for love and marriage.
ReplyDeleteI love to visit your site repeatedly because; here I find all information is very useful and educational for me.we are Interior Designer in Delhi
ReplyDeleteThanks a lot for sharing this blog. I was searching for this topic for a while. Glad that I came across your blog. Great effort. Do share more.we are Wallpaper importer in Delhi
ReplyDeleteGreat Article.Thank you for sharing such information -best pre school in punjab
ReplyDeletethanks for information if u want to know more about kindly visit us :- Car Interior Cleaning Dubai
ReplyDeleteShopclues here came up with an Offer where you can win special Shopclues Winner List 2019 by just playing a game & win prizes Call @6299249427
ReplyDeleteShopclues Winner List 2019
Shopclues Winner List
Shopclues Prize
Prize Shopclues
Thanks for sharing the information.
ReplyDeleteWeb Development Company in India
Digital Marketing Company
Mobile App Development Company
Graphic Design Company
We are providing Online Architectural Services, This is the most trustworthy site for planning application and building regulation drawings.
ReplyDeleteSnapdeal prize by just playing a game & win prizes Call @6289576795
ReplyDeletesnapdeal winner list 2020
snapdeal winner list 2020
snapdeal lucky draw
Snapdeal prize department
snapdeal winner name
snapdeal lucky customer