42
Test Java EE applications with Arquillian Ivan St. Ivanov

Testing Java EE apps with Arquillian

Embed Size (px)

Citation preview

Page 1: Testing Java EE apps with Arquillian

Test Java EE applications with Arquillian

Ivan St. Ivanov

Page 2: Testing Java EE apps with Arquillian

@ivan_stefanov

About me

@ivan_stefanovnosoftskills.com

Page 3: Testing Java EE apps with Arquillian

@ivan_stefanov

Page 4: Testing Java EE apps with Arquillian

@ivan_stefanov

Java EE Changed a LotStandalone technologies

◦EJB container◦JPA◦CDI

Arquillian testing framework

Page 5: Testing Java EE apps with Arquillian

@ivan_stefanov

Techniques to test Java EE appsTesting PersistenceTesting Contexts and Dependency Injection

(CDI)Testing business logicTesting whole scenarios

Page 6: Testing Java EE apps with Arquillian

@ivan_stefanov

The showcase appCollects match predictions from registered

usersAward points for correct predictionsUsed technologies

◦Java 8◦Java EE 8 – JPA, CDI, EJB, JAX-RS, JSF

Source code:https://github.com/ivannov/predcomposer

Page 7: Testing Java EE apps with Arquillian

@ivan_stefanov

Page 8: Testing Java EE apps with Arquillian

@ivan_stefanov

Testing PersistenceUse embedded databases (HSQLDB, Derby)Covered by other tests, often not neededUsed for quick check of persistence code

Page 9: Testing Java EE apps with Arquillian

@ivan_stefanov

1) Create persistence.xml<persistence version="2.1"> <persistence-unit name="predcomposer-test" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="javax.persistence.jdbc.driver“ value="org.hsqldb.jdbcDriver"/> <property name="javax.persistence.jdbc.url“ value="jdbc:hsqldb:mem:testdb"/> <property name="javax.persistence.jdbc.user" value="sa"/> <property name="javax.persistence.jdbc.password" value=""/> </properties> </persistence-unit></persistence>

Page 10: Testing Java EE apps with Arquillian

@ivan_stefanov

2) Initialize EntityManagerprotected static EntityManager entityManager;

@BeforeClasspublic static void setupTestObjects() { EntityManagerFactory emf = Persistence .createEntityManagerFactory( "predcomposer-test"); entityManager = emf.createEntityManager();}

Page 11: Testing Java EE apps with Arquillian

@ivan_stefanov

3) Begin transaction@Beforepublic void setUp() throws Exception { entityManager.getTransaction().begin(); insertTestData(); entityManager.flush(); this.competitionsService = new CompetitionsService(); competitionsService.entityManager = entityManager;}

Page 12: Testing Java EE apps with Arquillian

@ivan_stefanov

@Testpublic void shouldStoreCompetition() throws Exception { Competition newCompetition = new Competition( "Premiership 2015/2016", "The English Premier League"); Competition storedCompetition = competitionsService .storeCompetition(newCompetition); assertNotNull(storedCompetition.getId()); assertEquals(newCompetition, entityManager.find(Competition.class, storedCompetition.getId()));}

4) Write your test

Page 13: Testing Java EE apps with Arquillian

@ivan_stefanov

5) Cleanup@Afterpublic void tearDown() { entityManager.getTransaction().rollback();}

@AfterClasspublic static void closeEntityManager() { entityManager.close();}

Page 14: Testing Java EE apps with Arquillian

@ivan_stefanov

Page 15: Testing Java EE apps with Arquillian

@ivan_stefanov

Testing CDIUse CDI Unit or DeltaspikeLaunches CDI containerEasy injection of dependencies, mocks,

alternativesControl of requests and sessionsUsed for quick tests when dependencies and

scopes are involved

Page 16: Testing Java EE apps with Arquillian

@ivan_stefanov

1) Add dependency<dependency> <groupId>org.jglue.cdi-unit</groupId> <artifactId>cdi-unit</artifactId> <version>3.1.2</version> <scope>test</scope></dependency>

Page 17: Testing Java EE apps with Arquillian

@ivan_stefanov

@RunWith(CdiRunner.class)public class ViewGamePredictionsBeanTest { @Inject private ViewGamePredictionsBean bean;

@Test public void shouldLoadGamePredictionsUponRequest() { bean.showGamePredictions(game2); assertEquals(2, bean.getPredictions().size()); }}

2) Write the test

Page 18: Testing Java EE apps with Arquillian

@ivan_stefanov

@Alternativepublic class PredictionsServiceAlternative extends PredictionsService {

@Override public Set<Prediction> getPredictionsForGame(Game game) { // return two predictions }}

3) Create alternative

Page 19: Testing Java EE apps with Arquillian

@ivan_stefanov

@RunWith(CdiRunner.class)@ActivatedAlternatives({ PredictionsServiceAlternative.class,})public class ViewGamePredictionsBeanTest {

4) Add the alternative

Page 20: Testing Java EE apps with Arquillian

@ivan_stefanov

Page 21: Testing Java EE apps with Arquillian

@ivan_stefanov

Greeting earthlings

Page 22: Testing Java EE apps with Arquillian

@ivan_stefanov

Core principlesTests should be portable to any containerTests should be executable from both IDE and

build toolThe platform should extend existing test

frameworks

Page 23: Testing Java EE apps with Arquillian

@ivan_stefanov

Step 1 – pick a containerContainer extensions

◦JBoss, Tomcat, Weld, Glassfish, Jetty, WebSphere, WebLogic

Page 24: Testing Java EE apps with Arquillian

@ivan_stefanov

1) Add dependencies and profile<dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope></dependency><dependency> <groupId>org.wildfly</groupId> <artifactId> wildfly-arquillian-container-managed </artifactId> <scope>test</scope></dependency>

Page 25: Testing Java EE apps with Arquillian

@ivan_stefanov

Step 2 – connect the containerContainer types

◦Embedded ◦Managed◦Remote

Page 26: Testing Java EE apps with Arquillian

@ivan_stefanov

2) Configure container<arquillian> <container qualifier="arquillian-wildfly-managed"> <configuration> <property name="jbossHome"> target/wildfly-9.0.1.Final </property> </configuration> </container> </arquillian>

Page 27: Testing Java EE apps with Arquillian

@ivan_stefanov

Step 3 – package and deployShrinkWrap library

◦Deployment◦Resolve from Maven◦Create descriptors

Page 28: Testing Java EE apps with Arquillian

@ivan_stefanov

@RunWith(Arquillian.class)public class CompetitionsServiceIntegrationTest { @Deployment public static WebArchive createDeployment() { return ShrinkWrap.create(WebArchive.class) .addClass(CompetitionsService.class) .addPackage(Prediction.class.getPackage()) .addAsResource( new File("src/main/resources/META-INF/persistence.xml"), "META-INF/persistence.xml"); }}

3) Prepare the test archive

Page 29: Testing Java EE apps with Arquillian

@ivan_stefanov

Step 4 – run the testTests runs in-container

◦CDI, EJB, JNDI available◦No need to mock most of the services

Present the result as a normal unit test

Page 30: Testing Java EE apps with Arquillian

@ivan_stefanov

@Inject private CompetitionsService competitionsService;

@Test public void shouldCreateCompetition() throws Exception { testCompetition = new Competition("Premiership 2015/2016", "English Premier League"); testGame = new Game("Manchester City", "Juventus", LocalDateTime.of(2015, 9, 15, 21, 45)); testCompetition.getGames().add(testGame); Competition persistedCompetition = competitionsService.storeCompetition(testCompetition); assertNotNull(persistedCompetition.getId()); assertEquals(testCompetition, persistedCompetition); }

4.1) Write the test

Page 31: Testing Java EE apps with Arquillian

@ivan_stefanov

@RunWith(Arquillian.class)@RunAsClientpublic class CompetitionResourceTest { @Test public void shouldCreateCompetition(@ArquillianResource URL base) { URL url = new URL(base, "rest/competition"); WebTarget target = ClientBuilder.newClient().target(url.toExternalForm()); Form newCompetitionForm = new Form(); newCompetitionForm.param("name", COMPETITION_NAME); newCompetitionForm.param("description", DESCRIPTION); Response response = target.request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(newCompetitionForm, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); assertEquals(201, response.getStatus()); }}

4.2) Client side tests

Page 32: Testing Java EE apps with Arquillian

@ivan_stefanov

Step 5 – undeploy the testUndeploy the test archiveDisconnect or stop the container

Page 33: Testing Java EE apps with Arquillian

@ivan_stefanov

Page 34: Testing Java EE apps with Arquillian

@ivan_stefanov

That’s not allPersistence extensionWarpDroneGrapheneAngularJS, Android, OSGi…

Page 35: Testing Java EE apps with Arquillian

@ivan_stefanov

Graphene extensionDrive the application via page navigationSupport for AJAXPageObject pattern

Page 36: Testing Java EE apps with Arquillian

@ivan_stefanov

1) Add dependencies<dependency> <groupId>org.jboss.arquillian.extension</groupId> <artifactId>arquillian-drone-bom</artifactId> <type>pom</type> <scope>import</scope></dependency><dependency> <groupId>org.jboss.arquillian.selenium</groupId> <artifactId>selenium-bom</artifactId> <type>pom</type> <scope>import</scope></dependency><dependency> <groupId>org.jboss.arquillian.graphene</groupId> <artifactId>graphene-webdriver</artifactId> <type>pom</type> <scope>test</scope></dependency>

Page 37: Testing Java EE apps with Arquillian

@ivan_stefanov

2) Configure extension<arquillian> <extension qualifier="webdriver"> <property name="browser">phantomjs</property> </extension></arquillian>

Page 38: Testing Java EE apps with Arquillian

@ivan_stefanov

3) Create the page object@Location("login.jsf")public class LoginPage {

@FindBy(id = "loginForm:userName") private WebElement userName;

@FindBy(id = "loginForm:password") private WebElement password;

@FindBy(id = "loginForm:login") private WebElement loginButton;

public void login(String userName, String password) { this.userName.sendKeys(userName); this.password.sendKeys(password); guardHttp(loginButton).click(); }}

Page 39: Testing Java EE apps with Arquillian

@ivan_stefanov

4) Create the scenario test@RunWith(Arquillian.class)

@RunAsClientpublic class LoginScenarioTest { @Drone private WebDriver browser; @Page private HomePage homePage;

@Test public void shouldSayHelloUponSuccessfulLogin( @InitialPage LoginPage loginPage) { loginPage.login("ivan", "ivan"); homePage.assertGreetingMessage("Ivan"); homePage.assertGameFormVisible(true); }}

Page 40: Testing Java EE apps with Arquillian

@ivan_stefanov

Page 41: Testing Java EE apps with Arquillian

@ivan_stefanov

Page 42: Testing Java EE apps with Arquillian

@ivan_stefanov

Resources Showcase apphttps://github.com/ivannov/predcomposer Arquillianhttp://aslakknutsen.github.io/presentations/https://rpestano.wordpress.com/2014/06/08/arquillian/

https://rpestano.wordpress.com/2014/10/25/arquillian-and-mocks/