Please, use the debugger

Before getting into the point of this post, by debug I mean going through each line of source code one after one or step by step. Reviewing the state of the memory at each step (and if you are really interested on how a debugger works under the hood, you can play with a tool I wrote and presented in the post a bit about programming language implementation).

Now, going to the point of this post, I have found, during my experience (which is far from large one) working with other developers, that few of them use the debugger as the first tool for troubleshooting and learning or understand legacy code. My experience is mostly based on Java/Eclipse. If you are familiar with Java/Eclipse, you will know that debugging an application is pretty simple. Indeed, Java allows you to debug remote JVMs. Yes, you are able to debug a JVM deployed in one continent from an Eclipse running on a workstation on another continent. Very nice.

Why developers don’t use a debugger? Maybe because the experience of most of them came from web scripting languages like the old ASP (MS Active Server Pages) or PHP, which does not provide a way to debug (or is pretty complex to do it). In addition, a couple of years ago, you did not have a tool for debugging Javascript code.

Mostly during my assignments in my undergraduate courses, I used Pascal, C and C++. And a debugger in those languages becomes pretty necessary. Especially if you are trying to find out an issue that may be caused by a dangling reference. So, I have learned those programming languages and learned how to troubleshoot applications using a debugger. On my working experience, I jumped into Java/Eclipse. Java and their Exception mechanisms generates very informative errors making the use of the debugger less necessary than in C (in addition, and among other things, pointers in Java are not managed by the developer which is far less error prone). However, the debugger is still the best tool for troubleshooting and for understanding legacy code.

I have received questions from other developers like: “…when I click on the button X, I get an error page with the suggestion to call the customer service”. My answer is always the same… “Please, use the debugger, and let me know what you find”. In most of the cases, they come after 10 minutes saying something like: “… forget it, it was something wrong I did…”.

Other developers try to understand what is going on looking at the code and trying to follow the flow of the program in their head. Which of course is not easy, and very error prone. Don’t waste your time, please, use the debugger.

If you find an issue, follow these steps:
1. Start the debugger and discover what is going on.
2. Write a unit test that reproduces the issue. You will get the red bar.
3. Fix the issue.
4. Run the unit test you wrote in the step 2, and see if you get the green bar.
5. If you get the green bar, move on.

If you need to deal with legacy code, the debugger is your tool to understand and get the knowledge that later will let you apply light/safe refactors to make the code testable.

Today, you should not choose a programming language to develop an application (even small ones! Unless you just need the Hello World!) which does not provide an IDE for debugging. In addition, your IDE should allow you to run/execute unit tests (and debug them if necessary).

Posted in Notes Tagged with:

AngularJS

I have been playing with AngularJS and my humble opinion is that it is really nice (powerful and easy to learn). As part of my playing, I have been written the UI of my example from my previous post. Lets start with a small introduction, and then I will describe my implementation and some thoughts that will help to clarify why I think AngularJS is nice.

AngularJS is a fairly new Javascript framework and toolkit for building rich web applications. It use HTML as the template view, and JSON data as the model. And the orchestration of these two is done on a controller. Providing a MVC architecture. It is also a framework because AngularJS controls how your application is constructed, using dependency injection. Your controllers gets injected with your own objects or with AngularJS services. It is a toolkit because, among other things, it gives you a library to make http requests (and the combo comes with a mock library to make fake http requests for testing).

But non of the above are the most important things from AngularJS. The most important thing is the data binding. AngularJS comes with a small expression language to transform an HTML page in a template and an expression can be bound to data in order to be presented. Let’s see the following (non fully completed) example. First, we write an HTML template which contains an AngularJS expression (note that the expression is surrounded by {{ … }}).

<div ng-controller="MyController">
  <span>This is the message: {{message}}</span>
</div>

Here, the AngularJS expression is the variable message. Note also that we are defining a controller called MyController to act over that piece of template.
Now, we need to write the controller to bind some data to the message variable. This is written inside an AngularJS controller, as below:

function MyController($scope) {
 $scope.message = 'Hello World!';
}

As you might notice, the controller is a plain old javascript function. As part of the function signature, I’m telling AngularJS to inject the $scope object. The $scope is an AngularJS object. Then, I’m creating a property message in the $scope and assigning a value to it. $scope will be valid from the starting element where the controller was defined, in this case the div element, until the end of the element. Lastly, when I load my template in a browser, I will see the following output:

This is the message: Hello World!

Whenever the message value change, the view is updated. Which is great as I don’t have to deal with DOM manipulation. In addition, makes a pretty clean separation between models and views. You might grab from a server side end point, some JSON data and bind it to the $scope, to be presented.

Let’s move now to my example. The source code can be found here. Under the folder:

/WebContent: you will find all the AngluarJS HTML templates. Where in the template.html file you will see the layout of the UI. This is using another AngularJS feature called ngView. All the other html files are children of template.html.

/WebContent/js/tntbooks-controllers.js: is where I have defined my controllers. Note that the content of the file starts with angular.module. Yes… AngularJS has the concept of modules (nice, right?). So, what is this?

angular.module('tnt', ['tntBooks']).config...

tnt is the name of this module (note that this name match with the one defined on the template.html as part of the ng-app directive).

['tntBooks']: in brackets all the modules which this module depends on. In this case, tntBooks is a module I have defined.

And with .config… I’m defining the URIs of my site.

/WebContent/js/tntbooks-services.js: is where I have defined my module. So, first I’m defining the module:

angular.module('tntBooks', ['ngResource']);

with name tntBooks and I need the AngularJS module called ngResource. Which is used to make the http request to the Tnt server side end points. This module expose, as plain old javascript functions, the responsibilities of the Tnt book store back end. The controller’s functions consume this module decouple them from URI’s, query string params and http methods.

/WebContent/test/spec/tntbooks-controller-test.js: is where I have all my tests. Yes… AngularJS is designed to be tested. It provides mocks for your http requests and due to the framework injects the dependencies on the controller’s functions, write test code is simple. The tests are written using jasmine.

You might have found out that AngularJS is client-side. This means, among other things, that the markup is added to the JSON data once on the client. So, your back-end sends only data across the wire, not data plus HTML markup, having smaller pieces of chunks to be transmitted. It also decouples your front-end chosen technology from your back-end chosen technology.

From my (very) short experience with AngularJS (1.0.1) I found one item that might be nice to have it supported. Currently, you can only specify one layout for your application, while you might need more than one. For example, one for your free access pages and another one for your authenticated pages.

This is all for now. There are others very nice AngularJS features which I have not described here, like directives. I think this one requires another post.
I hope you can get something good from these notes and source code, at least to start looking into AngularJS in more detail.

Posted in Frameworks Tagged with: ,

Object Oriented Programming in Practice

The subject is a bit broad… so, let me explain what is this about. I’m trying to show a sample implementation of a system, modeling it using the Object Oriented Paradigm. The system is an online book store. The source code can be found here and the implemented requirements(1) here. I developed this using the Java programming language, Hibernate for persistence, Spring and Spring MVC.

The main purpose of this is to come up with a good object oriented model, trying to avoid any impact on it with implementation stuff like persistence. The persistence is a cross-cutting concern that should not affect our design. I did not spend time on hibernate optimization, or Spring best practices, you will find a lot of places out there about these. Creating a good object oriented model is not an easy exercise and there, is where I spent most of the time while develop this. The implemented model is based on a mini-market metaphor.

With this, I tried to avoid a very common mistake where model objects are full of getters and setters, but not behaviour. The business logic is spread across methods outside the model, and the model objects are used as data structures (i.e.: struct in C or record in Pascal). This is clearly procedural programming. And this is more evident when you have to provide persistence to your system. This symptom is called anemic model. OOP is domain driven by definition, and the responsibilities are more important to identify objects (or the only way others may say) than data.

The implementation consist of the following modules:

tntbooks.model: Here are the objects that do the stuff, modeling the mini-market. All the business logic is here. This module does not depend on any other module within the system (any number of front ends can consume this module and any persistence mechanism can be plugged for this model, without changing any line of code). The model is tested using just JUnit (it was not needed to use any mock framework).

tntbooks.api: Here are the objects that belongs to the interface. that deals with the non object oriented world. Deals with URLs, requests and response.

tntbooks.persistence: Here are the objects that deals with persistence and hibernate (in this case). It implements two interfaces from the model module.

core: This is a module that can be reused in other domain. It was created after some refactor to make the Cart object more reusable for other domains, and not only for the tnt book store application.

Another interesting thing to highlight here is the implementation of an Hibernate interceptor that I had to do (you will find it on the tntbooks.persistence package). This was needed to inject transient object to persistent object. The persistent object Customer talks with the Cashier transient object. When I retrieve a Customer object from the database, this interceptor inject the Cashier collaborator transparently. This makes client code cleaner, due to I don’t have to duplicate code to inject the Cashier every time I get a Customer from the database.

I also tried to hide as much as possible all the methods that were only required by Hibernate: getters, setters and default constructors. That is why I used the private keyword for those, in order to just expose the business responsibilities of the objects that belongs to the tntbooks.model package.

If you want to give it a try, I develop this using Eclipse, Tomcat 6.0, Ivy for dependency management (with IvyDE for Eclipse), you will find all the dependencies in the ivy.xml file and Apache Derby.

I’m happy to hear other thoughts around how to model these requirements or any suggestion that you may have.

(1). The requirements are taken from (with some modifications I made) a TDD course I took in 10pines.

Posted in Object Oriented Programming Tagged with: , ,

Is everything an Object?

I have been reading two books, Object Thinking by David West and Clean Code by Robert C. Martin. In these two great books, the authors mention the phrase: “Everything is an object”. What caught my attention was that both express very different thoughts about this phrase. In his book, David West, afirm that everything is an object and is a prerequisite if you want to be part of the object thinking culture. On the other hand, in his book, Robert C. Martin, says: “Mature programmers know that the idea that everything is an object is a myth. Sometimes you really do want simple data structures with procedures operating on them”.

A bit of background of these two gentlemen. Robert C. Martin has written many books on software development, agile methodologies and object oriented design and has founded Object Mentor, which is a company for mentoring and consulting about object oriented technologies. David West, Ph.D., is a consultant, educator and trainer in object oriented technologies. He founded and directed the Object Lab at the University of St. Thomas and cofounded the original Object Technology User Group (However if you look into amazon.com, you will find that the guy who wrote the Object Thinking book is the basketball player… funny bug).

I thought, how can this be possible. Such a difference from two very experienced people on the same field.  You might be thinking the same I’m thinking… Object Thinking is a book with examples written in Smalltalk while Clean Code is a book with examples written in Java. In addition to this, based on some research on the web (and this might not be correct) seems that Robert C. Martin’s experience is based on C++/Java. This says a lot about their opinions.  Their minds are modeled differently due to diferent experiences in the past ? Is harder to see everything as an object if you came from Object Oriented languages like C++ ?

Well… just to mention a small thing, the way you create an object in C++ is using the keyword new while in Smalltalk you send the message new to a class (which is also an object… of course, everything is an object). Big difference.

After droping these notes here I continue reading David West’s book and I found this paragraph: “Claiming that there are clear criteria for determining whether software is object oriented is not the same as saying all software should be object oriented. Expecting a device driver implemented with 100 lines of assembly language to reflect full object thinking is probably pointless.”

Right ! It seems we finally have an agreement… and I’m convinced that they will agree if they discuss about this topic. However, even when they might agree on this, they (both) assign to the phrase “everything is an object” very different rate.

If I take both toughts, I would say that mature programmers knows when to apply object oriented thought and when not.

Posted in Object Oriented Programming Tagged with:

A bit about programming languages implementation

I have co-authored with a good friend (Edgard Lindner), a tool to help students understand Programming Languages operational semantics and implementation. This tool helps students to understand the effect of each sintactical construction (like a function call), on hardware resources (i.e. memory) .

The tool, which we called LaST (Language Study Tool) comes with four compilers for four different languages (based on Carlo Ghezzi’s book: Programming Language Concepts). Each compiler implements different features described below:

  • C2C is a compiler for a static language. The total amount of memory that a program will be used can be determined at compile time. Its main purpose is to help to learn the semantics of languages with pure static memory management.
  • C3C is a compiler for a stack based language (Algol based languages). It supports direct and indirect recursion. Its main purpose is to help to learn the semantics of stack based languages and recursion.
  • C4C is a compiler for a block structure language (like Pascal). Its supports the ability to nest subprograms. Its main purpose is to help to learn the semantics of a block structure languages.
  • C5C is a compiler that adds more dynamic behaviors to C4. Its main purpose is to help to learn heap allocations.

If you want to read more, if you want to try the tool yourself (it is an Applet), or if you want to extend the tool with, for instance, an object oriented language (would be nice to see dynamic dispatch in action), go to LaST.

Posted in Programming Languages Concepts Tagged with: ,

Software Architecture vs Software Design

I cannot find in the literature a precise distinction between Software Architecture and Software Design. Of course, I did not read all the books about software Architecture available in the market, but I read two great books, which I recommend (mentioned on footnotes below), but neither of them, IMHO, are clear when try to differentiate one from the other.

Fairbanks in his book says: “In practice, you will often find it difficult to differentiate architecture from detailed design”. And also adds: “You will not be alone, since experts generally agree about the broad strokes of architecture but disagree about the fine details, such as where architecture stops and detailed design begins”. Others say that architecture refers to high level details, and Design to low level details.

Where is the line that clearly separates what is Architecture and what is Design? Where Architecture stops and where Design begins? If you are presented with any kind of software diagram, is that Architecture or Design? Also, I have read about Modular Design and Modular Architecture, same concept with a different title, which one is the most appropriate? I will try to answer these questions.

The rule that I think we should use is: If the elements of a software diagram can be mapped one to one to a programming language syntactical construction, then is Design, if not is Architecture.

So, for example, if you are seeing a class diagram or a sequence diagram, you are able to map a class and their relationships to an Object Oriented Programming language using the Class syntactical construction. This is clearly Design. In addition, this might bring to the table that this discussion has a relation with the programming language you will use to implement a software system. If you use Java, the previous example applies, as Java is an Object Oriented Programming Language. If you come up with a diagram that shows packages and its dependencies, that is Design too. You can map the element (a package in this case) to a Java syntactical construction.

Now, suppose your Java application is divided in modules, and each module is a set of packages (represented as a jar file deployment unit), and you are presented with a diagram containing modules and its dependencies, then, that is Architecture. There isn’t a way in Java (at least not until Java 7) to map a module (a set of packages) to a syntactical construction. You might notice that this diagram represents a step higher in the level of abstraction of your software model. Any diagram above (coarse grained than) a package diagram, represents an Architectural view when developing in the Java programming language. On the other hand, if you are developing in Modula-2, then a module diagram represents a Design.

As a final more obvious example, a diagram that represents a layered style system, it is clearly Architecture. There is no way to map the element (layer) to a syntactical construction in any programming language (at least that I’m aware of).

The rule above is applicable to the activity too. If you are creating a Class diagram, then you are working on the Design of your software. And if you are creating a layered picture, then you are working on the Architecture of your software.

I’m happy with this distinction. My thoughts could look pretty obvious, but as I mentioned before, I did not find a precise description in other trusted sources. Welcome to hear your comments.

1) Software Architecture. Foundations. Theory and Practice.Taylor, Medvidovic and Dashofy.
2) Just Enough Software Architecture. A Risk-Driver Approach. George Fairbanks.

Posted in Design & Architecture, Notes Tagged with: ,

A Note on the Definition of Legacy Code

Many developers think that Legacy Code is an old code base that they inherit. A working application that other developer or other team wrote and you inherit it to maintain or enhance or to migrate to a newer platform. This is not entirely true, according to the definition of Michael Feathers in his book, Working Effectively with Legacy Code. And is this definition I like to take.

You may own a new working application, written from scratch, by you or by your team and even these, you might have been written legacy code. Did you write tests cases ? Well, if you didn’t you wrote legacy code. Someone on your team, right now, might be writing legacy code. The difference between legacy or non-legacy code is test or lack of test.

Usually, you fear to change an old code base due to you are not sure what might you be breaking… well, a code base can be very old, but if it comes with a good test harness, then you will be able to improve it even if you are new to that old code base.

And if you inherit an old code base, without test, read Michael Feathers’ book, it is full of very good advises.

Posted in Notes Tagged with:

Testable Code when Dealing with Third Party Singletons

There are some old frameworks out there that makes you deal with Singletons or static methods.

In addition, those frameworks may ask you to declare your objects with your business logic, in configuration files, in order the framework can manage them for you. These old frameworks have not yet entered in the world of dependency injection. They still makes you deal with Singletons and does not give you the ability to inject those Singletons from outside (constructor injection or setter injection), due to they manage your objects.

So, you don’t have other choice than hard code these Singleton dependencies into your business logic object (or upgrade the framework version which might involve some extra time). Hard coding Singletons or static calls on your business logic makes your object hard to unit test. In the next code snippet you will see an easy way to deal with this.

package ar.cpfw.thirdparty;

public class EvilThirdPartySingleton {

  private final static EvilThirdPartySingleton INSTANCE =
      new EvilThirdPartySingleton();

  private EvilThirdPartySingleton() {

  }

  public static EvilThirdPartySingleton getInstance() {
    return INSTANCE;
  }

  public String getValue(String aKey) {
    // some complex query to give you a value
    // from a configuration based on aKey
    return &quot;... someValue ... &quot;;
  }
}

package ar.cpfw.myobjects;

import ar.cpfw.thirdparty.EvilThirdPartySingleton;

/**
 * An object managed by a third party framework
 * */
public class MyUnderTestObject {

  public void nonUnitTestableMethod() {
    // some logic here...
    // . . .

    // then, a call to the evil Singleton
    String aValue =
        EvilThirdPartySingleton.getInstance().getValue(&quot;aKey&quot;);

    // do more something with aValue
    // ...
  }

  public void unitTestableMethod() {

    // some logic here...
    // . . .

    // then, a call to the evil Singleton
    String aValue = getValue(&quot;aKey&quot;);

    // do more logic with aValue
    // ...
  }

  protected String getValue(String aKey) {
    return EvilThirdPartySingleton.getInstance().getValue(
        &quot;aKey&quot;);
  }
}

import org.junit.Test;

public class MyUnderTestObjectTest {

  @Test
  public void my_logic() {

      //set up
      MyUnderTestObject myObject = new MyUnderTestObject() {
          @Override
          protected String getValue(String aKey) {
              // just return the friendly value
              // you need for your test
              return &quot;aFriendlyTestValue&quot;;
          }
      };

      //call the method under test
      myObject.unitTestableMethod();

      //verify ...

  }
}

The EvilThirdPartySingleton is the Singleton we have to deal with, that belongs to a third party framework. The MyUnderTestObject is the object that implements some functionality of my application and is managed by a third party framework. This object has two informative methods. The name of the methods explain the intention of each one. Basically, one has hard coded the reference to the Singleton and the other access to the Singleton through a protected method. Finally, in the test class, MyUnderTestObjectTest, we stub the Singleton call by overriding the protected method.

You may be thinking that we are stubbing the object under test, and you will be right. But I’m not stubbing the method under test.
Ideally, we should inject all the depedencies, as is described very well in this video by Misko Hevery. But sometimes it is not possible for the reasons described above.

Is this an evil alternative solution? looking forward to read your thoughts…

Posted in Testing Tagged with: , ,

What is the role of a Software Architect ?

If you are an Architect you may have discovered that you are not going to be asked to spend all your time on improving the design of an existing software product, nor to write code for an specific project.

As soon as you become an Architect, your meeting’s calendar will grow considerably. You will be asked to do the planning for several projects, to come up with estimates, and a very high level description of the software components that will need to be taken into account to accomplish the project. In addition, if you work for a big multinational company, you will be asked to analyse the software technologies of other companies that your company has the intention to acquire.
Then, you will present your work to the business using a slide based or a word based tool. This is fine. You have to have very good communication skills.

But, you cannot forget that an entire team of developers and technical leads are waiting for your guidance too. You cannot leave them behind, you must find the time to write code, to design, to configure a development environment, to write test cases, to explain why an algorithm is better than other, to help developers to fix bugs, to help developers to write maintainable code, to help developers to write unit testable code, to help developers to come up with good designs, to help developers to identify and propose solutions for performance bottlenecks, etc. As an Architect, you must be able to replace a developer if for any reason that is required. In order to be able to do this and in order to lead (by example) a development team, you cannot be entirely divorced from development activities.

Try to find the balance between business related activities vs development activities. If you find hard to have time for development activities, block your calendar once a week (half day) to sit down and write code. This does not mean that you want to ignore an important part of your role, this means that you want to be prepared one day to do development for an underestimated project to deliver it in time.

Stay with your development team, don’t isolate yourself in an office. Make feel them that you are there if they need any help or suggestion. Listen what they say while doing development. Write code yourself and commit code into the repository once in a while.

Oh yes… you will have more work to do with the same amount of hours you had before.

Posted in Design & Architecture, Notes Tagged with: , ,

An API for your Web Pages

Unlike to what you might think based on the title, the content of this article is about testing a Web Application.
Selenium 2 (a merge between Selenium 1 and WebDriver) has an elegant and intuitive API to play with Web UI elements. This makes testing Web Application much nicer than before. You will see an example later.

But what is really important when you start writing this kind of test for your Web Application, is to minimize the impact of a change on the UI. Since the UI is probably always a good candidate to be changed, if your test are all coupled against UI elements all over your test code, you will spend most of your time fixing broken tests.

Having said that, you need to decouple your tests from your UI elements. For this, you can write an API for your Web Pages. This API will expose a set of public methods that represents what a real final user can do on your Web Application and this methods will be consumed from your test cases.

In addition, use an object for each different page of your Web application. Having a one to one relation, every time you have a UI change on a page, you will know which object has to be changed to keep the API working. This is a pattern called Page Object. Remember to use good names for your objects.

Below you will see an example. The first two classes, SearchPage and SearchResultPage are part of the API of a well known Web Application. It is not the intention of this article to learn the Web Driver API, if you want further information you can visit the official Web Driver documentation. The last class, SearchTest is a JUnit test class that consumes the Web Application API.

package ar.cpfw.test.api;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;

public class SearchPage {

  private WebDriver driver;
  private WebElement q;
  private WebElement btnG;

  public static SearchPage build(WebDriver driver) {
    SearchPage page =
        PageFactory.initElements(driver, SearchPage.class);
    page.open();
    return page;
  }

  public SearchPage(WebDriver driver) {
    this.driver = driver;
  }

  public void open() {
    driver.get(&quot;http://www.google.com/&quot;);
  }

  public SearchResultPage doSearch(String text) {
    q.sendKeys(text);
    btnG.submit();
    return SearchResultPage.build(driver);
  }
}
package ar.cpfw.test.api;

import static org.openqa.selenium.By.xpath;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.google.common.base.Function;

public class SearchResultPage {

  private WebDriver driver;
  private WebElement rso;

  public static SearchResultPage build(WebDriver driver) {
    return PageFactory.initElements(driver, SearchResultPage.class);
  }

  public SearchResultPage(WebDriver driver) {
    this.driver = driver;
  }

  public boolean hasResults() {
    Function resultObject =
        new Function() {
          public String apply(WebDriver d) {
            return rso.getTagName();
          }
        };

    Wait wait = new WebDriverWait(driver, 5);
    return !&quot;&quot;.equals(wait.until(resultObject));
  }

  public String getFirstResultLinkText() {
    final String matchFirstResultLink =
        &quot;//ol[@id='rso']/li[1]/div/span/h3/a&quot;;

    Function firstResult =
        new Function() {
          public String apply(WebDriver d) {
            return d.findElement(xpath(matchFirstResultLink))
                .getText();
          }
        };

    Wait wait = new WebDriverWait(driver, 5);
    return wait.until(firstResult);
  }
}
package ar.cpfw.test.search;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

import ar.cpfw.test.api.SearchPage;
import ar.cpfw.test.api.SearchResultPage;

public class SearchTest {

  private WebDriver driver;

  @Before
  public void set_up() {
    driver = new FirefoxDriver();
  }

  @Test
  public void any_results() {
    SearchResultPage resultPage = runSearch();
    Assert.assertTrue(resultPage.hasResults());
  }

  @Test
  public void the_official_site_is_first() {
    SearchResultPage resultPage = runSearch();
    Assert.assertEquals(&quot;AC/DC | The Official AC/DC Site&quot;,
        resultPage.getFirstResultLinkText());
  }

  private SearchResultPage runSearch() {
    SearchPage searchPage = SearchPage.build(driver);
    return searchPage.doSearch(&quot;ac/dc&quot;);
  }

  @After
  public void tear_down() {
    driver.close();
  }
}

More comments before to close the article. I have created statics method factories for our Page Objects in order to hide the use of the Web Driver PageFactory Object. The PageFactory object will assign a proxy for each instance variable of type WebElement. This proxy will resolve the bind to the real UI element using By.name or By.id API. Also note that the build method of the SearchPage, calls the open method. This leaves the SearchPage object with the state needed to call any of its public methods.
Finally, if you use a Dependency Injection framework, you can nicely decouple your test cases from the implementation of the WebDriver (Firefox, IE, Chrome) and with little additional work, you will be able to run all your test cases for each of the browsers you would like to support.

Posted in Frameworks, Testing Tagged with: , ,