Monday, July 12, 2010

Advanced Web Application Test Development Using Selenium IDE

In my last post I covered creating a basic Selenium test using the Selenium IDE and exporting tests to JUnit for execution through Selenium RC. Now, we're going to cover the more advanced aspects of using Selenium IDE to create advanced test cases for your we application.

The easiest way to generate tests, is too perform the actions in your browser and allow the Selenium IDE to populate automatically. In all honesty, this will handle 99% of the features you want to test. But there are times when the browser integrated features aren't enough to test everything and you have to get your hands a little dirty.

Assert the Title Attribute of an Image

For our first example, we're going to verify the title attribute of an image. One of my favorite sites is XKCD and the comics always have a funny image title that is part of the comic. The first thing we're going to do is browse over to http://www.xkcd.com/756/. If you hold the mouse over the image, you will see the title text appear, which says: "News networks giving a greater voice to viewers because the social web is so popular are like a chef on the Titanic who, seeing the looming iceberg and fleeing customers, figures ice is the future and starts making snow cones."

Let's fire up the Selenium IDE by opening Tools > Selenium IDE. Set the base URL to http://www.xkcd.com. Now if you'll right click on the comic, then go to Show all available commands > assertElementPresent //img[@alt='Public Opinion'].

The assertElementPresent command allows you to specify an element exists using locators. We're going to cover locators next. Switch over to the Selenium IDE and select the assertElementCommand we just created. In the target text box, change the @alt='Public Opinion' value to @title=News networks giving a greater voice to viewers because the social web is so popular are like a chef on the Titanic who, seeing the looming iceberg and fleeing customers, figures ice is the future and starts making snow cones.

This means that we are going to locate the image based on the title attribute rather than the alt attribute. Now your test should look like my test in the screenshot. Run the test now by clicking on the green triangle withe three bars and the test should pass. We now have a test that ensures the title text for this particular web comic is what we think it should be.

Selenium Element Locators

Element locators within Selenium allow you to specify which element on a page is the target of a given command. There are three default locators for Selenium that don't require you to specify what type of locator you are using:
  1. DOM
    Locators starting with "document" will use the DOM Locator.

  2. XPATH
    Locators that start with "//" will use the XPATH locator to find a given element.

  3. Identifier
    Locators that start with anything other than "document", "//", or a valid locator type, will default to using the identifier strategy. When using the identifier strategy, the first element with a matching id attribute will be selected. If no matching id is found, then Selenium will use the first element with a matching name attribute.

Saturday, July 3, 2010

Web Application Testing with Selenium and JUnit

Selenium is a suite of tools to automate web app testing. Selenium is very flexible and integrates with many testing frameworks and languages as well as running within many operating systems and browsers. The three major parts that make up Selenium are:
  1. Selenium IDE
    Integrates into Firefox as an add-on to allow you to generate tests that can then be exported out to other formats for automated testing setups. This post will cover using the Selenium IDE to generate tests to be used with JUnit.

  2. Selenium Remote Control
    Runs the test generated by the IDE on various platforms and browsers allowing for robust automated testing of your web application. Selenium RC will be lightly covered in this post, but will be covered in more depth in a later post.

  3. Selenium Grid
    Builds upon Selenium RC and allows you to distribute your tests across multiple servers for parallel execution. Selenium Grid will be covered in a later post.
Creating your First Test with Selenium IDE

The first thing you'll need to do is install the Selenium IDE add on into Firefox by going to http://seleniumhq.org/download/. Once the Selenium IDE has been installed, you'll have to restart Firefox and you'll be ready to begin creating tests.

Start Firefox and click on Tools > Selenium IDE to open the IDE so you can begin creating a new test. Click the record button inside of the Selenium IDE dialog, the red circle button, then you can begin performing the actions that will make up your test. This process is pretty much just browsing to the application that will be testing and being specifying what should be tested.

For our first example, we're going to use the Selenium IDE to build a basic test that asserts the title is correctly set for http://javaconfessions.com. We want to verify not only that the title is set correctly in the head of the document, but we want to make sure the title is showing properly at the top of the page.

Ensure that we have clicked the record button, the red circle button, then in the browser go to http://javaconfessions.com. Once the page loads, right click anywhere on the page and hover your mouse over the last item in the context menu which will be "Show all available commands."

Once the flyout menu appears, click the "assertTitle Confessions of a Java Programmer" menu item. You will see this command populate into the Selenium IDE. This command will assert that the title inside the head of the main HTML page reads "Confessions of a Java Programmer."

Now that we've tested to ensure the title in the head tag is correct, we're going assert the title also shows up on the top of the page. This time, select the header text at the top of the page that reads "Confessions of a Java Programmer." Right click and once again hover over the "Show all available commands" menu item, then click the "assertText //div[@id='header-inner']/div[1]/h1 Confessions of a Java Programmer" menu item. This command will assert that the top of the page reads "Confessions of a Java Programmer."

Running the Test in the Selenium IDE

Now that we've gone through the process to setup a basic test, we're going to run it in the Selenium IDE in order to show that it works the way we think it should. To execute the test in the Selenium IDE, click the button that has the green triangle with three bars to execute the entire test.

The browser will go through all of the actions defined in the test and it will pass. If there is a failure, you will see a red message in the output at the bottom and then you know you need to rework your test to ensure you are getting accurate results.

Exporting the Test for JUnit

Now that we have built the basic test in the Selenium IDE, we can export our test for use in a JUnit Test Case. In the Selenium IDE go to File > Export Test Case As > Java ( JUnit ) - Selenium RC. Name the file JavaConfessionsTestCase.java.

Open up the newly generated test file and change the package for the class if you desire. By default the test class will be created with a package of com.example.tests. After you are done editing the file close it and copy it into the appropriate package in your project's testing directory.

Running the Test

Now we need to download Selenium RC from http://seleniumhq.org/download/. Unzip the newly downloaded file and copy out the file named selenium-java-client-driver.jar out of the selenium-java-client-driver-1.0.1 directory to your testing environment's class path.

The next step is to copy out the selenium-server.jar out of the selenium-server-1.0.3 directory to a permanent spot on your testing environment server. This file can be put anywhere, as it will be ran as a service in order to allow Selenium testing from JUnit classes.

Before executing our JUnit test we need to start the Selenium RC server. Open a command prompt and change into the directory where you stored the selenium-server.jar file. Then start the Selenium RC server by typing java -jar selenium-server.jar.

With the Selenium RC server now running , you can execute your Selenium JUnit test just like you normally run JUnit tests. In the screenshot, you can see the results from executing the Selenium test in IntelliJ IDEA. In the next post, I will demonstrate how to create more complex Selenium tests.

Thursday, February 11, 2010

Add Rows to Groovy's Swing Builder DefaultTableModel

If you've had an opportunity to mess around with Groovy's Swing Builder, you may have noticed that the table model used for tables is not the standard javax.swing.table.DefaultTableModel, but is an instance of groovy.model.DefaultTableModel. Java's implementation of the DefaultTableModel has an addRow() method that allows the addition of new rows, however Groovy's implementation does not.

This left me, and many others, wondering how to go about adding a new row to Groovy's DefaultTableModel object. After looking over the Groovy API, I have come up with the solution below. Enjoy:

import groovy.swing.SwingBuilder

def swing = new SwingBuilder()
def tableData = [ [firstName: "Bob", lastName: "Stevens"], [firstName: "Lucy", lastName: "House"] ]
def myTable = swing.table(){
tableModel( list:tableData ){
propertyColumn( header:"First Name", propertyName:"firstName" )
propertyColumn( header:"Last Name", propertyName:"lastName" )
}
}

// Let's add a new row to the table
def rows = myTable.getModel().getRowsModel().getValue()
rows.add( [ firstName: "Reese", lastName: "Smith" ] )
myTable.getModel().getRowsModel().setValue( rows )
myTable.getModel().fireTableDataChanged()

This example will add a new row to the end of the table and then redraw the JTable so the new row will show up. The function getRowsModel() returns the ValueModel which allows you to manipulate the data within the table. The value set within the ValueModel will be a list of the rows in the table and you can add rows by calling add( rowData ) or specify an index with add( index, rowData ) to allow you to insert data at a specific spot in the list.

Tuesday, February 2, 2010

Fix Slow Charter DNS Lookups by Using OpenDNS

I have been having issues with DNS resolution being extremely slow with Charter Communications Internet on my Macbook. I tried disabling IP v6 in Firefox and that seemed to work for a little while, but eventually my DNS lookups slowed down again. Frustrated, I began looking for ways to not use Charter's DNS servers.

I found out about OpenDNS after googling a little bit. I opened up a free account and switched my router over to their DNS servers. Low and behold, my Internet speed is blazing again on my Macbook. So, if you're having issues with slow DNS lookups on OSX and Charter is your ISP, give OpenDNS a try.

Thursday, January 21, 2010

SmartSVN Blows the other Subversion Clients out of the Water

I was a developer in a Window's environment for many years and have had a few years of experience with TortoiseSVN. Once I switched to Ubuntu a while back, I strugged to find a suitable replacement for TortoiseSVN in Linux. I tried a few different solutions including RapidSVN and KDESVN. Neither of those even came close to the ease of use and stability of TortoiseSVN.

A friend who develops on OS X had mentioned that he uses SmartSVN and that it is available for Linux also. As a matter of fact, you can run SmartSVN under Windows, OS X, Linux, and even OS/2 Warp.

So I downloaded it and ran through the 30 day professional version trial. At the end of the trial I immediately paid the fee for the professional version. I know what you're all thinking. This sucker paid $79.00 for a Subversion client when there are a billion free ones available. I gladly paid the fee and say with great confidence that there is nothing out there that even comes close to what SmartSVN can do for you.

Even if I was still developing in a Windows environment and could still use TortoiseSVN, I would have paid the fee to use SmartSVN. TortoiseSVN does not even come close to the level of productivity I can accomplish under SmartSVN.

Merge Single Revisions Across Branches

I work in an environment with many different branches. At any given time I have to work on the trunk and two or three branches. If there is a change that needs to go into the trunk and possibly one or two branches, it is a time consuming process to get the changes everywhere they need to be.

Assuming I am using TortoiseSVN, I'll have to commit the changes to the trunk. Then using a diff tool, merge the changes I made from the trunk to the branch. It is all very manual and error prone. TortoiseSVN does offer a merging tool, but this is only to merge the entire branch, not single revisions or files but it is uselessly complicated in my opinion. You can read more about TortoiseSVN's merging functionality here.
Using SmartSVN, this same task is so simple. After you have commited your trunk changes, switch over to the branch where you wish to merge these changes to. Right click on your trunk commit in the transactions pane and click merge. This will merge the changes from that revision into your working copy of the branch. After that, simply commit to the branch.
If you only want to merge one or two files from a given commit, you can do that too. The amount of time this saves is huge when you don't have to manually merge these changes across branches.

Conclusion

The capability to merge single revisions across branches is huge, but there are still many other features that separate SmartSVN from the pack. For more detailed information on SmartSVN, check out their site at: http://www.syntevo.com/smartsvn/index.html

Also, just for the record, I'm not affiliated with Syntevo or receiving any compensation for this post.

Test your Java Regular Expressions ( REGEX ) Online

If you've ever worked with regular expressions using the java.util.regex package in Java, you know it can be a slow process to thoroughly test your regular expression. I recently found a website that allows you to test your regex using the java.util.regex package and actually provides detailed feedback.
Using fileformat.com's Regular Expression Test Page, you can run test data through Java's regex engine and see the Matcher's output methods such as matches(), replaceFirst(), replaceAll(), lookingAt(), and find(). It will also show you the groups your regular expression creates.

The next time you are writing some fancy regular expressions for use in the java.util.regex package, make sure you use this handy tool for testing your regex in Java.

Wednesday, January 13, 2010

Fixing Slow Internet Browsing when using Firefox on Mac OSX

If you're using Firefox on your Mac and having issues with slow web browsing, it may be due to the fact that Firefox is attempting to do IPV6 DNS lookups. The main symptom for this problem is that every time you attempt to browse to a new page, the status in the bottom left corner says "Locating whatever website..." and it takes a few seconds before the page starts to load. However, once you get to the page, browsing speeds up.

The problem is that Firefox attempts to resolve IPV6 addresses first then attempts to resolve IPV4 addresses by default. If your ISP's DNS server does not support IPV6, this will cause a delay. Fortunately, the good people at Mozilla gave us a way to change this setting.

To fix this, you can disable IPV6 in Firefox by following the steps below:
  1. Open Firefox, type about:config in the address bar and hit enter.
  2. You'll receive a warning, click the button that says "I'll be careful, I promise!"
  3. Find the preference named network.dns.disableIPV6 and double click it to set it to true.
  4. Restart Firefox
Now your browsing should speed up because Firefox will now only attempt to resolve addresses in IPV6 format. For more information about this issue check out http://kb.mozillazine.org/Network.dns.disableIPv6.

© 2010 Confessions of a Java Programmer, All Rights Reserved