Does anyone have any experience doing unit tests (or similar) when using Zay-ES? I’m just reading about test driven development and was wondering how one would go about doing unit tests for Zay-ES.
The way things are, I create entitycomponents on an entity, and intend for a system to pick up on those and do something with it. I can’t really see how that can be set up for unit tests. I have no measurable experience with unit tests, but would like to have some in my game dev project.
That’s not really a unit test. That’s an integration test.
A unit test only tests the unit being tested… which means that everything else external is mocked. (Groovy provides a lot of built-in features for testing, by the way… numerous articles on the web about it.)
In the end, in my opinion, you should target your unit tests to a very specific core set of code. The farther you get from “something everything uses” the more of a waste of time it is.
I have strong opinions about TDD in general. It WAAAY slows down development as often the test code will be 2x or more as much as the real code. And without 100% coverage you lose pretty much all of the promises of unit testing. (We could have a really long discussion about how the bugs you are most likely to have are also in the code that is least easy to write unit tests for, therefore least likely to have been unit tested if you aren’t going for 100% coverage.)
Instead, I recommend taking some of those ideas from unit testing and apply them to targeted areas where you get the most day-to-day bang. Core classes. Fragile code. Classes where you rely on certain side-effect behavior. All good candidates.
I’ll try to keep focus on unit testing, instead of integration testing. An example candidate in Sim-eth-es would be createBody in SimplePhysics. There’s no integration, only data, and it returns an object I can measure.
So whenever I intend to create new physical bodies, I can write up a unit test for that method and new data. Makes sense. I’ll do some googling on groove testing and see if I can get a unit testing framework up and running in gradle.
Just to be clear, since we’ve now used the word “integration” for two different things… I wanted to point out that it means two different things in case there was confusion.
There is “integration” as in the calculation of differential equations as done in physics.
And there is “integration testing”, which is testing multiple components “integrated” together.
In unit testing, you test only the “unit”. You would typically create mock objects for anything that the unit interacts (integrates) with… such as the ES or on some level even Vec3d/Quatd, etc… You carefully control what these mock versions return from their methods so that you aren’t testing them but the unit you are testing. In groovy’s mockFor() objects, you can even validate that methods are called in a particular order with particular parameters on the mock object. Very useful for proper unit testing.
…but note: proper unit testing is a real pain in the ass. It often takes 2-3 times as long to write the tests as the original object.
My experience tells me that the more automated tests you have the better you sleep. I do TDD when ever possible as it might be 2 times slower but this is only true for the beginning, after a couple of days, you might spend more time debugging nasty not often manually tested code parts which suddenly do not work any more. So I basically do not agree with “it is slower”. Done right it is not a pain in the ass but a joy to work, it brought be back my old days very a blinking cursor on a grey screen of my ZX81 was the highlight of the day, not talking about my first “hello world” on the screen
Integration tests can be a pain and for personal stuff I do not spend too much time on it (but spend more time debugging nasty behaviour, see above). For productive code, for me, there is really no way around testing, automated testing. Also if you have to maintain it later for several years and also for the successor of that piece of code I wrote, tests are a life safer.
As well it is not (only) about code coverage but about tests which must fail if something is broken, you can only guarantee this by write the corresponding test before your code and make sure it fails. But don’t write all the unit tests or even the integration tests before your code, do it in a cycle and step wise. On my fprintf blog http://fprintf.logdown.com/posts/593792 I mention three blog articles from a game developer