Skip to main content
Shura (aka Alexandre Iline) (Alexandre.Iline@Sun.Com)
Maria Tishkova (Maria.Tishkova@Sun.COM)
June 29, 2005

Concept oriented testing.

Preface.

The OOP gurus! This text is not for you. It is for the stupid us for whom it is not obvious what class model to choose when we start designing our systems.

Moreover, this text is for those weirds who are willing to do application testing. Even more: for those who want to perform regular automated UI testing. It is for those, however, who wants to achieve greater results with less support, after the test system is implemented and working.

To be more precise, the whole point of discussing test class model approaches is ... to minimize changes in the automated tests by incapsulating the code in some kind of a library.

That - the library design principles - is the topic discussed here.

Assumptions

This article assumes that you have a possibility to write UI testing code in Java. For that you would have to use one of the open source Java UI testing tools, such as Jemmy or JFCUnit.

The statements.

Let me start with one claim:
  1. You have to change your test code every now and then. You do have to ... unless the product you test is not changing. But ... if it is not changing, why to test it, then?

    If you do not have to change the test code when the product code is changed ... that could only be because your test logic does not depend on that product logic which was changed. That might mean (not necessarily, though) you just do not test that functionality - that code which was changed.

    Next one would be
  2. It's cheaper to change the underlying library code rather than the test.

    Seems obvious, however .... the reason is: you supposed to have a number of automated tests. This is, a _NUMBER_ of them. So, how would you go for a change in the test? Would you want to change all of them? I do not think so, do you?

    You, instead, would want to do
  3. Only one change for a one change of the product. Well, preferably, no changes ... :) (see above, however), But if you do, it's better to have to do as little changes as possible.

    So, the answer is obvious:
  4. Move the common code into some kind of a library. Now, that is really obvious, but ... how to build the library, what principles to build it on? (at this point the OOP gurus, who still in the audience, leave disgusted).

    In this article, we will only be discussing two approaches out of all the possible approaches to the library creation. We will, then, pick the one requiring less changes to the test code.

    So, the approaches are:
    • UI-depended approach
    • Concept-depended approach (for not having a better name)

Below we will use a simple example: filling a car-record. Color, model, make, license plate, ... all the attributed are filled in from the GUI.

UI-dependent library.

This a natural way of doing things ... you have a dialog window within the product, you create a class covering the window functionality and that's it - you're covered. Let me show an example.

So, what would the UI look like for editing a car-record. Well, likely it is a JFrame (JDialog) having controls for setting such things as color, model, make, etc.

So, what you would want to have in your test code is a class which provides attribute setting/getting functionality. Something like this:
public class CarRecordDialogOperator {
	public void enterColor(String color) {
		//find the text field
		...
		//type in the color
		...
		//click the ok button.
		...
	}
	public void enterModel(String model) {
		...
	}
	...
}
Your test code looks then like this:
class MyTest() {
	public void testSetGreenColor() {
		new CarRecordDialogOperator().enterColor("green");
	}
}
So, let's see what happens when the dialog is changed.
  1. Let's suppose that now the dialog not only has the color text field but also provides a way to call the color chooser.

    Do you need to change some code?
    No you don't. You may want to create more code to cover the color chooser invocation functionality, but you do not need to change the existing tests - they just work (this is due to the fact that the dialog still has the text field).

    That's good. But what if
  2. Now let's suppose that the dialog has changed a way that the color is not entered into a text field but instead into a combo box.

    Do you need to change the code?
    Yes, you do.

    How many changes will you be doing?
    One.

    Do you need to change the test code?
    No.

    One change only - you only have to change the enterColor() method body (to look for a combo box where it used to look for text field) and that's it.

  3. Now, let's suppose the text field disappeared completely and now we only have a color chooser.

    Do you have to change the code?
    Well ... you could do a hack ... "parse" the color name (some of them you could, probably, recognize), perhaps, and pick the color from the color chooser. But, to be honest ... yes, you do have to change the enterColor() method to use whatever color attributes are used to select color through the color chooser.

    Now, how many changes will you have to do?
    Well ... like I said, you can do a hack, but ... to be consistent ... plenty.

    Do you need to change the tests?
    Yes, basically, all of them which have to do with the color changing.

    And the very last case I would like to discuss here ...
  4. What if the dialog disappeared completely? What if the car records are edited within some table now and no dialog needed?

    This is even worse than 3:
    Do you have to change the code?
    Yes.

    Now, how many changes will you have to do?
    Plenty.

    Do you need to change the tests?
    All of the tests for car record editing.

So .......

Bottom line - whatever level of abstractions you implement, as long as your tests depend on the application UI logic, there may be cases when you have to change your test code.

The approach we just described is useful and everything, however, surely enough, we need another layer of abstraction.

Concept-depended approach

And the next level ... as we see now .. should not depend on the application UI.
Now, let me just jump on it with no further explanations.
This is how the code needs to look like:
class MyTest() {
	public void testSetGreenColor() {
		new CarRecord().setColor(CarColor.GREEN));
	}
}
Obvious, huh? Yes, it sure is.

Despite all the simplicity, this is the approach we are looking for.

Indeed, the test code only rely on the fact of having "car record" concept and the fact that the car has a color and the fact that some cars could, potentially, be green.

So, until there are green cars could be entered in the system .... test does not need to be changes.

 
 
Close
loading
Please Confirm
Close