Archive for the ‘theory’ tag
JUnit Theories: First Thoughts
One of my favourite additions to JUnit 4.4 was the @Theory annotation which allows us to write parameterised tests rather than having to recreate the same test multiple times with different data values or creating one test and iterating through our own collection of data values.
Previously, as far as I'm aware, it was only possible to parameterise tests by using the TestNG library which has some nice ideas around grouping tests but had horrible reporting the last time I used it.
To create parameterisable tests using Theories we need to write some code like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import org.junit.Test; import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; import org.junit.runner.RunWith; @RunWith(Theories.class) public class SomeTest { @Theory public void testTheNewTheoriesStuff(int value) { // test which involves int value } public static @DataPoints int[] values = {1,2,3,4,5}; } |
The 'testTheNewTheoriesStuff' Theory is then executed with each of the values defined in the values array decorated with the @DataPoints annotation.
The error message reported for a failure is reasonably good and makes it quite easy to figure out which one of the data points causes the problem.
An example error message for an assertion which failed inside a theory might look like this:
org.junit.experimental.theories.internal.ParameterizedAssertionError: testTheNewTheoriesStuff(values[1])
It's 0 indexed so this error message tells us that there was an error when running the theory with the 2nd data point, therefore allowing us to go and work out why that's the case and fix it.
This approach is actually particularly useful for testing the scope in which classes we pull from a dependency injection container are available from in our application.
Another potential use for this would be to test the edge cases of our classes – perhaps this would work best if we can randomise the data it uses.
This seems to be more the approach Microsoft are taking with the the Pex framework, a similar idea in the .NET space.
Learning theory first
I’ve always been the type of person who only gets the motivation to do something if there is some useful practical reason for doing so. It therefore probably doesn’t come as much of a surprise that I hated the majority of my mostly theoretical computer science degree.
I was talking to one of my colleagues last week and came out of the conversation convinced that the desire to know the theory behind concepts is amplified when you actually get to see it in action in a real life system.
My prime example is multi threading and concurrency. At university we had to write a program to calculate e to 500 decimal places using multi threading. In my mind this exercise was completely pointless, and I don’t think I came out of it any wiser with regards to threading.
Contrast that to the project I’m working on now where the main window of our application was freezing up due to an expensive operation being run on the UI thread. The solution of course was to execute the expensive operation on a background thread.
Although I know this is a fairly trivial example, it did provide a real life situation where threading was required. As a result of this I have become much more interested in the specifics of threading and the potential problems that can arise when doing so.
It would probably actually prove more useful to see the concepts in action in a real life system before being taught the detailed theory behind how it all fits together. For me at least when I’m learning about something I like to have a reference point and having seen the concept in action would provide this.
It seems obvious to me therefore that studying for a degree after having first done a few years in industry would probably lead to you having a much richer learning experience and a much improved understanding. Not that I expect that to catch on!