Isn't this a bit idealistic?
No, absolutely not.
You can never cover everything in tests
You can, and by applying TDD, you choose a workflow that even forces that. There are features that can't be covered by automated unit tests though, for example graphical things. Those have to be tested by humans but are also usually not critical.
and waiting for all possible tests to be written before a feature is implemented is only feasible in simple cases
I think you got the idea of TDD wrong. You don't write all tests beforehand. You write one single test case, and then you write the implementation, like this:
// Test case:
test( sum( 1, 2 ) == 3 );
// Implementation:
int sum( int a, int b ) {
return a + b;
}
One rule is that you only write code in the implementation that's being covered by the test cases. If it's not covered, you have to write another test first.
but bugs often appear in unexpected places (such as when you combine multiple features, and only in rare special cases)
And that's what unit testing avoids: Having unexpected bugs. If code is covered, there's no way you can miss a bug. You can still write wrong test cases, but here the following applies: Do you want to not do testing and accept a high chance of bugs, or do you want to do testing and accept a very low chance of writing wrong tests? If something's goes wrong, you've got a problem in both cases, but with unit testing it's minimized.
When you combine multiple features you do so called "integration tests", either with real objects or mock objects. It's all testable.
the chances of unintentional bugs just get reduced quite a bit and since you have all these tests, figuring out what is not being tested is quite a bit easier.
What do you mean by "unintentional bugs"? Let's assume theoretical 100% code coverage, how should a bug happen? The only chance something goes wrong is when you write a wrong test case -- but that's not a bug, it's a logic error.
Personally, I think it sounds awesome, but it often seems like so much work, plus there's always that thing, that you can't really test, especially for games...
Writing unit tests means work, yes. Robert C. Martin says "Professional programmers want to make sure that their code works", and I fully agree to that. The result is software tests. And by the way, software tests are also fun once you get used to the workflow.
The situation for games is not really different than for other application types. You can test nearly everything, except graphics effects and such. Untestable things are the rare cases.
I think you can still have bugs if you have covered 100% of the code with some test, but did not handle 100% of the functionality in the tests.
// Test case:
test( sum( 1, 2 ) == 3 );
// Implementation:
int sum( int a, int b ) {
return 3;
}
Oh yeah, I read you should only add the simplest thing to satisfy the test. :P
Also you would be supposed to make the test fail before making it pass. And then add more tests to get to the real implementation.
Somehow its easiest for those simple functions that always get put into examples and much work for something that rarely could get wrong. But the things you would gain most from having tests for are also the most difficult to write the tests for (thats what I'm still struggling with).
int sum( int a, int b ) {
return 3;
}
Oh yeah, I read you should only add the simplest thing to satisfy the test. :P
That's true, but why on earth do you want to trick yourself? ;-) That's what a lot of people get wrong as well: Unit testing doesn't mean to find ways to make everything fail, it's there to make sure that the stuff you write works as expected.
Returning a constant 3 in a function named "sum()" is clearly a logic error. If that's what you intended, then it's 100% bug-free. Again, illogical stuff is not a bug!
Also you would be supposed to make the test fail before making it pass.
Yes, that's true and important.
But the things you would gain most from having tests for are also the most difficult to write the tests for (thats what I'm still struggling with).
Can you give an example? I'm willing to help. :)
how one is meant to aim for 100% coverage when developing a game, due to visual aspect. How do you verify that what you mean to draw really is drawn?
The actual rendering itself is a very small part of the whole visual thing. For example you can test that positions, properties, blending modes and whatnot of your rendering objects are as you would expect. The final image has to be approved by human eyes; if you then continue by grabbing a screenshot of the result and use that for comparing against future final results is up to you, but for some things it's really okay to move them to the acceptance test area. ;-)
correct me if I 'm wrong Tank but SFGUI doesn't got a test suite; instead the examples are used as tests
It's correct. I've started SFGUI when I wasn't into software tests. And I can tell you that so many bugs could have been avoided by doing tests. Besides of that it's really time-consuming and annoying to run through all the examples (often the "test" program is enough, because it literally contains everything), click everything, check everything, look at everything etc. Side effects happen, and they are dangerous (they happen less with TDD, because you design differently; but if they happen, you usually detect them through failing tests somewhere).