4

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 Components (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 Nov 1 '16 at 17:03
4

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 to Components you could use it to check if c reacts.
  • 1
    In 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 the add method. – Matthew Nov 1 '16 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 Nov 2 '16 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.