TDD for jMonkeyEngine games

Hello fellow jMonkeys,

I would like to bring up TDD for discussion in relation to developing game software with jME3.

I am seeking to find those within the community that would like to colaborate on finding a way to make the jME3 engine easy to use within the TDD paradigm. To this end, we would need to find a way, a consensus, that will make passing tests easy to write against jME3 instanced objects.

I realise that many parts of a visual library cannot be tested programatically. But there again, many things can.
For instance:

  1. my rootNode should contain 27 children, so why does my test fail when I ask it to confirm that there are 27?
  2. the appStateManager should not contain an instance of MyAppState, so why does this test fail saying it’s still attached?
  3. The X-Wing model loaded by the assetManager should contain six child nodes. However, it contains seven. I forgot that I altered the model and now there is an extra node that I had forgotten about.
  4. Maybe even things like AI navigation, ray casting and collision bodies can be programatically tested.
    … and so on.

To this end, I have set up a sample project that runs jUnit tests against instantiated jME3 class fields. Some fields are instantiated and are “live”, others are null. Some fields can be constructed outside of the app instance for testing purposes. Some fields like assetManager seem to be enigmatic (at least to me, right now).

Monkeys can download and run the tests themselves. The test files are AppTest.java and LoadDiceModelTest.java The only dependencies for the project are the jME3 libraries in the libraries node and the jUnit library in the test libraries node. I used jUnit 4.10. These libraries are easy to set up in the SDK. In the project root directory, there is a text file called " TDD4jME3 discussion.txt" which sets out my own conclusions drawn from the tests. Tests with the @Ignore annotation do not currently pass. The annotation can be commented out and other Monkeys can see if they can get those tests to pass, and share the results … and the successful code.

Download link:
https://dl.dropboxusercontent.com/u/9940923/TDD4jME3.zip

I look forward to ideas on how this feature can be achieved for jME3. I have some ideas that I can share too, if others are interested.

And finally, for your perusal, here is an interesting article on the benefits of TDD:
http://java.dzone.com/articles/basics-test-driven-development

2 Likes

Sorry if I troll, but, did you really weigh the pros and cons of TDD?
I mean TDD is already kind of heavy for a company, with dedicated teams to tests and all…but for an indie game developer IMO it’s like shooting yourself in the foot.
Read this 7 Reasons Why TDD Failed to become Mainstream - PHP Classes

I’m not preaching against it in general really, I’m just warning you that you should really think how your game will benefit this and weigh it against the time sink that developing test is.

Also TDD can get really kinky and sidetrack you from the most important things. For example :

@alfinete said: 3. The X-Wing model loaded by the assetManager should contain six child nodes. However, it contains seven. I forgot that I altered the model and now there is an extra node that I had forgotten about.
And what are you gonna do about it? fix the model? or fix the test? If your answer is "fix the test", writing it in the first place was a waste of time. Imagine how it would go in a team with a dev and an artist : dev : "Dude your change to the xwing model doesn't pass the tests, there is a 7th node" artist : "So what? I need this node for the extra balster, how come it breaks the game?" dev : "ho no it doesn't break the game, it breaks the tests...."

That’s what I hate about TDD, most of the time it detects false positive and you end up fixing tests because your program legitimately changed.
You’re gonna say that this example is not really good because it was not really meant as a real situation but more an example. But unfortunately, in real life that’s the kind of test you write in a TDD approach because you have absolutely no insight of what/how/when the need is gonna change and you can’t foresee that a test is gonna be a waste.

IMO, basic unit testing of the core features is plenty enough, when applicable. But is that applicable to a game?

1 Like

Yes, there is an excellent point in nehon’s post: if TDD is always reactive in a particular area then it is only “makework” and not actually buying you any benefits. The idea behind TDD is that you write the tests first… which implies that if you are making changes that you also change the tests FIRST. The X-wing model is an example where such a thing would be pretty ridiculous. a) there is no predictable way to change the tests before you change the model, b) the difference in node counts is really immaterial in the end.

Also, much of the premise is already confusing what a “unit test” is. If I have a node with 5 children and I add a child, a unit test can check to see that there are now 6 children. If I load a model and check its node count, I’m actually doing a much higher form of testing than “unit testing”. (Whether it’s functional testing or integration testing is context-specific.)

Thank you for your comments. I appreciate the feed back. I had an inkling of your feeling towards TDD from the other earlier thread on the same topic.

I am writing my current project in jME3 largely without tests. Personally, I don’t think the TDD paradigm is necessary for all code. Most code is pretty straight forward to write and get right. However, when I need to write a tricky method, it is often easier to do so writing tests first. Sometimes the tricky method is cumbersome to check in your app, coz it needs a dozen clicks to get your app to the place where the method is being called. To have a test set up with class fields in the right state and then run it at a single click is quite a time saver. Plus, simple “sout” statements in the test can reveal info about class variables without using a whole lot of logging statements in your code. Some people write spike code. I think this is just testing outside of a testing environment, and has pretty much the same objective. Code written from tests fits seemlessly into place, spike code does not always merge so well.

Finding a way to get to the jME3 class objects to test against is merely a tool that can be used when needed. I’m not a wine drinker, but I have a corkscrew in my kitchen draw. A corkscrew is pretty much useless for anything except pulling corks out of wine bottles. But if friends turn up with a bottle of wine and I want to have a glass with them, I don’t want to try to get the cork out of the bottle with a carving knife. In the same way, having a good set of Allen Keys is essential if you are mechanic. But even if you are not a mechanic, having a set is useful for tightening up the legs on your electric piano stand.

It is to this end that I SEEK to find a way to get live SimpleApplication objects from an app instance to use in tests.

Hence to quote myself …

I am seeking to find those within the community that would like to colaborate on finding a way to make the jME3 engine easy to use within the TDD paradigm. (i.e. to run tests against an app instance). To this end, we would need to find a way, a consensus, that will make passing tests easy to write against jME3 instanced objects.

As for me … I have done some work running an app instance in another thread with the simpleUpdate() method blocked with a while(boolean){} loop. Even so, I have not been able to achieve viable objects. I’ll keep working on it as I get time. If others are interested in pitching in, that would be great. Perhaps there is a way to make a test runner in jME3 itself (headless?), maybe with appStates. I guess there are many possiblities.

Now imagine that every corkscrew you own requires constant maintenance and people who come to your house will somehow get confused if your corkscrew is in the wrong place… or they will see the corkscrew and think this must be a wine bar and treat it accordingly… or they will leave and go next door and spend several days there thinking “Why isn’t this the house I wanted? I tried the other house but it was a wine bar, so…”

In JME, corkscrews aren’t free. Every one is a maintenance/documentation/design/maintenance burden.

Beside, I plan to cut SimpleApplication out of the framework with a rusty dull spoon someday soon… you’d hate to have depended on the “class you shouldn’t be depending on anyway”. If your code is directly calling SimpleApplication methods then it might be broken.