Friday, October 30, 2009

Model-Based Testing For Web Applications With TestOptimal - (Part 1) Preparing The Model


Last week we introduced a 4 part HOWTO series on using TestOptimal for model-based testing of web applications. In today's Part 1,  we'll create a model using RTL's model generation tool, then convert that model for import into TestOptimal.  This will then allow us to generate automated test cases using TestOptimal's various test generations capabilities.

The target web application I selected to model for Part 1 is Google Maps. And as we've discussed in previous model-based testing articles (Model-Based Testing HOWTO Part 1 - Describing The Model), it's important to work with small models - ones that represent a logical set of functionality within a manageable set of states. To that end, I selected the Google maps search bar as our target to model.  Basically, we're going to model the search options functionality (Show/Remove search options) as well as the two buttons Search Maps and Google maps.  That may not seem like much to model, but from a testing point of view, as you take into account the various options for searching Google Maps, the model starts to expand quickly.

To build a model, you need to determine your states and transitions.  Once you identify those, you can begin to build your model, either manually or, as we do at RTL, using an automated tool.  So let's start by identifying the states we want to use for our model.  Based on the UI in the Google Maps search bar, and to keep things simple for this example, we'll only use the search options states.  Here's how I defined the sub-states:
1. SEARCH OPTIONS - Shown | Removed
2. OPTIONS SETTING - All results | Locations | Businesses | User-created content | Related maps | Mapped web pages | Real estate
The transitions I chose to include in this model are:
1. Click Show search options
2. Click Remove Search options
3. Select the search option "All results"
4. Select the search option "Locations"
5. Select the search option "Businesses"
6. Select the search option "User-created content"
7. Select the search option "Related maps"
8. Select the search option "Mapped web pages"
9. Select the search option "Real estate"
10. Click "Search Maps"
11. Click Google maps
Using this limited set of states and transitions resulted in a model (directed state graph) with 8 states and 71 paths! Click the graphic below to view in full size.
When importing a model like the one described above into TestOptimal, it needs to be in the GraphML format. So the next step is to convert our model into the proper format for TestOptimal.  I used TestOptimal's GraphML example listed here, which is based on a simple digraph found here.  Using these examples, I modified the output from our model generation tool so that it would produce a proper GraphML file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml>
<graph>
    <node id="n1">
    </node>
    <node id="n2">
    </node>
    <node id="n3">
    </node>
    <node id="n4">
    </node>
    <node id="n5">
    </node>
    <node id="n6">
    </node>
    <node id="n7">
    </node>
    <node id="n8">
    </node>
    <edge id="show_options" source="n1" target="n2">
    </edge>
    <edge id="remove_options" source="n2" target="n1">
    </edge>
    <edge id="select_all" source="n2" target="n2">
    </edge>
    <edge id="select_locations" source="n2" target="n3">
    </edge>
    <edge id="select_bus" source="n2" target="n4">
    </edge>
    <edge id="select_user" source="n2" target="n5">
    </edge>
    <edge id="select_related" source="n2" target="n6">
    </edge>
    <edge id="select_mapped" source="n2" target="n7">
    </edge>
    <edge id="select_real" source="n2" target="n8">
    </edge>
    <edge id="search_maps" source="n2" target="n2">
    </edge>
    <edge id="click_google_maps" source="n2" target="n1">
    </edge>
    <edge id="remove_options" source="n3" target="n1">
    </edge>
    <edge id="select_all" source="n3" target="n2">
    </edge>
    <edge id="select_locations" source="n3" target="n3">
    </edge>
    <edge id="select_bus" source="n3" target="n4">
    </edge>
    <edge id="select_user" source="n3" target="n5">
    </edge>
    <edge id="select_related" source="n3" target="n6">
    </edge>
    <edge id="select_mapped" source="n3" target="n7">
    </edge>
    <edge id="select_real" source="n3" target="n8">
    </edge>
    <edge id="search_maps" source="n3" target="n3">
    </edge>
    <edge id="click_google_maps" source="n3" target="n1">
    </edge>
    <edge id="remove_options" source="n4" target="n1">
    </edge>
    <edge id="select_all" source="n4" target="n2">
    </edge>
    <edge id="select_locations" source="n4" target="n3">
    </edge>
    <edge id="select_bus" source="n4" target="n4">
    </edge>
    <edge id="select_user" source="n4" target="n5">
    </edge>
    <edge id="select_related" source="n4" target="n6">
    </edge>
    <edge id="select_mapped" source="n4" target="n7">
    </edge>
    <edge id="select_real" source="n4" target="n8">
    </edge>
    <edge id="search_maps" source="n4" target="n4">
    </edge>
    <edge id="click_google_maps" source="n4" target="n1">
    </edge>
    <edge id="remove_options" source="n5" target="n1">
    </edge>
    <edge id="select_all" source="n5" target="n2">
    </edge>
    <edge id="select_locations" source="n5" target="n3">
    </edge>
    <edge id="select_bus" source="n5" target="n4">
    </edge>
    <edge id="select_user" source="n5" target="n5">
    </edge>
    <edge id="select_related" source="n5" target="n6">
    </edge>
    <edge id="select_mapped" source="n5" target="n7">
    </edge>
    <edge id="select_real" source="n5" target="n8">
    </edge>
    <edge id="search_maps" source="n5" target="n5">
    </edge>
    <edge id="click_google_maps" source="n5" target="n1">
    </edge>
    <edge id="remove_options" source="n6" target="n1">
    </edge>
    <edge id="select_all" source="n6" target="n2">
    </edge>
    <edge id="select_locations" source="n6" target="n3">
    </edge>
    <edge id="select_bus" source="n6" target="n4">
    </edge>
    <edge id="select_user" source="n6" target="n5">
    </edge>
    <edge id="select_related" source="n6" target="n6">
    </edge>
    <edge id="select_mapped" source="n6" target="n7">
    </edge>
    <edge id="select_real" source="n6" target="n8">
    </edge>
    <edge id="search_maps" source="n6" target="n6">
    </edge>
    <edge id="click_google_maps" source="n6" target="n1">
    </edge>
    <edge id="remove_options" source="n7" target="n1">
    </edge>
    <edge id="select_all" source="n7" target="n2">
    </edge>
    <edge id="select_locations" source="n7" target="n3">
    </edge>
    <edge id="select_bus" source="n7" target="n4">
    </edge>
    <edge id="select_user" source="n7" target="n5">
    </edge>
    <edge id="select_related" source="n7" target="n6">
    </edge>
    <edge id="select_mapped" source="n7" target="n7">
    </edge>
    <edge id="select_real" source="n7" target="n8">
    </edge>
    <edge id="search_maps" source="n7" target="n7">
    </edge>
    <edge id="click_google_maps" source="n7" target="n1">
    </edge>
    <edge id="remove_options" source="n8" target="n1">
    </edge>
    <edge id="select_all" source="n8" target="n2">
    </edge>
    <edge id="select_locations" source="n8" target="n3">
    </edge>
    <edge id="select_bus" source="n8" target="n4">
    </edge>
    <edge id="select_user" source="n8" target="n5">
    </edge>
    <edge id="select_related" source="n8" target="n6">
    </edge>
    <edge id="select_mapped" source="n8" target="n7">
    </edge>
    <edge id="select_real" source="n8" target="n8">
    </edge>
    <edge id="search_maps" source="n8" target="n8">
    </edge>
    <edge id="click_google_maps" source="n8" target="n1">
    </edge>
  </graph>
</graphml>
We're now ready to import our model into TestOptimal. In Part 2, we'll import this model and create a TestOptimal mScript.

0 comments. Add Comment.: