Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Alien Driven Development

Alien Driven Development

Integration Testing with Arquillian. An extended "over view about the Universe"-talk.

0fb625aef5a5feebdc02614a92e3af5e?s=128

Markus Eisele

July 01, 2013
Tweet

Transcript

  1. Alien Driven Development Integrationstests mit Java EE und Arquillian

  2. http://blog.eisele.net/ @myfear http://myfear.com/+ markus@eisele.net

  3. None
  4. © 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!
  5. © 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
  6. © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear

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

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

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

    - http://blog.eisele.net 9 You can’t develop what you can’t test.
  10. © 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.
  11. © 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
  12. © 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 …
  13. © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear

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

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

    - http://blog.eisele.net 15
  16. © 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
  17. © 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
  18. 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
  19. © 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
  20. © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear

    - http://blog.eisele.net 20 Basic Setup <dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.arquillian</groupId> <artifactId>arquillian-bom</artifactId> <version>1.0.4.Final</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement>
  21. © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear

    - http://blog.eisele.net 21 <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency> <!-- … --> </dependencies>
  22. © 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
  23. © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear

    - http://blog.eisele.net 23 <profiles> <profile> <id>arquillian-glassfish-managed</id> <dependencies> <dependency> <groupId>org.jboss.arquillian.container</groupId> <artifactId>arquillian-glassfish-managed-3.1</artifactId> <version>1.0.0.CR4</version> <scope>test</scope> </dependency> </dependencies> </profile> </profiles> https://docs.jboss.org/author/display/ARQ/Container+adapters
  24. © 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 + "!"; } }
  25. © 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")); } }
  26. © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear

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

    - http://blog.eisele.net 27 http://www.youtube.com/watch?v=VpZmIiIXuZ0
  28. © 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()); }
  29. © 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"); }
  30. © 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
  31. © 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()); } });
  32. © 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() { //…. } }
  33. © 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() { //…. } }
  34. © 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() { //…. } }
  35. © 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() { //…. } }
  36. © 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(); } }
  37. © 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.
  38. © 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(); } }
  39. © 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] }
  40. © 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. <dependency> <groupId>org.jboss.arquillian.extension</groupId> <artifactId>arquillian-screen-recorder</artifactId> <version>1.0.0.Alpha1</version> </dependency> <extension qualifier="screenRecorder"> <property name="rootFolder">target</property> <property name="videoFolder">video</property> <property name="videoName">myTestVideo</property> <property name="video">suite</property> <property name="screenshot">test</property> </extension>
  41. © 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. <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.6.3.201306030806</version> </plugin> <dependency> <groupId>org.jboss.arquillian.extension</groupId> <artifactId>arquillian-jacoco</artifactId> <version>1.0.0.Alpha5</version> </dependency>
  42. © 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<String>() { @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); }
  43. © 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()); }
  44. © 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(); }
  45. © 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. <dependency> <groupId>org.jboss.arquillian.extension</groupId> <artifactId>arquillian-jrebel-impl</artifactId> <version>1.0.0.Alpha1</version> </dependency>
  46. © 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; }
  47. © 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
  48. © 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. <container qualifier="android"> <configuration> <property name="adapterImplClass"> org.jboss.arquillian.container.android.managed.AndroidManagedDeployableContainer </property> </configuration> </container> @ArquillianResource AndroidDevice android; @Test @OperateOnDeployment("android1") public void test01() { assertTrue(android != null); } Droidium
  49. © 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.
  50. © 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 }
  51. © 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
  52. © msg Applied Technology Research, 01.07.2013 Markus Eisele - @myfear

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

    - http://blog.eisele.net 53 Questions?