Devoxx 2012 Hackergarten Overdrive!

Kick-off

Each project represented at Hackergarten briefly introduced itself and presented ideas to hack on. The presence of Red Hat community projects was very strong (~75%). We’re happy to report that there was lots of interest in Arquillian. It received the most votes for hacking, with JBoss Forge drawing in the second most.

General impressions

The Hackergarten was held in open areas at the back of the pavilion. The areas gave plenty of privacy, but also gave people freedom to move around. We didn’t have to experience that awkwardness of peeking through a door or the distraction of doors opening and closing. We were able to do demos in one section without affecting hacks or discussions going on in other sections because there was enough ambient noise, mostly music from the trade floor. The wired connections provided by switches at each table removed the distraction of getting on wifi, although it took a bit of time and some shuffling around in the morning to figure all that out.

Once we knew to get everyone plugged into the switches, we were off to the hacking races!

Pictures!

See more pictures in Album 1 and Album 2.

Hacking Overview (related to testing)

Code Contributions

Design Discussions

  • Arquillian Drone + Thucydides
  • Arquillian Ape + NoSQLUnit
  • Drools rules, Drools decision tables and Drools planner for filtering, prioritizing and coordinating distribution of tests in a suite
  • IntelliJ support for Arquillian, JBoss Forge
  • Using the web browser as a “container” to incorporate JavaScript tests into a Drone test
  • Juzu demo and shout out to use of Arquillian for testing
  • Jersey looking into adoption of Arquillian in test suite
  • Using Thucydides for CDI test suite and supporting spec documentation

Activity Stream (related to testing)

  • At the start of the event, I suggested the hack idea to integrate Arquilliun Drone and FluentLenium to Jan Papoušek
    • Jan and I introduced ourselves to Mathilde Lemee and they got to work on the integration straight away, starting off by sharing with each other how their respective projects worked.
    • By days end, they completed a working integration
    • Mathilde also integrated FluentLenium with Thucydides (“2 CDs”); stay tuned because that integration and the integration with Drone may become one and the same
    • In both cases, the integration with FluentLenium was so straightforward (and thus hackable) because of the nice abstraction layer Mathilde created that handled bootstrapping FluentLenium
  • Aslak hacked with Hans Dockter, creator of Gradle, on a gradle deployment plugin that uses Arquillian Containers to handle life cycle of dozens of containers (application servers, servlet containers and beyond)
  • Bartosz Majsak hacked on a demo for Arquillian Ape and enhanced Arquillian Transaction to work both in-container and embedded
  • I spoke with two of the IntelliJ developers (Peter and Yann) about:
    • a plugin for Arquillian (similar to the Eclipse Arquillian plugin)
    • adding an embedded Forge shell with UI interplay (similar to the JBoss Forge view in JBoss Tools)
  • I chatted with Julien Viet about:
  • Later in the day, Julien gave a presentation and demo of Juzu, excited to say it’s tested w/ Arquillian Core and Arquillian Drone
  • I brainstormed with Geoffrey De Smet, lead of Drools Planner, about:
    • using rules to handle the filtering decision for tests
    • the role decision tables can play in declaring conditions for which tests to run
    • optimizing test suite execution using Drools Planner and distributing tests over a grid
  • I spoke with John Smart about Arquillian Core and Arquillian Drone integration with Thucydides
    • We discussed how much the two projects align and what it would take to integrate
    • We concluded the first step is adding a bootstrap API in Thucydides, which he began to flesh out, that could be hooked to the Arquillian event model and all the integrations with individual test runners can be done once in Arquillian
    • We talked about how Drone could likely provide management of WebDriver
    • John Smart has been busy all week working on a bootstrap API for Thucydides (hacking on it with an ATDD approach, of course)
  • Koen Aers gave a demonstration of the JBoss Forge integration in JBoss Tools, talked about each of elements it brings to the Forge experience in the IDE
    • Koen wrote his first “Hello, World” IntelliJ plugin to get spun up and prepare to help with the integration
    • IntelliJ said they would put it on their roadmap and support the effort where possible
  • Alex Soto and Bartosz discussed integrating NoSQLUnit into Arquillian Ape (peristence extension)
    • These projects closely align and it pushes Arquillian’s definition of container management forward
    • I told Marek Jelen about Alex’s NoSQLUnit demo of testing MongoDB on OpenShift through the port forwarding setup by JBoss Tools; a blog entry may be in the works;
    • Arquillian + NoSQLUnit has lots of application, one of which may be testing NoSQL backends in the Infinispan project
  • Alexis Hassler was busy improving the Arquillian adapter for CloudBees by adding EJB injection support.
  • Aslak discussed with JAX-RS lead about using Arquillian for JAX-RS TCK; not likely soon, but Jersey is entertaining idea of using Arquillian to test Jersey (JAX-RS reference implementation)
  • I spoke with Paul Bakker briefly about combining the Forge Arquillian plugin and the Forge Arquillian Extension plugin into one code base
  • I brainstormed with David Blevins, lead of TomEE, about the role a test suite can play in the early and in-progress development of a specification
    • proposed idea of using a ATDD approach where tests could be not only marked as pending (before a ref impl is in place), but also proposed, open question and alternative
    • agreed that using tests can focus the discussion about the spec, clarify ambiguities & resolve different interpretations
    • John Smart gave a demo of Thucydides and we contemplated using it for the CDI test suite

Wrap-up

As the event wound down, I discussed with Andres Almiray, who organized the Hackergarten, about what went on during the day, whether Hackergarten accomplished his goals. He talked about the importance of giving people a chance to make a concrete contribution, give them a win to take home with them, lower perception of a barrier to contributing. I talked to him about the fact that Hackergarten is a catalyst for ideas, some of which come into play before the event, already successful and is also ongoing throughout the week, so we’ll only know total impact once conference is over. Some ideas take time to soak. I can attest, we’re still hacking ;)

Finally, Arquillian was invited to join the Nighthacking Tour hosted by Steven Chin on on Wednesday night, so look for that coverage when it comes online.

What people were tweeting…

  • Bartosz Majsak (@majson) posted: #devoxx #arquillian @aslakknutsen you have some pull requests
  • Markus Eisele (@myfear) posted: What could be the next cool #Arquillian feature? creative @aslakknutsen at the #hackergarden http://twitpic.com/bcv2lv
  • Alexis Hassler (@AlexisHassler) posted: GREEN BAR on my #arquillian test. Cloudbees Container Adapter is getting further, thanks to @majson & @aslakknutsen
  • Aslak Knutsen (@aslakknutsen) posted: Hacking #Arquillian Container control plugin for #SBT & #Leiningen. #Gradle next…
  • Jan Papousek (@jan_papousek) posted: @MathildeLemee the first attempt of integration FluentLenium and Arquillian is here https://github.com/papousek/arquillian-extension-fluentlenium
  • Mathilde Lemee (@MathildeLemee) posted: integrating FluentLenium to Arquillian Drone with @jan_papousek
  • John Smart (@wakaleo) posted: Awesome concentrated hacking session with @MathildeLemee: integrating #thucydides and FluentLenium in less than 10 lines of code.
  • Alex Soto (@alexsotob) posted: @majson Back home ty Arquillian guys for treat me as one of your team

Get Test-Infected at Devoxx 2012

It’s no suprise we’re obsessed with testing here in the Arquillian Galaxy. We’re eternally interested in sharpening our testing weapons, learning about tools that advance the frontline against the bugs, and discovering all the deep, dark code caves where bugs try to hide from testers.

This year, Devoxx, one of the premier Java developer conferences, is bringing together a large group of testing experts. Listed below are just some of the labs, workshops, and BOFs being presented at Devoxx that will enhance your bug hunting skills.

Monday, November 12, 2012

NoSQLUnit. Testing Your NoSQL Databases.

Alex Soto, Tools in Action

Unit tests should follow the FIRST rules (Fast, Isolated, Repeatable, Self-Validated and Timely). When persistence layer is under test, fast and isolated rules are the most violated. For relational database management systems, embedded databases and DbUnit framework exist to help us to not break them, but there is no like DBUnit framework for heterogeneous NoSQL systems. More »

Blast Your WebApp with Galting

Stephane Landelle and Romain Sertelon, Tools in Action

Your application is going live tomorrow, the new marketing campaign is about to start, you enjoy a margarita, life is good. Yet something keeps bugging you, are you sure your webapp won’t crash down? “Damn, forgot about the stress tests!” Traffic grows, data grows, our applications have to withstand increasing loads, so stress tests are more and more of a critical issue. More »

The Bugs Are Building Another Death Star

Multi-framework, battle hardened testers including members of Ike’s Crew, BOF

The bugs are building another Death Star. What’s our invasion plan?

Bugs don’t rest when you go to sleep. In fact, you should worry most when they are left alone. They are tireless creatures, hard at work to destroy your home. In software, it’s no different. We are at constant war with bugs. News flash, the bugs are building another Death Star and we’re just standing by! Let’s plot an invasion plan during this moderated discussion on the topic of enterprise testing. More »

Tuesday, November 13, 2012

To ATDD and Beyond! Better Automated Acceptance Testing on the JVM

John Smart, University

Test Driven Development is a game changer for developers, but Automated Acceptance Testing (ATDD) is a game changer for the whole team! More than just a testing technique, Automated Acceptance Testing is both a collaboration tool and a vital step on the road to Continuous Delivery. In this talk, you will see a real-world demo applying practical ATDD techniques to real-world projects using JBehave, Selenium 2 and Thucydides. More »

Testacular – Spectacular Test Runner for JavaScript

Vojta Jina, Tools in Action

Introduction to Testacular – test runner that makes makes testing JavaScript applications in real browsers frictionless and enjoyable. More »

JUnit Rules

Jens Schauder, Tools in Action

We all know JUnit rulez. But do you know JUnit Rules? Rules are a not so well known feature of JUnit. They allow us to encapsulate setup and teardown in a reusable package. You can manipulate the way tests get executed as well. More »

Wednesday, November 14, 2012

Testing Java Persistence Layer Done Right with Arquillian

Bartosz Majsak, Quickie

The Persistence Layer is one of the most crucial parts of enterprise applications, and we use many different frameworks and patterns to keep it clean. We write sophisticated queries and use optimization techniques to give our end users the greatest possible experience. So why is Persistence very often skipped in testing efforts? Is it really that complex and painful to setup? The Arquillian Persistence Extension removes that burden and boilerplate to make you a happy and productive programmer again. More »

Behaviour Driven Development on the JVM – A State of the Union

John Smart, Conference

Behavior Driven Development (BDD) is an increasingly popular variation on Test Driven Development, which helps developers think more about what they are testing, in terms of “executable specifications” rather than conventional tests. But there are dozens of BDD tools for the JVM out there: how do you know what to use, and when? More »

Thursday, November 15, 2012

Unitils: Full Stack Testing Solution for Enterprise Applications

Thomas De Rycke and Jeroen Horemans, Conference

Automated testing is the key to developing high quality software and maintainable codebases. How can we automate testing when data and database schemes are constantly evolving? How can we test infrastructure related components like automated e-mails without actually sending them? More »

Do You REST Assured?

Johan Haleby, Quickie

Today it’s easy to expose services as REST/HTTP with frameworks like Jersey and Spring but validating that the server actually behaves as expected can be cumbersome in Java. REST Assured is an open source Java DSL that allows you to avoid boiler-plate code to make requests and validate even complex responses in a simple manner. More »

JavaScript Unit Testing and Build Integration

Wouter Groeneveld, Conference

Unit testing has become very popular with the rise of test-first software development. Most enterprise applications contain only a small portion of javascript code, almost always completely untested. We have seen a steady increase of javascript code and frameworks lately, but for most people it’s still unclear how to (unit) test javascript, and most of all how to properly integrate these within your build environment next to other JUnit test cases. More »

Apache TomEE, Java EE 6 Web Profile on Tomcat

David Blevins, Conference

Apache TomEE is the Java EE 6 Web Profile certified version of Apache Tomcat and combines the simplicity of Tomcat with the power of Java EE. The first half of this session introduces TomEE and shows how Tomcat applications leveraging Java EE technologies can become simpler and lighter with a Java EE 6 certified solution built right on Tomcat. More »

Spock: Boldly Go Where No Test Has Gone Before

Andres Almiray, Quickie

Testing, testing, testing. We all know it has to be done but no one likes to do it. Enter Spock, a revolutionary way to writing (and thinking about) test code, that promises to wash away the pain and bring back the fun. More »

We look forword to hearing what testing tools, techniques and strategies you discover at Devoxx 2012.

Hack Idea: Fully Automate ATDD by Integrating Thucydides with Arquillian

Imagine being able to organize and structure your Arquillian tests as human-readable specifications by example that describe at a high-level how the application should work, then being able to present illustrated documentation generated from a test run that gives all parties an account of the features under development and tracks feature sign-off through automation of the acceptance criteria.

This goal can be achieved by Thucydides and Arquillian joining forces. Acceptance tests will not only be agile and illustrated, but fully automated. With a proof of concept in hand, we plan to advance this combination, including substituting Arquillian Drone to manage WebDriver, at the Devoxx 2012 Hackergarten.

Introducing the candidates

What is Thucydides?

Thucydides is a testing tool that encourages developers write more flexible and reusable end-to-end acceptance tests. In the style of Acceptance Test-Driven Development, Thucydides introduces a narrative for tests that describes the high-level requirements and automates the acceptance criteria using the tests. Developers then iterate using a test-driven approach to complete the requirements (i.e., stories), as depicted in the diagram below.

By analyzing the test metadata and test results, Thucydides generates illustrated documentation that describes how the application is used in the form of high-level requirements, acceptance criteria and screenshots, and records the progress of development.

What is Arquillian?

Arquillian is open source software that empowers you to test JVM-based applications more effectively. Created to defend the software galaxy from bugs, Arquillian brings your test to the runtime so you can focus on testing your application’s behavior rather than managing the runtime. Using Arquillian, you can develop a comprehensive suite of tests from the convenience of your IDE and run them in any IDE, build tool or continuous integration environment.

What is Arquillian Drone?

Arquillian Drone is an extension to Arquillian that manages the lifecycle of browsers for the purpose of controlling them from a test, thus simplifying automated functional / acceptance testing. Drone bootstraps the tooling necessary to send commands to the browser (e.g. Selenium Server, WebDriver, etc), spawns an instance of a browser, injects the browser API into the test class to allow tests to control that instance and, finally, properly disposes of the browser instance after the test is complete.

Integration benefits

Arquillian and Thucydides as yin and yang

While Thucydides handles automation of the browser—via the WebDriver library—it does not handle deploying the application being tested, nor does it manage the lifecycle of the container to which the application is deployed. In other words, it doesn’t automate everything. That’s where Arquillian steps in.

Thucydides brings the ATDD methodology and rich test reports to Arquillian, both new features to the Arquillian ecosystem. Arquillian complements Thucydides by managing the lifecycle of the container and deploying the application (as a whole or micro-deployment) to it. These services would otherwise need to be handled by the build when using Thucydides alone.

Beyond their combined core feature set, the integration brings all of the Arquillian extensions to Thucydides tests, opening the door to services such as loading seed data into the database, measuring performance and even managing browser automation. Speaking of managing browser automation…

More powerful browser automation with Drone

Bringing Arquillian Drone into the fold provides additional benefit by introducing a more powerful and flexible choice for controlling the browser in a Thucydides test, including simplified configuration, alternatives to WebDriver and extensions (e.g., Graphene). This secondary integration between Arquillian and Thucydides also unifies the developer experience with regard to how the browser is controlled across vanilla Arquillian Drone tests and Thucydides tests (embracing the concept that each tool should focus on doing one thing well).

Basic integration between Arquillian and Thucydides is a first step and getting Drone integrated is an optional (but valuable) bonus.

How this integration helps test writers

  • Arquillian tests become contract deliverables by leveraging Thucydides’ language for ATDD
  • Test segments of the webapp in isolation (using micro-deployments)
    • Accelerates acceptance testing because entire application doesn’t have to be built and deployed
  • Skip the build (e.g., Run As > XYZ Test in the IDE)
    • automatic container lifecycle management
    • deploy test archive defined in test class
    • inject application (initial) URL into test
  • Support for multiple target environments (e.g., local, dev, qa, staging)
  • Write Thucydides tests using other test runners, such as TestNG and Spock
  • Write Thucydides tests using any Arquillian-supported programming model (CDI, Spring, etc)
  • Rich reports summarizing test results generated by Thucydides, something Arquillian doesn’t currently provide
  • Use additional Arquillian extensions in Thucydides tests
  • Integrated configuration (arquillian.xml) for containers and browsers*
  • Use alternate browser automation libraries supported by Drone*
  • Use Graphene page fragments to reduce boilerplate code common in acceptance tests*

* requires Drone integration

Balancing responsibility

Thucydides’ strong suit is promoting ATDD through its programming model for writing acceptance tests as specifications by example and its reporting pipeline that summarizes test results as user stories. We believe Thucydides could move faster by focusing on tools and metrics needed to facilitate ATDD, allowing Arquillian to address the need of general purpose test extensions such as alternate test runners, data loading, browser automation, programming model integration, etc. In other words, Thucydides has more freedom to focus on its core competency, as stated on its website:

Organize and structure acceptance tests, associate tests with the user stories or features that they test and generate illustrated documentation describing how the application is used based on the stories described by the tests.

Hacking on the integration

We plan to hack on this idea during the Hackergarten at Devoxx 2012. Keep in mind there is a proof of concept we can reference as a starting point, described later in this section.

John Smart, the author of Thucydides, has offered to host the integration in the Thucydides code base, which is fantastic.

When and where are we hacking?

We are going to use the free Hackergarten day at Devoxx 2012 as an opportunity to put our heads together to make progress on this integration. Here are the details:

We’ll also be hacking throughout the week, either at the long white “hacking” tables on the second floor of the venue or after hours at a bar. Of course, anyone is welcome to hack on this idea at anytime from anywhere. This is open source!

Who will be there hacking?

Karel Piwko (Arquillian Drone Lead) and Vineet Reynolds (Arquillian Core and Thucydides integration) will be participating, time permitting, from afar. Feel free to reach out to them on IRC or the forums.

What we want to achieve

The following two tests are proposed milestones we want to achieve during the hack. They contrast what integration looks like without Drone to the integration with Drone. Thinking through these scenarios helps reveal integartion points that need to be exposed or refined.

The tests in this section apply to the Beer Advisor sample application.

Sample test without Drone integration

@RunWith(ThucydidesRunner.class) // or @RunWith(Arquillian.class)
@Story(BeerAdvisorFeatures.SearchingBeers.class)
public class SearchingBeersStory {

    // Thucydides members

    @Managed(uniqueSession = true)
    public WebDriver browser;

    @ManagedPages
    public Pages pages;

    @Steps
    public SearchingSteps searchingSteps;

    // Arquillian members

    @Deployment(testable = false)
    public static WebArchive createTestArchive() {
       return ShrinkWrap.create(WebArchive.class, "searching-beers-story.war")...;
    }

    @ArquillianResource
    URL deploymentUrl;

    // Tests

    @Before
    public void before_tests() {
        pages.setDefaultBaseUrl(deploymentUrl.toExternalForm());
    }

    @Test
    public void should_find_all_usa_beers() {
        searchingSteps.on_main_beer_advisor_page();
        searchingSteps.search_for("from usa");
        searchingSteps.should_contain_beers(new Beer("90 minute IPA"), new Beer("Mirror Pond"));
    }
}

The following steps outline the interplay between Arquillian and Thucydides while the test executes in this scenario.

  • Either Arquillian or Thucydides takes over test execution and activate both frameworks
  • Responding to the test suite start event, Arquillian and configures and starts (or connects to) the container
  • Arquillian deploys test archive(s) to container
  • Arquillian injects the application URL into the @ArquillianResource URL inject point of the test
  • Thucydides spawns a browser instance using WebDriver
  • Thucydides executes tests, sending browser commands to WebDriver
  • Thucydides takes screenshots using WebDriver as the browser is interacting with the web application
  • Thucydides destoys the browser instance using WebDriver
  • Arquillian undeploys the test archive
  • Arquillian stops the container
  • Thucydides generates reports from the high-level summarizes, screenshots and test results

Any Arquillian extensions that are loaded should also work as normal.

Sample test with Drone integration

@RunWith(ThucydidesRunner.class) // or @RunWith(Arquillian.class)
@Story(BeerAdvisorFeatures.SearchingBeers.class)
public class SearchingBeersStory {

    // Thucydides members

    @Steps
    public SearchingSteps searchingSteps;

    // Arquillian members

    @Deployment(testable = false)
    public static WebArchive createTestArchive() {
       return ShrinkWrap.create(WebArchive.class, "searching-beers-story.war")...;
    }

    @Drone // may get moved to the page objects
    public WebDriver browser;

    // Tests

    @Test
    public void should_find_all_usa_beers() {
        searchingSteps.on_main_beer_advisor_page();
        searchingSteps.search_for("from usa");
        searchingSteps.should_contain_beers(new Beer("90 minute IPA"), new Beer("Mirror Pond"));
    }
}

The following steps outline the interplay between Arquillian and Thucydides while the test executes in this scenario.

  • Either Arquillian or Thucydides takes over test execution and activate both frameworks
  • Arquillian configures and starts (or connects to) the container
  • Arquillian deploys test archive(s) to container
  • Arquillian injects the application URL into the @ArquillianResource URL injection point of the test
  • Arquillian Drone spawns a browser instance using the configured browser automation library (e.g., WebDriver)
  • Arquillian Drone sets the default base URL on the managed pages
  • Thucydides executes tests, sending browser commands to the browser automation library
  • Arquillian Drone takes screenshots as the browser is interacting with the web application
  • Arquillian Drone destoys the browser instance using the configured browser automation library
  • Arquillian undeploys the test archive
  • Arquillian stops the container
  • Thucydides generates reports from the high-level summarizes, screenshots and test results

Any Arquillian Drone extensions, such as Graphene, that are loaded should also work as normal.

Sample code to use for exploring the integration

Prior work

Vineet Reynolds has been experimenting with an integration between Thucydides and Arquillian Core. Vineet’s integration code uses a Thucydides StepListener implementation to weave the Arquillian lifecycle into the test. Tests are run using the Thucydides testrunner, while Arquillian manages the container lifecycle and performs the deployment of archives defined in the tests. The integration does not incorporate Arquillian Drone, opting to leave management of WebDriver up to Thucydides.

Aslak and Bartosz improved upon the integration and incorporated it into the Beer Advisor sample app for their JavaZone talk in September 2012. They introduced a JUnit Rule that activates the Arquillian services that run before and after each test method, such as test enrichment. A JUnit Rule is currently necessary due to insufficient hooks in Thucydides, but it gets the job done. Eventually we want to phase out the JUnit Rule because it exposes integration plumbing in the test.

Engineering challenges

Challenge #1: Unified test runner

Thucydides needs a startup API that isn’t coupled with JUnit so that Arquillian is able to perform the startup in an extension. At the moment there is a lot of setup code in the ThucydidesRunner to reproduce. The alternative is that Thucydides provides enough hooks in its StepEventBus for Arquillian to hook its own startup into the Thucydides lifecycle. In the integration prototype, a JUnit rule is used to activate Arquillian in a Thucydides test, but this is not the most elegant approach.

Ideally, the @RunWith(Arquillian.class) annotation should be enough for Arquillian to drive Thucydides if Arquillian detects Thucydides is also in use (e.g., the @Story annotation is present on the test class). This is the preferred approach since it simplifies the experience for the user across the test suite (a single @RunWith for all integration tests) and it may make the integration more compatible with extensions since Arquillian has a more sophisticated event bus.

Challenge #2: Drone integration

When Drone is integrated, the user has an option to use the browser automation library (directly or via the page object pattern) as with other Drone tests or use the page object support provided by Thucydides. Drone should be able to pass Thucydides the WebDriver instance so that Thucydides can operate its own page objects.

Ideally, the integration with Drone should cut down on as many redundant declarations in the class as possible to simplify test authoring. That means that the @Drone injection point is used to access the browser instance and and @ArquillianResource URL injection point is used to access the initial (base) url.

Karel Piwko mentioned that Drone needs a better SPI for improved integration with Arquillian Graphene, slated for 1.2.0.Final. He believes the Drone SPI will also help facilitate Thucydides integration. It also opens the door for Drone to be integrated into Thucydides on its own.

Happy hacking!

Resources

Introducing Arquillian Graphene Page Fragments

Tools like Arquillian Graphene, WebDriver, or just plain Selenium combined with concepts like Page Objects can help you automate your functional(integration, whatever…) web UI tests. We have already introduced some of the advances brought to you by Arquillian Graphene earlier. In this blog entry we will look a bit deeper into a new concept introduced in Arquillian Graphene 2.0.0.Alpha2; Page Fragments.

Consider the following example taken from the RichFaces component showcase. The page under test contain three Autocomplete widgets.

public class TestAutocompleteWidgets extends AbstractGrapheneTest {

    private JQueryLocator minCharInput = jq("input[type=text]:eq(0)");
    private JQueryLocator multipleSelectionInput = jq("input[type=text]:eq(1)");
    private JQueryLocator selectFirstFalseInput = jq("input[type=text]:eq(2)");
    private JQueryLocator selection = jq("div.rf-au-itm");

    @Test
    public void testFirstAutocomplete() {

        graphene.keyPress(minCharInput, 'a');

        assertFalse(graphene.isElementPresent(selection),
            "The suggestion list should not be visible, since there is only one char!");

        String keys = "ar";
        graphene.focus(minCharInput);
        selenium.type(minCharInput, keys);
        guardXhr(graphene).fireEvent(minCharInput, Event.KEYPRESS);

        assertTrue(graphene.isVisible(selection), 
            "The suggestion list should be visible, since there are two chars!");

        String actualArizona = graphene.getText(jq(selection.getRawLocator() + ":eq(0)"));
        assertEquals(actualArizona, "Arizona", "The provided suggestion should be Arizona!");

        String actualArkansas = graphene.getText(jq(selection.getRawLocator() + ":eq(1)"));
        assertEquals(actualArkansas, "Arkansas", "The provided suggestion should be Arkansas!");

    }

    @Test
    public void testSecondAutocomplete() {

        char key = 'a';
        selenium.focus(multipleSelectionInput);
        guardXhr(selenium).keyPress(multipleSelectionInput, key);

        assertTrue(selenium.isVisible(selection),
            "The suggestion list should be visible, since there is correct starting char!");

        selenium.keyPressNative(KeyEvent.VK_ENTER);

        key = ' ';
        selenium.keyPress(multipleSelectionInput, key);

        key = 'w';

        selenium.focus(multipleSelectionInput);
        guardXhr(selenium).keyPress(multipleSelectionInput, key);

        assertTrue(selenium.isVisible(selection),
            "The suggestion list should be visible, since there is correct starting char!");

        selenium.keyPressNative(KeyEvent.VK_ENTER);

        String actualContentOfInput = selenium.getValue(multipleSelectionInput);
        assertEquals(actualContentOfInput, "Alabama Washington", "The input should contain something else!");
    }

    @Test
    public void testThirdAutocomplete() {
        //similar autocomplete interactions as in the previous tests
    }
}

Now, ask yourself the following questions:

  • Do you find these types of tests less robust than for example unit tests for the persistence layer?
  • Do you think these tests still pass when the underlying HTML change?
  • Do you see repeating code in the these tests?

In my opinion you should have a clean answer to all of these questions. You are probably aware that tests should be loosely coupled with the underlying HTML structure of the application under test as it makes tests more robust and changes in the HTML structure of the page will not directly affect all tests.

Let’s apply the Page Objects pattern to split the HTML structure and the test logic. The Page Object will encapsulate the HTML structure so when the HTML change, only your Page Objects has to change.

  • But what about when I’m testing another application that use the same Autocomplete widget?
  • Should I copy the part of the Page Object that interact with the Autocomplete widget and paste it around in my code?

But as you’re already thinking: this would be a major don’t-repeat-yourself violation! Is there something we could do to improve this?

Yes, there is! Arquillian Graphene Page Fragments to the rescue!

Page Fragments, what are they?

  • Page Fragments are any repeating part of a page, any widget, web component, etc.
  • They encapsulate parts of the page into reusable test components across your whole test suite.
  • You can differentiate each fragment by its root element and reference other elements as children of that root.
  • They leverage Selenium WebDriver under the hood combined with all of the killer features of Graphene.
  • And they come with a set of utilities which simplify using them within tests and Page Objects.

How to define Page Fragments

public class AutocompleteFragment<T> {

    @Root
    WebElement root;

    @FindBy(css = "input[type='text']")
    WebElement inputToWrite;

    public static final String CLASS_NAME_SUGGESTION = "rf-au-itm";

    public List<Suggestion<T>> getAllSuggestions(SuggestionParser<T> parser) {
        List<Suggestion<T>> allSugg = new ArrayList<Suggestion<T>>();

        if (areSuggestionsAvailable()) {
            WebElement rightSuggList = getRightSuggestionList();
            List<WebElement> suggestions = rightSuggList.findElements(
                        By.className(CLASS_NAME_SUGGESTION));

            for (WebElement suggestion : suggestions) {
                allSugg.add(parser.parse(suggestion));
            }
        }

        return allSugg;
    }

    public List<Suggestion<T>> type(String value, SuggestionParser<T> parser) {
        List<Suggestion<T>> suggestions = new ArrayList<Suggestion<T>>();

        inputToWrite.sendKeys(value);
        try {
            waitForSuggestions();
        } catch (TimeoutException ex) {
            // no suggestions available
            return suggestions;
        }

        suggestions = getAllSuggestions(parser);
        return suggestions;
    }

    //other handy encapsulation of Autocomplete services
}

The example is just a snippet from the full implementation of the RichFaces Autocomplete component.

Notice the @Root annotation? The value of the root field is automatically injected by Graphene. The root field contain the root element as defined by the @FindBy annotation on the injection point of the Page Fragment in the Page Object or test. All @FindBy fields in the Page Fragment will use this root as a starting point.

The fragment implementation is pretty generic and therefore reusable in all tests in all applications that use the Autocomplete widget. A full implementation would encapsulate all the services this fragment provide, but it could for example also encapsulate browser specific interactions like submit or click actions. There are no boundaries!

Using Page Fragments and Page Objects together

Let’s rewrite the previous test to use our new Page Fragment together with our Page Object.

First we define a Page Object which contain the structure of the page under test.

public class TestPage {
    
    @FindBy(css = "div.rf-au:nth-of-type(1)")
    private AutocompleteFragment<String> autocomplete1;

    @FindBy(css = "div.rf-au:nth-of-type(2)")
    private AutocompleteFragment<String> autocomplete2;

    @FindBy(css = "div.rf-au:nth-of-type(3)")
    private AutocompleteFragment<String> autocomplete3;

    @FindBy(xpath = "//*[contains(@id,'sh1')]")
    private WebElement viewSourceLink;

    //all getters for the fields

    //other handy methods which you find useful when testing those three Autocomplete widgets
}

Declaring the Page Fragment in the Page Object is the preferred option, but you can also declare the Page Fragment directly in the test if desired. The only thing you need to do is to annotate the Page Fragment object with WebDriver’s @FindBy annotation to refer to the fragment’s root DOM element. That simple!

Graphene differentiates between Page Fragments and plain WebElements in the same Page Object so they can be declared side by side. All of the initialization is done automatically, so there is no need to initialize the Page Fragments or Page Objects in the @Before method of your test case.

In this last example we see how the autocomplete widgets’s Page Fragment is used in the test case.

public class TestWhichUsesPageFragments extend AbstractTest {

    @Page
    private TestPage testPage;

    @Test
    public void testFirstAutocomplete {
        AutocompleteFragment<String> autocomplete = testPage.getAutocomplete1();
        
        autocomplete.type("a");

        assertFalse(autocomplete.areSuggestionsAvailable(), 
            "The suggestion list should not be visible, since there is only one char!");

        String keys = "ar";
        autocomplete.type(keys);

        assertTrue(autocomplete.areSuggestionsAvailable(), 
            "The suggestion list should be visible, since there are two chars!");

        List<Suggestion<String>> expectedSuggestions = new ArrayList<Suggestion<String>>();
        expectedSuggestions.add(new Suggestion<String>("Arizona"));
        expectedSuggestions.add(new Suggestion<String>("Arkansas"));

        assertEquals(autocomplete.getAllSuggestions(new StringSuggestionParser()), expectedSuggestions, 
            "Suggestions are wrong!");
    }

    @Test
    public void testSecondAutocomplete() {
        AutocompleteFragment<String> autocomplete = testPage.getAutocomplete2();

        String key = "a";
        autocomplete.type(key);
        
        String errorMsg = "The suggestion list should be visible, since there was typed correct char ";
        assertTrue(autocomplete.areSuggestionsAvailable(), errorMsg + key);

        autocomplete.autocomplete(autocomplete.getFirstSuggestion());

        autocomplete.type(" ");

        key = "w"
        autocomplete.type(key);

        assertTrue(autocomplete.areSuggestionsAvailable(), errorMsg + key);

        autocomplete.autocomplete(autocomplete.getFirstSuggestion());        

        String actualContentOfInput = autocomplete.getInputValue();
        assertEquals(actualContentOfInput, "Alabama Washington", "The input should contain something else!");
    }

    @Test
    public void testThirdAutocomplete() {
        //similar autocomplete interactions as in the previous tests
    }
}

As your application grow, the only thing that needs to change is the root references of your Page Fragments. Last but not least you will be able to make your Page Fragment availabe to be used by other tests in other applications.

To try Page Fragments check out the Graphene 2.0.0.Alpha2 release. Getting start information can be found in the Reference Documentation.

Bug killing proposals accepted for 2012 Google Summer of Code!

The much anticipated announcement about which students were selected to participate in the 2012 Google Summer of Code program was published earlier today. In total, there are 1,212 students participating. We’d like to congratulate all the students accepted and wish you all best of luck this summer!

The JBoss Community is proud to be participating as an independent mentor organization for the first time this year. We were selected thanks to a strong showing of volunteer mentors and an overwhelming number of compelling and creative ideas. More than half of the ideas came from the Arquillian community ~:)

I’d like to extend a big thank you to everyone who came forward with ideas. Acceptances aside, these ideas are already helping shape the future of the various JBoss projects.

Accepted projects

The Arquillian project is excited to announce that we have 2 students participating this year!

Google granted the JBoss Community 8 student slots. From those 8 slots, Arquillian was allotted 2 slots—far less than the number of excellent proposals submitted. After much agonizing over the decision for the last week, the Arquillian mentors decided to award the slots to the following two student proposals:

Project #1

Title Extend Arquillian to support Spring testing (beans and MVC controllers)
Student Jakub Narloch
Mentor Marius Bogoevici
Summary Arquillian provides an extensible testing platform that can be used for testing any type of Java-based component. The initial focus for Arquillian was testing Java EE components, such as CDI beans, EJBs and JPA. However, Arquillian provides all the infrastructure and hooks necessary to make it an ideal testing platform for Spring applications. So the main of this project would be introducing suport for Spring testing.

Project #2

Title Automated Visual Verification
Student Jakub Dunia
Mentor Lukas Fryc
Summary Testing is important part of development. It is a procedure we need to perform many times, that is why there are many tools to automate it. There are cases where it is not that easy, like Visual Verification. Normally we need real person to check whether the web page looks good or not. The goal of this project is to write a tool that allows to easily review set of automatically collected screenshots generated by tests, and also improve existing comparision algorithms.

Jakub Narloch is already well on his way to bringing Spring testing support to Arquillian having implemented a prototype. You can read about the status of his prototype in the GSoC – Arquillian Spring integration forum thread.

Jakub Dunia, with his insight into problem solving, has already demonstrated he’ll be invaluable member of our community. The project he has chosen to support is extremely innovative, not only in scope of Arquillian, but in UI testing in general.

Congratulations Jakub * 2!

There’s an additional testing-related proposal, sponsored by the Errai team, that was also accepted:

Project #3

Title A Jenkins plugin to visualize Jacoco code coverage reports
Student Ognjen Bubalo
Mentor Jonathan Fuerth
Summary JaCoCo is a tool which generates code coverage reports based on Java unit tests. The project is about writing a Jenkins plugin to visualize JaCoCo code coverage reports.

Congratulations Ognjen!

Next steps

Jakub, Jakub and Ognjen, please contact your mentors immediately. Make a plan to communicate with your mentor regularly, at minimum, once each week. Since we’re big believers in openness, the best way to keep in touch is through a public channel such as the Arquillian development forum or the #arquillian channel on Freenode IRC.

We plan to publish status reports on these projects here at arquillian.org to allow the community to follow your progress and provide feedback. For those watching, stay tuned!

Promising proposals

Although we could only accept two proposals, there were many well-written proposals that truly deserved a slot (if only we had more to give). I’d like to thank the students for the time they spent preparing and submitting the proposals by highlighting them here. The rating shown under each proposal is the average rating (out of 5) given by the JBoss mentors who voted.

Unleash the Jester on integration tests by adding support for mutation testing in Arquillian

Student: Adam Sznajder
Rating: 5 / 5

Server-Side Performance Testing Framework reusing Arquillian Core

Student: Oliver Kišš
Rating: 4.8 / 5

RushEye Manager for Automated Visual Verification

Student: Udesh Liyanaarachchi
Rating: 4.5 / 5

Integrate Robotium into Arquillian Drone and Android extensions for complete automated application testing on Android

Student: Aleksey Shilin
Rating: 4.25 / 5

Provide an object-oriented format for defining test data for the Arquillian Persistence Extension

Student: Martin Skurla
Rating: 4 / 5

Automate JavaScript tests in an integration environment using Arquillian

Student: Chaitanya Nalla
Rating: 3.67 / 5

Provide an object-oriented format for defining test data for the Arquillian Persistence Extension

Student: Houssem
Rating: 3.67 / 5

Integrate Sahi into Arquillian Drone for automated browser testing

Student: Asanka Amarasinghe
Rating: 3.5 / 5

Despite the fact that these proposals were not accepted into GSoC, we really want to see them pursued. We view this program as an opportunity to interact with the next generation of the JBoss Community and to help them discover, or reinforce, their passion for open source. In fact, several students, including Chaitanya Nalla, have already expressed interest in contributing to Arquillian despite not being accepted to GSoC. That’s the spirit!

As Anil mentioned on the JBoss GSoC mailinglist, we’re exploring a diverse approach to enable students to continue their proposals, ranging from Red Hat summer internships to community-supported projects. Our plan is to closely track the GSoC schedule to keep the projects on track and to give you, the students, the experience the comes with completing a summer project (and likely increase your chance of being awarded a slot next year). Stay tuned for details.

What’s next?

Keep an eye on this blog for periodic progress reports about the GSoC student projects and any additional non-GSoC summer projects.

The first milestone is May 21st, when coding officially begins (trust me, these guys will be way ahead of that scheduled date). The mid-term evaluations happen mid July and the projects wrap up in mid August. See the official timeline for all the dates.

Even when GSoC ends, the community continues on! We hope summer students stay involved in the community long after the hacking days of summer.