I had problems finding a good question title, so feel free to improve on that.
I want to implement an Entity Component System in C++, and wish to use TDD for the first time. Now I have doubts about how useful TDD is when the target "architecture" is already specified, but want to try it anyway. My problem is more of a TDD problem though, and I could have run into it in another context as well:
The first test was supposed to check that I can add a Component
to an Entity
as an Entity
should "possess" a set of Component
s (maybe this is a bad test and the problem lies here already?). So far no code exists and I'm facing a dilemma which might not be one. I could write a test that does this:
Entity e;
Component c;
e.add(c);
But how would I assert that the add
has worked correctly? I know I am going to need some sort of has_component
method sooner or later, but I shouldn't implement additional functionality now, or should I?
I could also make Entity
have some list type in its public interface and use that in the test, and refactor that "away" later.
What is a correct approach here? It might be my mindset for TDD is totally off, so I'm grateful for any input!
-
I'm also unsure about the tags. Does this question merit the C++ tag, or is it irrelevant here?InvisiblePanda– InvisiblePanda2016年11月01日 17:03:56 +00:00Commented Nov 1, 2016 at 17:03
1 Answer 1
Your first test is a good start. Maybe think about error checking: is there a return code from add, to tell that it did work or not ? Or is it supposed to throw an exception if something goes wrong ?
Preferred approach
Knowing that you'll need a method has_component()
for the Entity
class, just add it to the class definition, with a stub implementation that always return false
(and a big comment // TO DO !!
).
Your next test would then be:
assert(! e.has_component(c) );
e.add(c);
assert(e.has_component(c)); // or return FAIL to your test framework.
The principle is that your test will fail until both functions are correct.
What are the alternatives
- use a simpler member, such as
number_of_components()
to check that you're on the right track (i.e. number increases when adding a new component; number remains same when adding same component twice). - let the test code inspect the internals of your
Entity
. I don't like this approach, because it breaks the rules of encapsulation. - make a a test double that provides emulated/simulated answer for
has_component()
. Would it be a very complex feature, this would be the way to go. But for simple features like here, this might be overkill. - if you'd have a dispatching function that forwards calls from
Entity
toComponents
you could use it to check if c reacts.
-
1In addition to this, writing degenerate test cases can sometimes help, for example, write a test for what would happen if the user passes
null
to theadd
method.Matthew– Matthew2016年11月01日 18:43:00 +00:00Commented Nov 1, 2016 at 18:43 -
Thank you for this great input! I understand the merits of the different ways to go about it now I think. I try to adhere to "one assert per test" though. Your post also made me think of different ways to tackle the
Entity
class and what would happen if I e.g. wrote a test for different methods first.InvisiblePanda– InvisiblePanda2016年11月02日 18:20:52 +00:00Commented Nov 2, 2016 at 18:20