The current project I am involved in, we are using BDD style of testing, where our specifications (tests) are both designing force and documentation for the implementation. One of the interesting cases we are running into, is when we need to express some complex conditions. For example
When a component is asked to perform some action on some object
- Should do A
- Should do B
Then we add complexity by trying to look into what is going to happen when
- instance of some object is valid
- instance of some object is invalid
So far it’s working nicely, and code looks like this
1: public class When_component_is_asked_to_perform_some_action_on_some_other_object : Component_Specs
2: {
3: [Observation]
4: public void Should_do_A() {}
5:
6: [Observation]
7: public void Should_do_B() {}
8: }
9:
10: public class And_some_other_object_is_valid : When_component_is_asked_to_perform_some_action_on_some_other_object
11: {
12: [Observation]
13: public void Should_happen_something_when_some_object_is_valid() {}
14:
15: }
16:
17: public class And_some_other_object_is_invalid : When_component_is_asked_to_perform_some_action_on_some_other_object
18: {
19: [Observation]
20: public void Should_happen_something_else_when_some_object_is_invalid() {}
21:
22: }
The problem started when there were 10 passing tests instead of 6. Well, good that they all were passing, but what’s the catch? Apparently, the When_component_is_asked_to_perform_some_action_on_some_other_object class was running on it’s own, in addition to the AND specifications that included its’ observations by inheritance. Solution was simple, don’t let the testing framework instantiate the base specification.
1: public abstract class When_component_is_asked_to_perform_some_action_on_some_other_object : Component_Specs
2: {
3: [Observation]
4: public void Should_do_A() {}
5:
6: [Observation]
7: public void Should_do_B() {}
8: }
9:
10: public class And_some_other_object_is_valid : When_component_is_asked_to_perform_some_action_on_some_other_object
11: {
12: [Observation]
13: public void Should_happen_something_when_some_object_is_valid() {}
14:
15: }
16:
17: public class And_some_other_object_is_invalid : When_component_is_asked_to_perform_some_action_on_some_other_object
18: {
19: [Observation]
20: public void Should_happen_something_else_when_some_object_is_invalid() {}
21:
22: }
Moral: passing tests is important. Having clean and manageable tests is no less important.