Friday, February 20, 2009

Fast exploratory tests with IFrames

by Håvard Rast Blok

While working with a search quality development team, I was asked to collect information from their result pages across all the supported languages. The aim was to quickly get an overview, and then manually look through them for irregularities. One option would have been to grab the pages using tools like Selenium or WebDriver. However, this would have been complex and expensive. Instead, I opted for a much simpler solution: Display each language variation in a separate IFrame within the same HTML page.



An example of how this looks, can be seen here, where the Google Search page is shown in 43 different languages. There are also some links for other Google sites, or you can type in your own link, and the query attribute for language, "hl=", will be appended at the end.



(Warning: Do not try this with YouTube, as 43 Flash windows on the same pages will crash your browser. Also, Firefox 2 is known to be slow, while Firefox 3 works fine.)



The JavaScript Code



Creating the IFrames is easy using JavaScript, as can be seen in the example below. I assume that the array of languages to iterate over is retrieved by the function getLanguages(). Then a simple loop uses document.write(...) to dynamically add the IFrames. It is worth mentioning that this method seemed to be the best way of dynamically creating them; using the document.createElement(...) resulted in some complex race condition issues when adding the IFrames and their content at the same time.



var languages = getLanguages();
for (var lang, i = 0; lang = languages[i]; i++) {
  document.write('<hr><a name="' + lang + '"/>' +
                 '<h2>' + lang + '</h2><center>' +
                 '<iframe src="' + url + lang +
                 '" width="' + queryMap['width'] +
                 '" height="' + queryMap['height'] +
                 '"></iframe>' +
                 </center><br/><br/>');
}



The rest of the source code, can be seen in this example. Nothing else is needed to get the overview.



Conclusion


The example in this article shows that a very simple and inexpensive solution can be useful for exploratory testing of web pages; especially when quickly looking over the same pages in multiple languages. The small amount of code required, makes it easy to customize for any project or page, and the fact that the requests are done dynamically, gives a view which is always up to date.



Of course, this type of overview lends itself best to very simple stateless pages, which do not require complex navigation. It would for example be more difficult to get the same list of IFrames for Gmail, or other complex applications. Also, as the IFrames are loaded dynamically, no history is kept, so tracking when a potential bug was introduced in the page under test might prove more tedious.



Furthermore, it should be noted that the overview only simplifies a manual process of looking at the pages. In some situations, this might be very beneficial, and enough for the developer, while in other projects more automated tests might be designed. E.g., it could be difficult to automate tests for aesthetic issues, but easy to spot them manually, while it may prove more beneficial to automate checks for English terms in other languages.



Finally, a word on the issue of translations and language skills. The overview in this example, quickly highlights issues like incorrect line wrapping, missing strings, etc. in all variations of the page. Also, it was easy to spot strings not already translated in some of the languages, like Japanese, and in fact I reported a bug against the Search front page for this. However, for other issues, more language specific skills are necessary to spot and file bugs: E.g. should the Arabic page show Eastern or Western Arabic numerals? And have the Danes picked the English term for "Blogs", while the Norwegians and Swedish prefer a localized term? I don't know.

Thursday, February 19, 2009

TotT: Partial Mocks using Forwarding Objects

A Partial Mock is a mock that uses some behavior from a real object and some from a mock object. It is useful when you need bits of both. One way to implement this is often a Forwarding Object (or wrapper) which forwards calls to a delegate.

For example, when writing an Olympic swimming event for ducks, you could create a simple forwarding object to be used by multiple tests:

interface Duck {
Point getLocation();
void quack();
void swimTo(Point p);
}

class ForwardingDuck implements Duck {
private final Duck d;
ForwardingDuck(Duck delegate) {
this.d = delegate;
}
public Point getLocation() {
return d.getLocation();
}
public void quack() {
d.quack();
}
public void swimTo(Point p) {
d.swimTo(p);
}
}



And then create a test that uses all of the real OlympicDuck class's behavior except quacking.

public void testDuckCrossesPoolAndQuacks() {
final Duck mock = EasyMock.createStrictMock(Duck.class);
mock.swimTo(FAR_SIDE);
mock.quack(); // quack after the race
EasyMock.replay(mock);
Duck duck = OlympicDuck.createInstance();
Duck partialDuck = new ForwardingDuck(duck) {
@Override public void quack() {
mock.quack();
}
@Override public void swimTo(Point p) {
mock.swimTo(p);
super.swimTo(p);
}
// no need to @Override “Point getLocation()”
}

OlympicSwimmingEvent.createEventForDucks()
.withDistance(ONE_LENGTH)
.sponsoredBy(QUACKERS_CRACKERS)
.addParticipant(partialDuck)
.doRace();
MatcherAssert.assertThat(duck.getLocation(), is(FAR_SIDE));
EasyMock.verify(mock);



partialDuck is a complex example of a partial mock – it combines real and mock objects in three different ways:

  • quack() calls the mock object. It verifies that the duck doesn't promote the sponsor (by quacking) until after the race. (We skip the real quack() method so that our continuous build doesn't drive us crazy.)

  • getLocation() calls the real object. It allows us to use the OlympicDuck's location logic instead of rewriting/simulating the logic from that implementation.

  • swimTo(point) calls both objects. It allows us to verify the call to the real duck before executing it.


There is some debate about whether you should forward to the real or mock Duck by default. If you use the mock duck by default, any new calls to the mock will break the test, making them brittle. If you use the real duck, some very sensitive calls like submitToDrugTest() might get called by your test if your duck happens to win.

Consider using a Partial Mock in tests when you need to leverage the implementation of the real object, but want to limit, simulate or verify method calls using the power of a mock object.

Remember to download this episode of Testing on the Toilet and post it in your office.

Constructor Injection vs. Setter Injection

by Miško Hevery

There seems to be two camps in dependency-injection: (1) The constructor-injection camp and (2) the setter-injection camp. Historically the setter-injection camp come from spring, whereas constructor-injection camp are from pico-container and GUICE. But lets leave the history behind and explore the differences in the strategies.

Setter-Injection

The basic-ideas is that you have a no argument-constructor which creates the object with "reasonable-defaults" . The user of the object can then call setters on the object to override the collaborators of the object in order to wire the object graph together or to replace the key collaborators with test-doubles.

Constructor-Injection

The basic idea with constructor-injection is that the object has no defaults and instead you have a single constructor where all of the collaborators and values need to be supplied before you can instantiate the object.

At first it may seem that setter injection is preferred since you have no argument constructors which will make it easy for you to create the object in production and test. However, there is one non-obvious benefit with constructor injection, which in my opinion makes it a winner. Constructor-injection enforces the order of initialization and prevents circular dependencies. With setter-injection it is not clear in which order things need to be instantiated and when the wiring is done. In a typical application there may be hundreds of collaborators with at least as many setter calls to wire them together. It is easy to miss a few setter calls when wiring the application together. On the other hand constructor-injection automatically enforces the order and completeness of the instantiated. Furthermore, when the last object is instantiated the wiring phase of your application is completed. This further allows me to set the collaborators as final which makes the code easier to comprehend if you know a given field will not change during the lifetime of the application.

Let's look at an example as to how we would instantiate a CreditCardProcessor.
CreditCardProcessor processor = new CreditCardProcessor();

Great I have instantiated CreditCardProcessor, but is that enough? No, I somehow need to know to call, setOfflineQueue(). This information is not necessarily obvious.
OfflineQueue queue = new OfflineQueue();
CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);

Ok I have instantiated the OfflineQueue and remember to set the queue as a collaborator of the processor, but am I done? No, you need to set the database to both the queue and the processor.
Database db = new Database();
OfflineQueue queue = new OfflineQueue();
queue.setDatabase(db);
CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);

But wait, you are not done you need to set the Username, password and the URL on the database.
Database db = new Database();
db.setUsername("username");
db.setPassword("password");
db.setUrl("jdbc:....");
OfflineQueue queue = new OfflineQueue();
queue.setDatabase(db);
CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);

Ok, am I done now? I think so, but how do I know for sure? I know a framework will take care of it, but what if I am in a language where there is no framework, then what?

Ok, now let's see how much easier this will be in the constructor-injection. Lets instantiate CreditCardPrecossor.
CreditCardProcessor processor = new CreditCardProcessor(?queue?, ?db?);

Notice we are not done yet since CreditCardProcessor needs a queue and a database, so lets make those.
Database db = new Database("username", "password", "jdbc:....");
OfflineQueue queue = new OfflineQueue(db);
CreditCardProcessor processor = new CreditCardProcessor(queue, db);

Ok, every constructor parameter is accounted for, therefore we are done. No framework needed, to tell us that we are done. As an added bonus the code will not even compile if all of the constructor arguments are not satisfied. It is also not possible to instantiate things in the wrong order. You must instantiate Database before the OfflineQueue, since otherwise you could not make the compiler happy. I personally find the constructor-injection much easier to use and the code is much easier to read and understand.

Recently, I was building a Flex application and using the Model-View-Controller. Flex XML markup requires that components must have no argument constructors, therefore I was left with setter-injection as the only way to do dependency injection. After several views I was having hard time to keep all of the pieces wired together properly, I was constantly forgetting to wire things together. This made the debugging hard since the application appeared to be wired together (as there are reasonable defaults for your collaborators) but the collaborators were of wrong instances and therefor the application was not behaving just right. To solve the issue, I was forced to abandon the Flex XML as a way to instantiate the application so that I can start using the constructor-injection and these issues went away.

Monday, February 09, 2009

To Assert or Not To Assert

by Miško Hevery

Some of the strongest objections I get from people is on my stance on what I call "defensive programming". You know all those asserts you sprinkle your code with. I have a special hate relationship against null checking. But let me explain.

At first, people wrote code, and spend a lot of time debugging. Than someone came up with the idea of asserting that some set of things should never happen. Now there are two kinds of assertions, the ones where you assert that an object will never get into on inconsistent state and the ones where you assert that objects never gets passed a incorrect value. The most common of which is the null check.

Than some time later people started doing automated unit-testing, and a weird thing happened, those assertions are actually in the way of good unit testing, especially the null check on the arguments. Let me demonstrate with on example.
class House {
  Door door;
  Window window;
  Roof roof;
  Kitchen kitchen;
  LivingRoom livingRoom;
  BedRoom bedRoom;

  House(Door door, Window window,
            Roof roof, Kitchen kitchen,
            LivingRoom livingRoom,
            BedRoom bedRoom){
    this.door = Assert.notNull(door);
    this.window = Assert.notNull(window);
    this.roof = Assert.notNull(roof);
    this.kitchen = Assert.notNull(kitchen);
    this.livingRoom = Assert.notNull(livingRoom);
    this.bedRoom = Assert.notNull(bedRoom);
  }

  void secure() {
    door.lock();
    window.close();
  }
}

Now let's say that i want to test the secure() method. The secure method needs door and window. Therefore my ideal would look like this.
testSecureHouse() {
  Door door = new Door();
  Window window = new Window();
  House house = new House(door, window,
             null, null, null, null);

  house.secure();

  assertTrue(door.isLocked());
  assertTrue(window.isClosed());
}

Since the secure() method only needs to operate on door, and window, those are the only objects which I should have to create. For the rest of them I should be able to pass in null. null is a great way to tell the reader, "these are not the objects you are looking for". Compare the readability with this:
testSecureHouse() {
  Door door = new Door();
  Window window = new Window();
  House house = new House(door, window,
    new Roof(),
    new Kitchen(),
    new LivingRoom(),
    new BedRoom());

  house.secure();

  assertTrue(door.isLocked());
  assertTrue(window.isClosed());
}

If the test fails here you are now sure where to look for the problem since so many objects are involved. It is not clear from the test that that many of the collaborators are not needed.

However this test assumes that all of the collaborators have no argument constructors, which is most likely not the case. So if the Kitchen class needs dependencies in its constructor, we can only assume that the same person who put the asserts in the House also placed them in the Kitchen, LivingRoom, and BedRoom constructor as well. This means that we have to create instances of those to pass the null check, so our real test will look like this:
testSecureHouse() {
  Door door = new Door();
  Window window = new Window();
  House house = new House(door, window,
    new Roof(),
    new Kitchen(new Sink(new Pipes()),
           new Refrigerator()),
    new LivingRoom(new Table(), new TV(), new Sofa()),
    new BedRoom(new Bed(), new Closet()));

  house.secure();

  assertTrue(door.isLocked());
  assertTrue(window.isClosed());
}

Your asserts are forcing you to create so many objects which have nothing to do with the test and only confuse the reader and make the tests hard to write. Now I know that a house with a null roof, livingRoom, kitchen and bedRoom is an inconsistent object which would be an error in production, but I can write another test of my HouseFactory class which will assert that it will never happen.

Now there is a difference if the API is meant for my internal consumption or is part of an external API. For external API I will often times write tests to assert that appropriate error conditions are handled, but for the internal APIs my tests are sufficient.

I am not against asserts, I often use them in my code as well, but most of my asserts check the internal state of an object not wether or not I am passing in a null value. Checking for nulls usually goes against testability, and given a choice between well tested code and untested code with asserts, there is no debate for me which one I chose.

Thursday, February 05, 2009

TotT: Be an MVP of GUI Testing

With all the sport drug scandals of late, it's difficult to find good role models these days. However, when your role model is a Domain Model (object model of the business entities), you don't need to cheat to be an MVP--Use Model-View-Presenter!

MVP is very similar to MVC (Model-View-Controller). In MVC, the presentation logic is shared by Controller and View, as shown in the diagram below. The View is usually derived directly from visible GUI framework component, observing the Model and presenting it visually to the user. The Controller is responsible for deciding how to translate user events into Model changes. In MVP, presentation logic is taken over entirely by a Supervising Controller, also known as a Presenter.

MVC




MVP




The View becomes passive, delegating to the Presenter.

public CongressionalHearingView() {
testimonyWidget.addModifyListener(
new ModifyListener() {
public void modifyText(ModifyEvent e) {
presenter.onModifyTestimony(); // presenter decides action to take
}});
}



The Presenter fetches data from the Model and updates the View.

public class CongressionalHearingPresenter {
public void onModifyTestimony() {
model.parseTestimony(view.getTestimonyText()); // manipulate model
}
public void setWitness(Witness w) {
view.setTestimonyText(w.getTestimony()); // update view
}
}



This separation of duties allows for more modular code, and also enables easy unit testing of the Presenter and the View.

public void testSetWitness() {
spyView = new SpyCongressionalHearingView();
presenter = new CongressionalHearingPresenter(spyView);
presenter.setWitness(new Witness(“Mark McGwire”, “I didn't do it”));
assertEquals( “I didn't do it”, spyView.getTestimonyText());
}



Note that this makes use of a perfectly legal injection -- Dependency Injection.

Remember to download this episode of Testing on the Toilet and post it in your office.