Functional Testing with Geb (webdriver with steroid) in Java Maven project

Background

My company has existing Java enterprise project.  One of the project is web application developed using old version of Spring, Struts, & iBatis.

My task is to upgrade some of libraries & dependencies, make it works with Microsoft SQL (previously it runs only on top of Oracle DB), and deploy it to Tomcat instead of Oracle Weblogic. Basically, there will be changes but the UI will remain the same. UI will be the last part to upgrade.

Ideally, I can just reuse existing functional testing codes to make sure my modification doesn’t break existing code.

Unfortunately, the previous developer didn’t write a single test code.  So, I’m planning to start covering all the codes with tests, be it unit test, integration, and/or functional tests.

Requirement

For this article, we’ll focus on writing functional testing code

My Solution

Here’s my test flow:

  • Clean up database first before running.
  • make sure application using the right configuration. test environment should be pointing to test database.
  • Prepare the dependencies. This app depends on another project which is web-service API for user authentication.
  • Run tomcat server
  • Deploy dependencies then deploy the target app.
  • Run functional testing
  • Clean up

I choose Geb as the testing tools. Geb is just like Selenium WebDriver with steroid. It is groovy so it’s more expressive

Well, I can opt to use headless testing like CasperJS (PhantomJS) but I want to show my business analyst this cool stuff that can open a browser on its own and do the testing automatically.

Setup Geb-spock in Maven

First, we need maven to include geb-spock & it’s dependencies. We better specify scope=test, for those that only used for testing.

And I define gmaven-plugin to compile all the groovy code for testing. Note that, we can use the better version of gmaven. Please check here for more detail.

Now we can start writing the functional test code. We can refer to Geb documentation.  It’s very good documentation and would be even easier to grasp if you know jQuery and (of course) groovy.

I recommend to use Page object pattern and modules. It promotes reusability. Moreover, it suits my project too, because the project uses Struts Tiles for layout templating which each template/page can easily be matched with the Geb page/ module.

Geb test runs on Firefox browser by default. Optionally we can define other browser drivers in GebConfig.groovy.

Using the above config, we can run using spesific browser by adding “-Dgeb.env=chrome” or  ”-Dgeb.env=ie”. Note that we need to download chromedriver.exe and IEDriverServer.exe and save it in our local. In my case, I put it under “drivers” folder.

For IE, I recommend to use the 32 bit version. I tried the 64 bits executable (because my dev machine is 64 bits) but then it runs very slow. I switched to 32 bits and it works fine.

And of course we still need to install the browsers before running the testing. Please install the browser version that is supported by your application. For example, if your web application’s javascript only works for IE9 or later. Don’t install IE version older than IE9.

Using Maven Failsafe in Maven Lifecyle: integration-test

For my current plan, I just want to run the geb functional testing only. The unit and integration testing will be run separately. So, I setup separate maven profile call “functional-test”. Since, I don’t want to run JUnit tests (unit/integration), I skip surefire.

Then I define the failsafe configuration to run integration-test and verify.

If you see the following config, it only runs those file ended with “Spec” , this assumes that all the functional testing named with that pattern. And for my current requirement, I need to pass in geb.build.baseUrl so that I don’t need to define it manually in every Geb test page I wrote.

 

Setup deployment using Maven

I used tomcat7-maven-plugin for remote deployment and initially I wanted to reuse it for my testing also. However, I found that cargo-maven2-plugin fits my requirement better. It’s more configurable. Anyway here’s the cargo configuration.

There are few things to note here:

  • I define cargo.servlet.port, because I want to use port other than 8080
  • I specify tomcat.mirror.url to let the cargo-maven plugin download. Please make sure your link is valid and you have reliable connection. Initially I was pointing it to tomcat download URL (which is in US). Then, sometimes there’s test error because of Tomcat downloading problem. So, now I switch to mirror URL that’s closer to my location and more reliable.
  • You see there’s deployable section. it’s where we specify any dependencies. In my case, the project depends on access-control WS API that’s deployed separately.
  • And I specify the pingURL to make sure the dependencies is deployed completely first before deploying the target app.

 

Next, just

if we have separate maven profile “integration-test” and want to test against other browser like “chrome”, then the command would be

Please ensure we call “verify” not “integration-test”. “verify” will ensure environment clean up after the integration-test.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">