Saturday, June 11, 2011

Flexible validation mechanism in test automation using decorator pattern

Today, I like to talk about having flexible way of validation logic in your test automation.

Are you familiar with design pattern called "Decorator?" I don't want to spend a lot of time explaining what it is in this post, so you can search Decorator pattern on the web (there are a lot of them).

Basically, what it is is that having mechanism of code to process what is responsible for currently object and trigger the next object in line to process its own logic. (you really need to understand what decorator pattern is if you don't know it)

Now, we can apply this pattern to validation logic.
Normally, in your automation there are several different kinds of validations you would put to conclude that the test passed or not. As the automation gets more complicated and scale, you would not want to have one validation class that handles all the validation/verification for all test cases. New and different kind of validation/verification logic might need some other process that previous validation logic not required. So how do you flexibly add new verification logic in to your automation? There will be several ways to handle this but one of the solution is using decorator pattern.

Let me go though the concept and I will provide some example of that.

  1. Define a base abstract class/interface (i.e. Validator) and defined a constructor that takes Validator object and  method called validate().
  2. Now create derived class call Validator1, Validator2,.... that inherit/implements the base class/interface
  3. In Validator1 and Validator2 class implement a private method that process its own logic and have its validate() method to call that. 
  4. After #3, call validate() method of Validator instance variable
The simple code would look like this.

public abstract class Validator
{
    private Validator m_validator;
    
    public Validator(Validator validator)
    {
        m_validator = validator;
    }
    
    public abstract validate();
}


public class Validator1 extends Validator
{
    private Validator m_validator;

    public Validator1(Validator validator)
    {
        m_validator = validator;
    }
 
    public validate()
    {
        validator1logic();
        m_validator.validate();
    }

   private void validator1logic()
   {
        //execute the logic here
    }
}

You can see the idea here. Each derived Valdiator class will have its own logic and execute validate() method whatever Validator object passed.

Now you have several derived Validator classes and you can mix and match any combination as you wish.

Here is the sample code

// 3->2->1 in order
Validator myValidator = new Validator3( new Validator2 ( new Validator1(null)));
myValidator.validate();

// just 2 and 1
Validator myValidator = new Validator3( new Validator1(null));
myValidator.validate();

// 1,2 3
Validator myValidator = new Validator1( new Validator2 ( new Validator3(null)));
myValidator.validate();

Saturday, June 4, 2011

Assumptions in software testing

"Today, I like to talk about assumptions in software testing.

In a daily life, we do make lot of assumptions. Maybe because we're so used to it, or because we've never seen other side of the situation.

In software testing, we should be very careful about these assumptions. PMs, Devs and business owners are making statements with a lot of assumptions when they write or speak about the application. Even if the spec did not mentions about assumption, we, testers, need to figure out what assumptions are made in the project team and understand the impact of that. 

Some assumptions are safe, but sometimes assumptions cost you a lot of money to the company.

I was lucky enough to have a Skype coaching with James Bach. And I learned that we, testers, need to be very careful about assumptions. Since I got permission from James Bach to share his teaching, I'll use his example to show the impacts of assumption.

" Let's say you are carrying a calculator. You drop it. Perhaps it is damaged. What might you do to test it?"

Think about this for a moment. 
Can you question the statement above?

First, I guess we visualize the situation. At least, I did. Wherever you are. And you drop the calculator. The situation seems pretty normal. Our focus seems to test the calculator to make sure it is working correctly.

What he was trying to teach here first, I think, is that do not jump on testing without understanding the situation clearly.

Can you ask what kind of calculator is it?
How did I dropped it? Where does it dropped? Where am I? Who am I?

You can come up with more questions to understand the situation. Right?

Then your test case will be narrow down. Then your testing is more focused on the correct situation.
Would that save the cost of testing?(time, energy and budget)

So now, let's talk about assumption. Assumptions are all that bad then in testing?
Here is what James Bach said.


Have you ever seen a building that was being built? Builders use scaffolding to put it up the scaffolding is not the building. it's a tool used to create the building and at the end they take the scaffolding down.
assumptions in testing is like scaffolding. at least, a LOT of assumptions are like scaffolding
some assumptions are like foundation. Scaffolding is temporary. Foundation is permanent.

The leaning tower of Pisa is leaning because the ground is not as solid as they thought it was... that's like a bad assumption. We use assumptions in testing, and that's a good thing. but you must distinguish between safe assumptions and dangerous assumptions. Assumptions are to testers as bees are to a beekeeper... if the beekeeper never wants to be stung, he better get rid of all the bees
but then he'll have no honey. so he keeps the bees but he's CAREFUL with them.
we make assumptions. but if an assumption is dangerous
we will either:
1. not make it
2. make it but declare it
3. make it but not for long

Now, your assignment is to make a list
of what factors make an assumption dangerous

The End