I am writing a game using a custom ECS architecture. I recently had a chain of nasty bugs where fixing one bug caused regressions elsewhere. Being a software engineer by trade, I suppose that unit tests would allow me to fix these bugs more safely (and so faster) - but the approaches I'd usually take to unit testing seem to get tangled up in the ECS architecture.

For example:

  • Items are entities (there is a component which marks an entity as an item)
  • Some entities have inventories, so inventories are components.
  • Some items can stack when picked up, where what was two entities on the ground becomes a single entity representing the stack if both are picked up.

I would like to create a test to cover this stacking behavior because I recently had bugs in that area. The scenario seems like a basic 1+1=2 test: Verify that an empty inventory that picks up two identical stackable items has a stack of two of that item afterward, however, running that test requires instantiating the ECS system because this interaction involves creating and deleting entities (the stacked item is a different entity than either of its constituent items).

Is this scenario not such a good candidate for unit testing after all, and I should write it as an integration test instead? (If so, is it a problem if I find that almost none of my components or systems can be meaningfully unit tested?) Should I reframe my thinking around unit tests and consider a test that covers Component+ECS as a "unit" test? Is the fact that I can't unit test this sort of scenario evidence of a messy code base that I should refactor?


1 Answer 1


It is entirely normal for unit tests to involve dependencies of the thing you are testing. For example, you have probably written many tests that (directly or indirectly) invoke the memory allocator to allocate objects that you are going to test, or test data. That doesn't mean they're integration tests.

What you should do in this kind of situation is make sure that it is easy and concise to set up the ECS in a test, and to make assertions about what entities and components exist at the end. That way it is not tedious to write multiple tests, and the tests are focused on the thing being tested rather than cluttered with setup code. Hopefully, this will pay off many times over in writing tests for many components.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .