Integration Testing with Arquillian. An extended "over view about the Universe"-talk.
Alien Driven DevelopmentIntegrationstests mit Java EE und Arquillian
View Slide
http://blog.eisele.net/@myfearhttp://myfear.com/+[email protected]
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net4Testing is too hard.Testing isn’t fun.Testing is so sloow.Testing sucks!
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net5Unit Tests Integration Tests System TestsComplexityFunctionalTest Code
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net6You can’t fix what you can’t run.
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net7You can’t fix what you can’t debug.
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net8You can’t fix what you can’t test.
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net9You can’t develop what you can’t test.
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net10Not testing needs to be more painfulAnd time consuming than using testing.
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net11What is touchedby testing?FrameworksBuildIDEServerClientCode
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net12FrameworksBuildIDEServerClientEE Spring DIMaven Ant GradleEclipse NetBeans IntelliJGlassFish Tomcat AS7IE Chrome FF……………Code Source Test Other …
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net13http://www.youtube.com/watch?v=VpZmIiIXuZ0
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net14An Innovative Testing Platform for the JVM
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net15
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net16Guiding Principles Tests should be portable to any supported container Tests should be executable from IDE and build tool Should extend or integrate existing test frameworkshttps://docs.jboss.org/author/display/ARQ/Reference+Guide
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net17SourceTestIDEBuildFrameworksTests ClassesServerDepsPackage~Client
arquillian© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net18SourceTestIDEBuildTests ClassesServerDepsPackageClientPackageClient
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net19Lifecycle Select Container Start Container Package Archive Run Test in Container Show Results Undeploy / Disconnect
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net20Basic Setuporg.jboss.arquillianarquillian-bom1.0.4.Finalimportpom
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net21javaxjavaee-web-api7.0providedjunitjunit4.8.1testorg.jboss.arquillian.junitarquillian-junit-containertest
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net22Java EE Container SupportEmbedded Managed Remotehttps://docs.jboss.org/author/display/ARQ/Container+adapters
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net23arquillian-glassfish-managedorg.jboss.arquillian.containerarquillian-glassfish-managed-3.11.0.0.CR4testhttps://docs.jboss.org/author/display/ARQ/Container+adapters
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net24@Statelesspublic class HelloBean {public String sayHello(String name) {return "Hello " + name + "!";}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net25@RunWith(Arquillian.class)public class HelloBeanIntegrationTest {@EJBHelloBean hello;@Deploymentpublic static WebArchive createDeployment() {return ShrinkWrap.create(WebArchive.class).addClass(HelloBean.class).addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");}@Testpublic void shouldSayHello() throws Exception {Assert.assertEquals("Hello Earthling!", hello.sayHello("Earthling"));}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net26
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net27http://www.youtube.com/watch?v=VpZmIiIXuZ0
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net28https://docs.jboss.org/author/display/ARQ/DroneDrone…brings power of Selenium into Arquillian framework.@DroneWebDriver 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());}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net29Graphenehttps://docs.jboss.org/author/display/ARQ/Graphene…brings power of Selenium and AJAX into Arquillianframework.@RunWith(Arquillian.class)public class TestLogin {@DroneWebDriver browser;@PageHomePage homePage;@Test(expects = LoginFailedException.class)public void testLoginFailed(){homePage.login("non-existent", "user");}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net30Warphttps://github.com/arquillian/arquillian-extension-warp/blob/master/README.md…client-side test which asserts server-side logic.@RunWith(Arquillian.class)@WarpTest@RunAsClientpublic class BasicTest {//...}Warp.initiate(Activity).inspect(Inspection);@BeforeServlet@AfterServlet@BeforePhase@AfterPhase
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net31Warp.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;@InjectCdiBean myBean;private String updatedName;@BeforePhase(UPDATE_MODEL_VALUES)public void initial_state_havent_changed_yet() {assertEquals("John", myBean.getName());}});
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net32Transactionhttps://github.com/arquillian/arquillian-extension-transaction…enhances your tests with transaction support.@RunWith(Arquillian.class)public class TransactionTest {@Deploymentpublic static WebArchive deployment() {//...}@Test@Transactional(TransactionMode.ROLLBACK)public void test() {//….}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net33Persistencehttps://docs.jboss.org/author/display/ARQ/Persistence…helps with database wrangling.@RunWith(Arquillian.class)public class PersistenceTest {@Deploymentpublic static WebArchive deployment() {//....addAsResource("test-persistence.xml", "persistence.xml");}@Test@UsingDataSet("datasets/users.yml")@ShouldMatchDataSet("datasets/expected-users.yml")public void test() {//….}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net34https://docs.jboss.org/author/display/ARQ/Persistence@RunWith(Arquillian.class)@CreateSchema("scripts/ddl.sql")public class PersistenceTest {@Deploymentpublic 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() {//….}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net35Performancehttps://docs.jboss.org/author/display/ARQ/Performance…keeps your tests in time.@RunWith(Arquillian.class)@PerformanceTest(resultsThreshold = 2)public class PersformanceTest {@Deploymentpublic static WebArchive deployment() {//...}@Test@Performance(time = 575)public void test() {//….}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net36Seam 2https://docs.jboss.org/author/display/ARQ/Seam+2…bringing Seam 2 Context to Arquillian.@RunWith(Arquillian.class)public class ComponentInjectionTest {@Deploymentpublic static WebArchive deployment() {//....addAsResource(EmptyAsset.INSTANCE, "seam.properties");}@InSomeSeamComponent component;@Testpublic void test() {assertThat(component).isNotNull();}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net37Springhttps://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) andJSR-330(@Inject, @Named) annotations• Bean initialization support (@PostConstruct)• Auto packaging the spring-context and spring-web artifacts.
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net38Guicehttps://github.com/arquillian/arquillian-extension-guice…bringing Guice DI to Arquillian.@RunWith(Arquillian.class)@GuiceConfiguration(AppointmentModule.class)public class ComponentInjectionTest {@Deploymentpublic static WebArchive deployment() {//...}@Inject@Named("appointmentService")private AppointmentService appointmentService;@Testpublic void test() {assertThat(appointmentService).isNotNull();}}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net39Spockhttps://github.com/arquillian/arquillian-testrunner-spock…bringing Spock Testing to Arquillian.@InjectAccountService servicedef "transferring between accounts should result in account withdrawal anddeposit"() {when:service.transfer(from, to, amount)then:from.balance == fromBalanceto.balance == toBalancewhere:from << [new Account(100), new Account(10)]to << [new Account(50), new Account(90)]amount << [50, 10]fromBalance << [50, 0]toBalance << [100, 100]}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net40Screen Recorderhttps://github.com/arquillian/arquillian-extension-screenrecorder…records your tests.org.jboss.arquillian.extensionarquillian-screen-recorder1.0.0.Alpha1targetvideomyTestVideosuitetest
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net41Jacocohttps://github.com/arquillian/arquillian-extension-jacoco…gives you test-coverage.org.jacocojacoco-maven-plugin0.6.3.201306030806org.jboss.arquillian.extensionarquillian-jacoco1.0.0.Alpha5
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net42Google Web Toolkithttps://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() {@Overridepublic void onFailure(Throwable caught) {Assert.fail("Request failure: " + caught.getMessage());}@Overridepublic void onSuccess(String result) {assertEquals("Received invalid response from Server", "Welcome!", result);finishTest();}});delayTestFinish(5000);}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net43Portalhttps://github.com/arquillian/arquillian-extension-portal…help you write tests for portlets.@RunWith(Arquillian.class)@PortalTestpublic class PortletTest {@Deploymentpublic static WebArchive deployment() {//...}@ArquillianResource@PortalURLURL portalURL;@Test@RunAsClientpublic void renderFacesPortlet() throws Exception {browser.get(portalURL.toString());}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net44https://github.com/arquillian/arquillian-extension-bytemanByteman …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();}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net45JRebelhttps://github.com/arquillian/arquillian-extension-jrebel… hot-deploy your integration tests.org.jboss.arquillian.extensionarquillian-jrebel-impl1.0.0.Alpha1
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net46OSGihttps://github.com/arquillian/arquillian-container-osgi… brings Arquillian to OSGi Frameworks.@RunWith(Arquillian.class)public class SimpleBundleTestCase {@ArquillianResourceBundleContext context;@Deploymentpublic 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;}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net47@Testpublic void testBundleContextInjection() {assertNotNull("BundleContext injected", context);assertEquals("System Bundle ID", 0, context.getBundle().getBundleId());}@Testpublic void testBundleInjection(@ArquillianResource Bundle bundle) {// Assert that the bundle is injectedassertNotNull("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 calledassertEquals("Bundle RESOLVED", Bundle.RESOLVED, bundle.getState());// Start the bundlebundle.start();assertEquals("Bundle ACTIVE", Bundle.ACTIVE, bundle.getState());https://github.com/arquillian/arquillian-container-osgi
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net48https://github.com/arquillian/arquillian-droidium…brings Native and WebDriver based testing toAndroid devices.org.jboss.arquillian.container.android.managed.AndroidManagedDeployableContainer@ArquillianResourceAndroidDevice android;@Test@OperateOnDeployment("android1")public void test01() {assertTrue(android != null);}Droidium
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net49iOS Platformhttps://github.com/arquillian/arquillian-extension-ios…brings Native and WebDriver based testing toiOS devices.
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net50QUnit automates the QUnit JavaScript testing on WebApplications@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}
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net51Cukespace … deploy and run Cucumber features using Arquillian.@RunWith(ArquillianCucumber.class)public class CukesInBellyTest {@Deploymentpublic 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
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net52
© msg Applied Technology Research, 01.07.2013Markus Eisele - @myfear - http://blog.eisele.net53Questions?