Saturday, October 12, 2013

Writing Selenium Tests in a more DSL like way

I noted in a previous blog post that I was starting to write more tests in a more fluent DSL like manner. I thought I would illustrate this. Here is an example of a test that does the following (assuming you are logged in on the home screen):

  1. From the navigator (think of it as a button bar) click the "Create wantlist" - this will launch a create wantlist editor and return this solvent.
  2. We want to fill in the fields and check for certain conditions (like if the form is valid or not). 
  3. We want to hit "save" button
I do not show the additional steps of verifying the item that got created in the table.

public void create() {
    Navigation nav = new Navigation(config);
    WantlistEditor editor = nav.create(Navigation.CreateAction.WANTLIST);
    String id = generateUnique("");
    editor.invalid()
            .set(factory.get(StampAttribute.Country, Country.BASUTOLAND))
            .set(factory.get(StampAttribute.Denomination, "2d"))
            .set(factory.get(StampAttribute.Description, "scarlet (\"Tail\" flaw)"))
            .set(factory.get(StampAttribute.Catalogue, Catalogue.STANLEY_GIBBONS))
            .set(factory.get(StampAttribute.CatalogueCondition, Condition.MINT_NG))
            .set(factory.get(StampAttribute.CatalogueNumber, "193a-" + id))
            .set(factory.get(StampAttribute.CatalogueValue, 2.25))
            .valid()
            .save()
            .success();



On thing to point out is that when I call a method like valid() or invalid() I am not returning a boolean from the function (in the past it would have been a isValid() type syntax. Instead, I am coding the test as I expect it to behave and if it is not behaving in this manner it will fail at that point. As well a method like success() is programmed to look for the closure of the editor as marking a successful create.

As mentioned earlier, I am using an attribute factory to get the attribute. An attribute is a nifty class I created which is able to hold a value that was set (so I can verify it) and also state what the input type is (selection, checkbox, text etc.) and is able to return a selenium By object that I can use for selection.

On large disadvantage of using the chaining approach is exceptions. Unless your methods themselves do not report errors well, it is difficult to trace what line causes the error. This is one disadvantage of DSL interfaces and means you need to think better about the erroneous conditions and how best to log/print them to console/log files.

No comments: