Posted by Anders
Fri, 14 Sep 2007 15:11:00 GMT
When JUnit 4.1 was released last year, they added a nice feature that has gone mostly unnoticed.
RSpec envy
Consider this archetypical RSpec example in Ruby. One class, Stack, being tested in two different scenarios (empty and non-empty):
describe Stack, " (empty)" do
before(:each) do
@stack = Stack.new
end
it "should have zero size" do
@stack.size.should == 0
end
# ...
end
describe Stack, " (non-empty)" do
before(:each) do
@stack = Stack.new
@stack.push 'x'
end
it "should have size greater than zero" do
@stack.size.should > 0
end
# ...
end
Doing the same thing in JUnit would require us to either create two different classes, which makes our tests hard to follow, or to abandon the “before”-methods and initializing at the start of each test method. Other tools, like JDave, solve this by having an inner class for each scenario, but for various reasons JDave isn’t the solution for me.
Enclosed to the rescue
When browsing the JUnit source code, my colleague Rickard stumbled on the org.junit.runners.Enclosed class. Apparently it’s been part of JUnit since 4.1 released in 2006. Enclosed is a test runner that runs all the inner classes of a class as tests. It works perfectly within IntelliJ and other tools. Now you can have Rspec-style testing in JUnit, almost. Behold its goodness:
@RunWith(org.junit.runners.Enclosed.class)
public class StackTest {
public static class EmptyStack {
private Stack stack;
@Before
public void before() {
stack = new Stack();
}
@Test
public void shouldHaveZeroSize() {
assertEquals(0, stack.size());
}
// ...
}
public static class NonEmptyStack {
private Stack stack;
@Before
public void before() {
stack = new Stack();
stack.push("x");
}
@Test
public void shouldHaveSizeGreaterThanZero() {
assertTrue(stack.size() > 0);
}
// ...
}
}
Posted in Java, Programming | Tags bdd, jdave, junit, rspec, testing | 2 comments
Posted by Anders
Mon, 14 May 2007 20:34:00 GMT
A conversation between a colleague and me, earlier this year:
—But we know we’re going to need X later, so why not write support for it now?
—Yeah, but we don’t need it now.
—That sounds a bit too “Extreme Programming”.
—It is Extreme Programming!
Sometimes I forget that things I take for granted is foreign for others. Why would anyone want to write code now if we don’t need it this very moment?
Hearing about Extreme Programming (XP) is rare these days. Even if XP isn’t a term I would use to describe what I do, or even what try or want to do any more, its ideas has deeply affected the way I work. I write test-driven. I practice refactoring. I write minimal code, since I believe it’s the most future-proof way to write code (which superficially looks like a paradox). Maybe I’m avoiding the term XP just to stay out of trouble. Either way, I was a bit surprised to hear someone else describe what I did as XP (and as something of an accusation, even).
But XP has also simply fallen out of fashion, and I can’t honestly say that I’m unaffected by that. Today people talk about Agile, or Scrum, if they talk at all about methods.
At work we loosely follow Scrum. While I believe Scrum to be a well thought out (and tried out) method, which we would benefit even more from by following closer, I can’t shake the feeling that it’s like XP with the controversial parts taken out. It steers clear of a lot of things that could be interpreted as “telling people how to do their work”, that still are essential for creating working software. But given how hard it can be to lift teams from complete chaos into only some level of organization, I guess we won’t see any widespread success of methods that expect experienced programmers to re-learn how they do their work.
I don’t know if that’s a bad thing or a good thing.
Posted in Programming | Tags methodology, scrum, testing, xp | 1 comment
Posted by Anders
Sun, 15 Apr 2007 10:07:00 GMT
When I first tried RSpec it felt like a good tool that forced you to write your tests in a form that’s very close to what’s considered best practice. There are a lot of ways to abuse Test::Unit or JUnit, but if you know what you’re doing you’re usually still close. RSpec was good enough for me to change to it, but didn’t feel like a big deal.
But after some time with RSpec I’m now writing a lot tests in Java again. What I realize is how hard it is to organize tests well in JUnit. The tool is fighting me all the way, you just can’t make simple tests easily. If you want to take full advantage of the setUp() methods you have to create a lot of classes. This quickly makes it hard to get an overview over your tests. It just can’t be compared to RSpec’s “context”. I believe JUnit’s way of having exactly one setUp() per class is the problem. Maybe some way of allowing multiple setUp() would be possible.
There are a lot of other differences between RSpec and JUnit, the conditions for example (assertTrue vs. should_eat_cake) and the naming of the test cases. But still the organization of the tests make a big difference. There’s nothing for Java that really does that today. Test NG does an attempt, but at the cost of a little more complexity. But there’s nothing preventing it from being done.
Posted in Ruby, Java, Programming | Tags junit, rspec, testing | 1 comment
Posted by Anders
Mon, 09 Apr 2007 15:20:00 GMT
I was going to use ActiveRecord for some simple storage in a small application I’m hacking on. Since ActiveRecord itself has support for lots of databases I figured that it didn’t matter which database I used for testing1.
In Java I would have used Hypersonic, or some other self-contained in-memory database, for this. Looking around in Rails land, you find that most people use Rails’ testing features and run their tests against a separate instance of their production database, usually MySQL. Other people use Sqlite3, which seems to be the simplest database around.
Since I don’t have a production database (and generally dislike MySQL2), I looked at Sqlite. First of all, it requires Sqlite itself to be installed. In OS X this is already done, but it will be a problem elsewhere. Then there’s a confusing selection of different gems with drivers. But once you get the right one installed, it seems to work fine.
Once I started working with it, I ran into a problem. Every time something is wrong with the database structure, no matter if it’s the whole database missing or just a single column misspelled, I get the same error:
`table_structure': ActiveRecord::StatementInvalid (ActiveRecord::StatementInvalid)
Since I was changing the database structure a lot, I got this all the time. Don’t know if this is Sqlite, the driver, ActiveRecord or me that’s to blame, but it wasn’t very practical.
Since my patience is very short, I simply dropped the database storage feature from my app. :) But there seems to be two issues here:
- There is no self-contained, gem-installed database for Ruby
- The error handling in Sqlite, or something on the way to Sqlite, isn’t very good
I now hope that someone will tell me what an idiot I am and that I should use some other driver, or some other database.
1 I’m using RSpec, which is the best testing framework since sliced bread.
2 Bleh.
Update: By enabling debug logging in ActiveRecord you’re supposed to get more information out of it. I’ll try that the next time I work on it.
Posted in Ruby, Programming | Tags databases, testing | no comments
Posted by Anders
Thu, 07 Dec 2006 20:35:00 GMT
Together with my colleague Rickard Bäckman I recently led a workshop on Unit Testing of existing code.
Earlier this year our department was on a course on Unit Testing held by Citerus1. To follow up on that it was decided that we would do something on our own. Using tests in simple example code is one thing, but faced with our existing complex code-base it’s much harder to do it.
While I have helped many colleagues with various Unit Testing problems over the years I’ve never tried to teach it in any organized form. We figured that a workshop would be the most effective way for everyone to learn some new techniques. The format of the Citerus course would be a good fit.
I had already gathered a few examples where we had run into testing problems with our code. So I gathered those and added a few small constructed code examples to showcase interesting problems. These are the problems that they were asked to add Unit Tests to:
- Code that uses external library with lots of interfaces
(Hibernate)
- Code that uses external library with concrete classes (Apache
Lucene)
- Time in different forms (
System.currentTimeMillis(), Thread.sleep())
Using all the laptops we could find we had everyone form pairs and start working on the problems, while we hovered around them and answered questions. Sometimes we only had to confirm their ideas, other time we had to subtly (or not) suggest alternative solutions. In the end we managed to have all the pairs finish with all but one task at almost the same time.
We then ended it with going through the tasks, letting one pair show
their solution, and having a discussion around them. (My skills in
moderating discussions probably need some more practice, but I think
it worked out fine). This was also where we introduced alternative
solutions to the first problem using JMock and EasyMock.
As a conclusion I believe the workshop format was a success. There is
no other way that we could have gotten every programmer in the
department to both experience all of those problems and then
first-handedly implement a solution. The next time they face a problem
like that they will know at least one solution.
1 They’re really good, I can recommend their courses.
Posted in Java, Programming | Tags testing | 4 comments