$30 off During Our Annual Pro Sale. View Details »

Alien Driven Development

Alien Driven Development

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

Markus Eisele

July 01, 2013
Tweet

More Decks by Markus Eisele

Other Decks in Technology

Transcript

  1. Alien Driven Development
    Integrationstests mit Java EE und Arquillian

    View Slide

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

    View Slide

  3. View Slide

  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!

    View Slide

  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

    View Slide

  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.

    View Slide

  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.

    View Slide

  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.

    View Slide

  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.

    View Slide

  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.

    View Slide

  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

    View Slide

  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 …

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  20. © 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



    View Slide

  21. © 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



    View Slide

  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

    View Slide

  23. © 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

    View Slide

  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 + "!";
    }
    }

    View Slide

  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"));
    }
    }

    View Slide

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

    View Slide

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

    View Slide

  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());
    }

    View Slide

  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");
    }

    View Slide

  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

    View Slide

  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());
    }
    });

    View Slide

  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() {
    //….
    }
    }

    View Slide

  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() {
    //….
    }
    }

    View Slide

  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() {
    //….
    }
    }

    View Slide

  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() {
    //….
    }
    }

    View Slide

  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();
    }
    }

    View Slide

  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.

    View Slide

  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();
    }
    }

    View Slide

  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]
    }

    View Slide

  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.

    org.jboss.arquillian.extension
    arquillian-screen-recorder
    1.0.0.Alpha1


    target
    video
    myTestVideo
    suite
    test

    View Slide

  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.

    org.jacoco
    jacoco-maven-plugin
    0.6.3.201306030806


    org.jboss.arquillian.extension
    arquillian-jacoco
    1.0.0.Alpha5

    View Slide

  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() {
    @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);
    }

    View Slide

  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());
    }

    View Slide

  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();
    }

    View Slide

  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.

    org.jboss.arquillian.extension
    arquillian-jrebel-impl
    1.0.0.Alpha1

    View Slide

  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;
    }

    View Slide

  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

    View Slide

  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.



    org.jboss.arquillian.container.android.managed.AndroidManagedDeployableContainer



    @ArquillianResource
    AndroidDevice android;
    @Test
    @OperateOnDeployment("android1")
    public void test01() {
    assertTrue(android != null);
    }
    Droidium

    View Slide

  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.

    View Slide

  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
    }

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide