After a few month developing my OPM Editor, it is now in a fairly usable stage. At least enough to start working on the OPM Interpreter, the real reason behind the editor. My idea is to use OPM as a high-level visual programming language, implementing low-level operations being implemented in textual programming languages.
So where do I start? I have one requirement: to be able to click on the “execute” button in eclipse, and then the model will execute… Oh I would make a perfect client ;-).
Anyway, I started playing with the idea how to implement my interpreter, going forward and back, but never moving very far. So I decided it was time for a change. I have read a lot about TDD (Test Driven Development), a methodology which tells that you should first write your tests and then implement your code. I hadn’t done any TDD in my life (at my previous job we did unit testing, but after writing code. And now as a researcher I seldom write unit tests). But being able to write the tests before the code also means that you know what you want your code to do, and this was my problem – I was unable to think what my code should do.
So now I’m in my second week of TDD. It has been a rough time but I think I am starting to understand how things work. One of the first things that happens when you start massive unit testing is that your test classes sometimes become larger than the classes under test. This is really depressing. But then when you think about it a bit more, you start to understand that this is OK, and it is probably normal. Software systems have almost infinite inputs, so the testing space is also infinite. If you have a function that takes 2 booleans and does something, you have [latex]2^2[/latex] possible inputs. Not much, right?. But if instead of Boolean they are integer, this explodes to [latex](2^32)^2[/latex], which is a very large number by any count. so in theory, it is definitely OK for tests to be longer than functionality. But it still hurts.
Another thing that takes time to understand are mocking frameworks. First of all, you have to learn when to use mocks, when to use real classes and when to do a mix of these. And I am still learning. And after you decide that you need a mock, the documentation for EasyMock is a bit disorganized and hard to understand the first and second time you read it. I guess that after 3 days of using EasyMock and re-reading the documentation I can say that I have understood most of what they are saying.
But the best thing that TDD has done is make me think more on how my classes are related and how they can be decoupled to make my design easier to understand, more elegant and better. I started testing one class and it was a mess. The class had only two public methods and many private ones. It had private attributes which where other classes and it called them back and forth… I had no idea how to test this class. But the problem was my design, not my testing capabilities. I divided the class into two/three different classes which collaborated with each other, and these classes all had public methods that could be tested easily. Furthermore, I could test the main class using mocked collaborators, so that the test failed ONLY if there was a problem in the class itself, and not in the collaborators. I think this was the real gain from doing TDD.
So even if you are not going to do TDD all the time, you should at least try it for a month or two (and do it as far away from a deadline as you can). It is very hard, requires a lot of discipline and it does feel that you are doing things slower. But you are also doing them better. And sometimes (not always) that counts.