Slide 1

Slide 1 text

Alien Driven Development Integrationstests mit Java EE und Arquillian

Slide 2

Slide 2 text

http://blog.eisele.net/ @myfear http://myfear.com/+ [email protected]

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 4 Testing is too hard. Testing isn’t fun. Testing is so sloow. Testing sucks!

Slide 5

Slide 5 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 5 Unit Tests Integration Tests System Tests Complexity Functional Test Code

Slide 6

Slide 6 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 6 You can’t fix what you can’t run.

Slide 7

Slide 7 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 7 You can’t fix what you can’t debug.

Slide 8

Slide 8 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 8 You can’t fix what you can’t test.

Slide 9

Slide 9 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 9 You can’t develop what you can’t test.

Slide 10

Slide 10 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 10 Not testing needs to be more painful And time consuming than using testing.

Slide 11

Slide 11 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 11 What is touched by testing? Frameworks Build IDE Server Client Code

Slide 12

Slide 12 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 12 Frameworks Build IDE Server Client EE Spring DI Maven Ant Gradle Eclipse NetBeans IntelliJ GlassFish Tomcat AS7 IE Chrome FF … … … … … Code Source Test Other …

Slide 13

Slide 13 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 13 http://www.youtube.com/watch?v=VpZmIiIXuZ0

Slide 14

Slide 14 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 14 An Innovative Testing Platform for the JVM

Slide 15

Slide 15 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 15

Slide 16

Slide 16 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 16 Guiding Principles  Tests should be portable to any supported container  Tests should be executable from IDE and build tool  Should extend or integrate existing test frameworks https://docs.jboss.org/author/display/ARQ/Reference+Guide

Slide 17

Slide 17 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 17 Source Test IDE Build Frameworks Tests Classes Server Deps Package ~ Client

Slide 18

Slide 18 text

arquillian © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 18 Source Test IDE Build Tests Classes Server Deps Package Client Package Client

Slide 19

Slide 19 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 19 Lifecycle  Select Container  Start Container  Package Archive  Run Test in Container  Show Results  Undeploy / Disconnect

Slide 20

Slide 20 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 20 Basic Setup org.jboss.arquillian arquillian-bom 1.0.4.Final import pom

Slide 21

Slide 21 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 21 javax javaee-web-api 7.0 provided junit junit 4.8.1 test org.jboss.arquillian.junit arquillian-junit-container test

Slide 22

Slide 22 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 22 Java EE Container Support Embedded Managed Remote https://docs.jboss.org/author/display/ARQ/Container+adapters

Slide 23

Slide 23 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 23 arquillian-glassfish-managed org.jboss.arquillian.container arquillian-glassfish-managed-3.1 1.0.0.CR4 test https://docs.jboss.org/author/display/ARQ/Container+adapters

Slide 24

Slide 24 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 24 @Stateless public class HelloBean { public String sayHello(String name) { return "Hello " + name + "!"; } }

Slide 25

Slide 25 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 25 @RunWith(Arquillian.class) public class HelloBeanIntegrationTest { @EJB HelloBean hello; @Deployment public static WebArchive createDeployment() { return ShrinkWrap.create(WebArchive.class) .addClass(HelloBean.class) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } @Test public void shouldSayHello() throws Exception { Assert.assertEquals("Hello Earthling!", hello.sayHello("Earthling")); } }

Slide 26

Slide 26 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 26

Slide 27

Slide 27 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 27 http://www.youtube.com/watch?v=VpZmIiIXuZ0

Slide 28

Slide 28 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 28 https://docs.jboss.org/author/display/ARQ/Drone Drone …brings power of Selenium into Arquillian framework. @Drone WebDriver driver; @Test @InSequence(1) public void login() { driver.get(contextPath + "home.jsf"); driver.findElement(USERNAME_FIELD).sendKeys(USERNAME); driver.findElement(PASSWORD_FIELD).sendKeys(PASSWORD); driver.findElement(LOGIN_BUTTON).click(); Assert.isTrue("User is logged in.", driver.findElement(LOGGED_IN).isDisplayed()); }

Slide 29

Slide 29 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 29 Graphene https://docs.jboss.org/author/display/ARQ/Graphene …brings power of Selenium and AJAX into Arquillian framework. @RunWith(Arquillian.class) public class TestLogin { @Drone WebDriver browser; @Page HomePage homePage; @Test(expects = LoginFailedException.class) public void testLoginFailed(){ homePage.login("non-existent", "user"); }

Slide 30

Slide 30 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 30 Warp https://github.com/arquillian/arquillian-extension-warp/blob/master/README.md …client-side test which asserts server-side logic. @RunWith(Arquillian.class) @WarpTest @RunAsClient public class BasicTest { //... } Warp .initiate(Activity) .inspect(Inspection); @BeforeServlet @AfterServlet @BeforePhase @AfterPhase

Slide 31

Slide 31 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 31 Warp .initiate(new Activity() { public void perform() { WebElement nameInput = browser.findElement(By.id("helloWorldJsf:nameInput")); nameInput.sendKeys("X"); browser.findElement(By.tagName("body")).click(); }}) .inspect(new Inspection() { private static final long serialVersionUID = 1L; @Inject CdiBean myBean; private String updatedName; @BeforePhase(UPDATE_MODEL_VALUES) public void initial_state_havent_changed_yet() { assertEquals("John", myBean.getName()); } });

Slide 32

Slide 32 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 32 Transaction https://github.com/arquillian/arquillian-extension-transaction …enhances your tests with transaction support. @RunWith(Arquillian.class) public class TransactionTest { @Deployment public static WebArchive deployment() { //... } @Test @Transactional(TransactionMode.ROLLBACK) public void test() { //…. } }

Slide 33

Slide 33 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 33 Persistence https://docs.jboss.org/author/display/ARQ/Persistence …helps with database wrangling. @RunWith(Arquillian.class) public class PersistenceTest { @Deployment public static WebArchive deployment() { //... .addAsResource("test-persistence.xml", "persistence.xml"); } @Test @UsingDataSet("datasets/users.yml") @ShouldMatchDataSet("datasets/expected-users.yml") public void test() { //…. } }

Slide 34

Slide 34 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 34 https://docs.jboss.org/author/display/ARQ/Persistence @RunWith(Arquillian.class) @CreateSchema("scripts/ddl.sql") public class PersistenceTest { @Deployment public static WebArchive deployment() { //... .addAsManifestResource("test-persistence.xml", "persistence.xml"); } @Test @UsingDataSet("datasets/users.yml") @ShouldMatchDataSet("datasets/expected-users.yml") @CleanupUsingScript("drop-schema.sql") public void test() { //…. } }

Slide 35

Slide 35 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 35 Performance https://docs.jboss.org/author/display/ARQ/Performance …keeps your tests in time. @RunWith(Arquillian.class) @PerformanceTest(resultsThreshold = 2) public class PersformanceTest { @Deployment public static WebArchive deployment() { //... } @Test @Performance(time = 575) public void test() { //…. } }

Slide 36

Slide 36 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 36 Seam 2 https://docs.jboss.org/author/display/ARQ/Seam+2 …bringing Seam 2 Context to Arquillian. @RunWith(Arquillian.class) public class ComponentInjectionTest { @Deployment public static WebArchive deployment() { //... .addAsResource(EmptyAsset.INSTANCE, "seam.properties"); } @In SomeSeamComponent component; @Test public void test() { assertThat(component).isNotNull(); } }

Slide 37

Slide 37 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 37 Spring https://github.com/arquillian/arquillian-extension-spring …bringing Spring 2 and 3 to Arquillian. • Injection of Spring beans into test classes • Configuration from both XML and Java-based config • Injecting beans configured in web application (e.g. DispatcherServlet) for tests annotated with @SpringWebConfiguration • Support for both Spring(@Autowired, @Qualifier, @Required) and JSR-330(@Inject, @Named) annotations • Bean initialization support (@PostConstruct) • Auto packaging the spring-context and spring-web artifacts.

Slide 38

Slide 38 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 38 Guice https://github.com/arquillian/arquillian-extension-guice …bringing Guice DI to Arquillian. @RunWith(Arquillian.class) @GuiceConfiguration(AppointmentModule.class) public class ComponentInjectionTest { @Deployment public static WebArchive deployment() { //... } @Inject @Named("appointmentService") private AppointmentService appointmentService; @Test public void test() { assertThat(appointmentService).isNotNull(); } }

Slide 39

Slide 39 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 39 Spock https://github.com/arquillian/arquillian-testrunner-spock …bringing Spock Testing to Arquillian. @Inject AccountService service def "transferring between accounts should result in account withdrawal and deposit"() { when: service.transfer(from, to, amount) then: from.balance == fromBalance to.balance == toBalance where: from << [new Account(100), new Account(10)] to << [new Account(50), new Account(90)] amount << [50, 10] fromBalance << [50, 0] toBalance << [100, 100] }

Slide 40

Slide 40 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 40 Screen Recorder https://github.com/arquillian/arquillian-extension-screenrecorder …records your tests. org.jboss.arquillian.extension arquillian-screen-recorder 1.0.0.Alpha1 target video myTestVideo suite test

Slide 41

Slide 41 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 41 Jacoco https://github.com/arquillian/arquillian-extension-jacoco …gives you test-coverage. org.jacoco jacoco-maven-plugin 0.6.3.201306030806 org.jboss.arquillian.extension arquillian-jacoco 1.0.0.Alpha5

Slide 42

Slide 42 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 42 Google Web Toolkit https://github.com/arquillian/arquillian-extension-gwt … brings Arquillian to GWT. @Test @RunAsGwtClient(moduleName = "org.myapp.MyGwtModule") public void testGreetingService() { GreetingServiceAsync greetingService = GWT.create(GreetingService.class); greetingService.greetServer("Hello!", new AsyncCallback() { @Override public void onFailure(Throwable caught) { Assert.fail("Request failure: " + caught.getMessage()); } @Override public void onSuccess(String result) { assertEquals("Received invalid response from Server", "Welcome!", result); finishTest(); } }); delayTestFinish(5000); }

Slide 43

Slide 43 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 43 Portal https://github.com/arquillian/arquillian-extension-portal …help you write tests for portlets. @RunWith(Arquillian.class) @PortalTest public class PortletTest { @Deployment public static WebArchive deployment() { //... } @ArquillianResource @PortalURL URL portalURL; @Test @RunAsClient public void renderFacesPortlet() throws Exception { browser.get(portalURL.toString()); }

Slide 44

Slide 44 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 44 https://github.com/arquillian/arquillian-extension-byteman Byteman …gives you runtime bytecode manipulation. @RunWith(Arquillian.class) @BMRules( @BMRule( name = "Throw exception on success", targetClass = "StatelessManagerBean", targetMethod = "forcedClassLevelFailure", action = "throw new java.lang.RuntimeException()") ) public class BytemanFaultInjectionTestCase { //… @EJB(mappedName = "java:module/StatelessManagerBean") private StatelessManager bean; @Test(expected = EJBException.class) { Assert.assertNotNull("Verify bean was injected", bean); bean.forcedMethodLevelFailure(); }

Slide 45

Slide 45 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 45 JRebel https://github.com/arquillian/arquillian-extension-jrebel … hot-deploy your integration tests. org.jboss.arquillian.extension arquillian-jrebel-impl 1.0.0.Alpha1

Slide 46

Slide 46 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 46 OSGi https://github.com/arquillian/arquillian-container-osgi … brings Arquillian to OSGi Frameworks. @RunWith(Arquillian.class) public class SimpleBundleTestCase { @ArquillianResource BundleContext context; @Deployment public static JavaArchive createdeployment() { final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "test.jar"); archive.setManifest(new Asset() { public InputStream openStream() { OSGiManifestBuilder builder = OSGiManifestBuilder.newInstance(); builder.addBundleSymbolicName(archive.getName()); builder.addBundleManifestVersion(2); builder.addImportPackages(Bundle.class); return builder.openStream(); } }); return archive; }

Slide 47

Slide 47 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 47 @Test public void testBundleContextInjection() { assertNotNull("BundleContext injected", context); assertEquals("System Bundle ID", 0, context.getBundle().getBundleId()); } @Test public void testBundleInjection(@ArquillianResource Bundle bundle) { // Assert that the bundle is injected assertNotNull("Bundle injected", bundle); // Assert that the bundle is in state RESOLVED // Note when the test bundle contains the test case it // must be resolved already when this test method is called assertEquals("Bundle RESOLVED", Bundle.RESOLVED, bundle.getState()); // Start the bundle bundle.start(); assertEquals("Bundle ACTIVE", Bundle.ACTIVE, bundle.getState()); https://github.com/arquillian/arquillian-container-osgi

Slide 48

Slide 48 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 48 https://github.com/arquillian/arquillian-droidium …brings Native and WebDriver based testing to Android devices. org.jboss.arquillian.container.android.managed.AndroidManagedDeployableContainer @ArquillianResource AndroidDevice android; @Test @OperateOnDeployment("android1") public void test01() { assertTrue(android != null); } Droidium

Slide 49

Slide 49 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 49 iOS Platform https://github.com/arquillian/arquillian-extension-ios …brings Native and WebDriver based testing to iOS devices.

Slide 50

Slide 50 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 50 QUnit automates the QUnit JavaScript testing on Web Applications @RunWith(QUnitRunner.class) @QUnitResources("src/test/resources/assets") public class QUnitRunnerTestCase { @QUnitTest("tests/ticketmonster/qunit-tests-dom.html") @InSequence(1) public void qunitDomTest() { // empty body - only the annotations are used }

Slide 51

Slide 51 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 51 Cukespace … deploy and run Cucumber features using Arquillian. @RunWith(ArquillianCucumber.class) public class CukesInBellyTest { @Deployment public static Archive> createDeployment() { return ShrinkWrap.create(WebArchive.class) //… .addAsResource("my/features/cukes.feature"); } @EJB private CukeService service; @Inject private CukeLocator cukeLocator; @When("^I persist my cuke$") public void persistCuke() { this.service.persist(this.cukeLocator.findCuke()); } } https://github.com/cukespace/cukespace

Slide 52

Slide 52 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 52

Slide 53

Slide 53 text

© msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear - http://blog.eisele.net 53 Questions?