Model-based testing with GraphWalker and Selenium – part 1

In this post I’d like to make a start exploring the possibilities and drawbacks that model-based testing (MBT) can offer to test automation in general and Selenium WebDriver in particular. I’ll be using GraphWalker as my MBT tool of choice, mostly because it’s open source, doesn’t have a steep learning curve and it’s available as a Java library, which makes integration with any Selenium project as simple as downloading the necessary .jar files and adding them to your test project.

I’ll use the login procedure for the Parabank demo application I’ve used so often before as an example. First, we need to model the login procedure using standard edges and nodes (which are called vertexes in Graphwalker):
A model of the Parabank login procedure
I’ve used yEd to draw this model, mostly because this tool offers the option to export the model in .graphml format, which will come in very handy at a later stage. I’ll go into that in another post.

After the browser has been started and the Parabank homepage is displayed, we can perform either a successful or an unsuccessful login. Unsuccessful logins take us to an error page, which offers us the possibility to try again, again with both positive and negative results as a possibility. A successful login takes us to the Accounts Overview page, from where we can log out. The application offers us many more options once we have performed a successful login, but for now I’ll leave these out of scope.

Next, we are going to ‘draw’, i.e. implement this model in GraphWalker. This is pretty straightforward:

private Model createModel() {

	// Create a new, empty model
	Model model = new Model();

	// Create vertexes (nodes)
	Vertex v_Start = new Vertex().setName("v_Start");
	Vertex v_HomePage = new Vertex().setName("v_HomePage");
	Vertex v_ErrorPage = new Vertex().setName("v_ErrorPage");
	Vertex v_AccountsOverviewPage = new Vertex().setName("v_AccountsOverviewPage");

	// Create edges
	Edge e_StartBrowser = new Edge()
	Edge e_LoginFailed = new Edge()
	Edge e_LoginFailedAgain = new Edge()
	Edge e_LoginSucceeded = new Edge()
	Edge e_LoginSucceededAfterFailure = new Edge()
	Edge e_Logout = new Edge()

	// Add vertexes to the model

	// Add edges to the model

	return model;

Easy, right? The only downside is that this is quite a lot of work, especially when your models get pretty large. It also leaves (a lot of) room for improvement when it comes to maintainability. We’ll get to that in a later post as well.

Theoretically, we could have GraphWalker go through this model and explore all vertexes and edges, but in order to do meaningful work we need to link them to concrete action steps performed on Parabank. A good and clean way to do this is to consider the following:

  • Edges are like state transitions in your model, so this is where the action (typing in text boxes, clicking on links, etc.) ends up.
  • Vertexes represent states in your model, so this is where the verifications (checks) need to be performed.

For example, this is the implementation of the e_StartBrowser edge:

WebDriver driver = null;

public void e_StartBrowser() {

	driver = new FirefoxDriver();
	driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);


By giving the method the same name as the actual edge, GraphWalker knows that it needs to execute this code snippet every time the e_StartBrowser node is encountered when running through the model. We can do the same for the vertexes, for example for the v_HomePage vertex representing the page we land on when we perform a successful login:

public void v_HomePage() {

	Assert.assertEquals(driver.getTitle(),"ParaBank | Welcome | Online Banking");

For simplicity, we’ll just do a check on the page title, but you’re free to add any type of check you wish, of course.

Finally, we need to tell GraphWalker to load and run the model. I prefer using TestNG for this:

public void fullCoverageTest() {

	// Create an instance of our model
	Model model = createModel();
	// Build the model (make it immutable) and give it to the execution context
	// Tell GraphWalker to run the model in a random fashion,
	// until every vertex is visited at least once.
	// This is called the stop condition.
	this.setPathGenerator(new RandomPath(new VertexCoverage(100)));
	// Get the starting vertex (v_Start)
	//Create the machine that will control the execution
	Machine machine = new SimpleMachine(this);
	// As long as the stop condition of the path generator is not fulfilled, hasNext will return true.
	while (machine.hasNextStep()) {
		//Execute the next step of the model.

The most important part in this test is the stop condition, which basically tells GraphWalker how to run the test and when to stop. In this example, I want to run the model and its corresponding Selenium actions randomly (within the restrictions implied by the model, of course) until every vertex has been hit at least once (100% vertex coverage). GraphWalker offers a lot of other stop conditions, such as running the model until:

  • Every edge has been hit at least once
  • A predefined vertex is hit
  • A predefined time period has passed (this is great for reliability tests)

A complete list of options for stop conditions can be found here in the GraphWalker documentation.

When we run this test, we can see in the console output that GraphWalker walks through our model randomly until the stop condition has been satisfied:
GraphWalker console outputAs usual when using TestNG, a nice little report has been created that tells us everything ran fine:
GraphWalker TestNG report - passNote that unlike what I did in the example above, it’s probably a good idea to use soft asserts when you’re using TestNG together with GraphWalker. Otherwise, TestNG and therefore GraphWalker will stop executing at the first check that fails. Unless that’s exactly what you want, of course.

In this post we’ve seen a very basic introduction into the possibilities of MBT using GraphWalker and how it can be applied to Selenium tests. In upcoming tests I’ll dive deeper into the possibilities GraphWalker provides, how it can be used to generate executable models from .graphml models, and how to make the most of the tool while keeping your tests clean and maintainable.

The Eclipse project containing the code I’ve used in this post can be downloaded here.

19 thoughts on “Model-based testing with GraphWalker and Selenium – part 1

  1. Pingback: Testing Bits – 10/18/15 – 10/24/15 | Testing Curator Blog

  2. Just one note… to get green test result you should have “Error”, istead of “Fault”… ;o)

    public void v_ErrorPage() {

    Assert.assertEquals(driver.getTitle(), “ParaBank | Error”);

    • Hi Roman,

      you’re absolutely correct! In my defense, I changed that on purpose to see how GraphWalker reacted to a failed assertion, but I forgot to change it back to the correct value before uploading the code.

      I’ll fix that ASAP. Thanks for mentioning it!

      EDIT: Done!

    • Hey Patrick,

      I am planning to cover that in a follow up post, unfortunately I haven’t had the time yet to prepare and write one. In the meantime Google might be your best friend..

      I agree that the ability to parse graphml files rather than rewriting them in code would be a massive improvement. I know GraphWalker supports it, I just haven’t had the opportunity to look into it yet..

      • Hi Bas,

        Really a good post. I was wondering if its possible to use above technique for API testing. If it is possible, could you please give some details on how to achieve MBT on API testing.


        • Hi Kumar, if you can model the behavior of your API / your application as a sequence of API calls then surely it’s possible. I like the idea so I’m going to use in a future post. Might take a couple of weeks though..

          • Come to think of it, I’m not sure whether this would make a good example. Most web services are stateless and using MBT or GraphWalker in particular is especially useful for stateful applications. It can be done, but I don’t think it demonstrates the full power of MBT / GraphWalker. My next post will therefore probably be web application-oriented, just as this one.

            If you want to apply GraphWalker on web services / APIs, just replace the Selenium code by code you use to call your API (vertexes) and assert the responses (nodes), for example using REST Assured.

          • Thanks for reply Bas.


            get(“/lotto”).then().assertThat().body(“lotto.lottoId”, equalTo(5));

            For the above Rest Assured code, could you please give the content of Edge and Vertex.

          • That’s what I tried to explain: such an API call doesn’t directly translate to an edge and a vertex in GraphWalker. A transition between vertexes by means of an edge implies a state transition. An API call is simply a query for data (in this case). There’s no change in state.

    • Hi Patric,

      try this:

      public final static Path MODEL_PATH = Paths.get(“my-Graph.graphml”);

      public void runFunctionalTestAllEdges() {
      new TestBuilder().addModel(MODEL_PATH, new WizardLoginTest().setPathGenerator(new RandomPath(new EdgeCoverage(100)))).execute();

      public void runFunctionalTestAllVertexes() {
      new TestBuilder().addModel(MODEL_PATH, new WizardLoginTest().setPathGenerator(new RandomPath(new VertexCoverage(100)))).execute();

      public void runFunctionalTestAll60Seconds() {
      new TestBuilder().addModel(MODEL_PATH, new WizardLoginTest().setPathGenerator(new RandomPath(new TimeDuration(60, TimeUnit.SECONDS)))).execute();

      • Hi Roman,
        thanks for your reply.
        But it doesn`t work.
        Could you please share an example for the “WizardLoginTest”-Class?



Leave a Reply

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