Orthogonal Test Organization
Posted: Sat Dec 05, 2009 8:35 am
Lets say you had a SUT (system under test)
For fun lets make it a Animal class.
So the Animal class has this interface:
Let's say this Animal gets injected (for testability) a configuration object in it's constructor, the config option provides paramaters
Let's say you will need to cover these code paths
I might create these test classes:
Now what if I need another configuration option, canWalk (controls forwards & backwards with 1 setting)
So there is a new path
The new test classes would be
Now what if I need to make yet another setting that was orthogonal with the existing settings, how do you keep from a test class explosion, without violating single responsibility principle in the test class (each test class should only declare the test utility methods it uses).
I guess this would be more of a functional test suite, so I want to be able to test each possible path, lets say I needed to test all these paths. How do you organize the tests?
In a real example you could say get rid of the Noise path, its decoupled from walking, but lets make it a real example and say we also need to test a ton of behavior like the animal making noises every N steps it takes, etc... ( so suddenly you are multiplying the # of paths again and again)
Would you have
etc....
How do you keep from littering your namespace?
For fun lets make it a Animal class.
So the Animal class has this interface:
Code: Select all
walkForwards()
walkBackwards()
makeNoise()Code: Select all
walkSpeed
canWalkBackwards
noiseStyle
Code: Select all
A) walkForwards WILL walk the appropriate speed
B) walkBackwards WILL walk the appropriate speed
C) walkBackwards WILL throw an exception if this animal can not Walk Backwards
D) makeNoise should use the right noise styleCode: Select all
AnimalWalkTest test class will test paths A & B & C
AnimcalNoiseTest will test path DSo there is a new path
Code: Select all
E) walkForwards WILL throw an exception if animal is NOT a WalkerCode: Select all
AnimalWalkTest test class will test paths A & B
AnimcalCanWalkTest will test paths C & D & E
AnimcalNoiseTest will test path DI guess this would be more of a functional test suite, so I want to be able to test each possible path, lets say I needed to test all these paths. How do you organize the tests?
Code: Select all
walkSpeed = happy path
canWalkBackwards = True
noiseStyle = happy path
canWalk = True
walkSpeed = boundary path
canWalkBackwards = True
noiseStyle = happy path
canWalk = True
walkSpeed = happy path
canWalkBackwards = False
noiseStyle = happy path
canWalk = True
walkSpeed = happy path
canWalkBackwards = True
noiseStyle = boundary path
canWalk = True
walkSpeed = boundary path
canWalkBackwards = True
noiseStyle = boundary path
canWalk = True
walkSpeed = boundary path
canWalkBackwards = False
noiseStyle = boundary path
canWalk = True
walkSpeed = happy path
canWalkBackwards = True
noiseStyle = happy path
canWalk = False
walkSpeed = boundary path
canWalkBackwards = True
noiseStyle = happy path
canWalk = False
walkSpeed = happy path
canWalkBackwards = False
noiseStyle = happy path
canWalk = False
walkSpeed = happy path
canWalkBackwards = True
noiseStyle = boundary path
canWalk = False
walkSpeed = boundary path
canWalkBackwards = True
noiseStyle = boundary path
canWalk = False
walkSpeed = boundary path
canWalkBackwards = False
noiseStyle = boundary path
canWalk = FalseWould you have
Code: Select all
AnimalWalkForwardsNoiseTestClass
AnimalWalkForwardsSpeedTestClass
AnimalWalkBackwardsNoiseTestClass
AnimalWalkSpeedNoiseTestClassHow do you keep from littering your namespace?