Wednesday, October 28, 2009

Abstract Class Smell

PLEASE SEE THE UPDATES BELOW, I didn't realize that my issue was with the Template Method Pattern.
------------------------------------------------------------------------
Original Post:

I coded up a smell today, I had an abstract class who's public methods were calling the abstract implementations. Here's kind of what it looked like:

public abstract class Foo {
  abstract SomeObj foo();
  abstract SomeObj bar();
  public void somethingFooDoes() {
      SomeObj a = foo();
      SomeObj b = bar();
     //do some stuff with a + b
  }
}

How did I get here you might ask. Well, there were going to be two implementations of Foo, a prod implementation and a sandbox implementation. I started off with Foo as an interface and began coding up the Prod + Sandbox impls. It turned out that the prod and sandbox implementations had really similar structures. So, I made Foo an abstract class and moved the common stuff in there. A few more refactorings and Foo ended up looking like it does above. It then dawned on me, Foo was really using different strategies to get at the SomeObjs, I refactored to the strategy pattern:

public class Foo {
  private final SomeObjProducer someObjProducer;
  public Foo(SomeObjProducer someObjProducer) {
     this.someObjProducer = someObjProducer;
  }
  public void somethingFooDoes() {
      SomeObj a = someObjProducer.foo();
      SomeObj b = someObjProducer.bar();
     //do some stuff with a + b
  }
}

Now Foo has become concrete and is configurable with the different strategies for producing SomeObjs. To me this code is much more flexible and it now has collaborators. Where in the Abstract implementation it was kind of collaborating with itself (yuck!)

What's the moral of the story? If you have an abstract class and you find yourself calling abstract methods in your concrete methods (whoa that's a mouthful) consider refactoring to the strategy pattern.

UPDATE: a co-worker correctly pointed out that the first code snippet of Foo was the Template Method Pattern. Maybe it's too broad a statement, but it seems that anytime you have a template method pattern you could refactor it into the strategy pattern. Taking your inheritance based code and refactoring it into composition based code. Context is king, but these days I certainly favor composition over inheritance.

UPDATE AGAIN: I received some good complaints regarding my code sample.

Imagine using the more standard Game example from wikipedia (but simplified for brevity)

public abstract class Game {

 public void playOneGame() {
  while(!endOfGame()) {
   makePlay();
  }
 }

 public abstract boolean endOfGame();
 public abstract void makePlay();
}
This could be refactored to use composition instead of inheritance, where Game is now an interface.
public class GamePlayer {
 private Game game;
 public GamePlayer(Game game) {
  this.game = game;
 }

 public void playOneGame() {
  while(!game.endOfGame()) {
   game.makePlay();
  }
 }
}

Tuesday, October 13, 2009

Hollywood Dilemma

At sdtconf over the weekend I led an open spaces discussion about the Hollywood Principle and testing. Venkat Subramaniam took the time to post a really thoughtful article about it. I'll quote it below, but it is worth reading!

The discussion was around the cost and reason for inverting control, Venkat provided a toy problem which we twisted for our own purposes, we modeled a paper boy. The paper boy requests payment from a customer and the customer can either pay or stiff the paper boy.

I argued for the following:

public class PaperBoy {
  public void collectPayments(List customers) {
    for(Customer customer : customers) {
      customer.getPayment(this, 200);
    }
  }
  //...
And the test
Customer customer = mock(Customer.class);
PaperBoy paperBoy = new PaperBoy();
//set up a payment to be collected;
paperBoy.collectPayments(customer);
verify(customer).getPayment(paperBoy,$$$);
and the Customer
public class Customer {
  public void getPayment(PaperBoy paperBoy, int amount) {
    if (hasNoMoney || doesNotCareToPay)
      paperBoy.stiff(this);
    else {
      deductMoney(amount);
      paperBoy.acceptPayment(this, amount);
    }
  }
  //...
and the Test
Customer customer = new Customer(someMoney and a bad attitude);
PaperBoy paperBoy = mock(PaperBoy.class);
customer.getPayment(paperBoy,$$$);
verify(paperBoy).stiff(customer);
etc. for the other cases. Venkat points out some issues with this kind of implementation that I'd like to address:
Problem 1. The above code has some unnecessary coupling and bi-directional relationship. The Customer depends on PaperBoy. That is a coupling that I would seriously question.

Problem 2. The unit test is now made to do more. It has to create a mock of the PaperBoy. Even if you tell me it is not much code, a single line of code that is not absolutely needed is a lot of code IMHO. You don't have to maintain code that you do not write.

Problem 3. Are you really stiffing the PaperBoy? Who decides that? Can a paperboy decide that under very hard economic conditions, a loyal customer may be deserves a break? I have no problem the customer deciding to pay or not, but if that is stiffing or not is for the paperboy to decide IMO.

I'd like to address problem 3 first. The paper boy can still cut the guy a break, he just does it in his stiff method. Or maybe it shouldn't be a stiff method, maybe it should be an iWontPayMethod().

Problem 1. I really don't like the coupling! The coupling would be limited if the Customer was talking to a debt collector interface, and the PaperBoy was talking to a Payee(uhg) interface. But it's still a little smelly. I don't fundamentally see a problem with the bi-directional relationship, but maybe that's just because I haven't coded too much with bi-directional relationships (and maybe there's a good reason for that).

Problem 2. Let's take a look at Venkat's code + what some tests would look like.

public class PaperBoy {
  public void collectPayments(List customers) {
    for(Customer customer : customers) {
      int payment = customer.getPayment(200);
      if (payment > 0)
        acceptPayment(customer, payment);
      else
        stiff(customer);
    }
  }
  //...

public class Customer
{
  public int getPayment(int amount) {
    if (hasNoMoney || doesNotCareToPay)
      return 0;
    else {
      deductMoney(amount);
      return amount;
    }
  }
  //...
The Customer Tests:
Customer customer = new Customer(someMoney and a bad attitude);
assertEquals(0,customer.getPayment($$$);
So Venkat is correct in this example the mocks add 2 extra lines per test which isn't great. But that's not the whole story. Let's take a look at the PaperBoy tests.
Customer customer = new Customer(someMoney and a bad attitude);
PaperBoy paperBoy = new PaperBoy();
//set up a payment to be collected, let's assume this is one line
paperBoy.collectPayments(customer);
assertTrue(paperBoy.wasStiffedBy(customer);

Customer customer = new Customer(someMoney and a good attitude);
PaperBoy paperBoy = new PaperBoy();
//set up a payment to be collected, let's assume this is one line
paperBoy.collectPayments(customer);
assertTrue(paperBoy.collectedPaymentFrom(customer, $$$);
I have two issues with the PaperBoy tests:
  1. There is an extra test needed, which in terms of maintence is not such a good thing.
  2. The PaperBoy tests are highly coupled to the implementation of the Customer. This means anytime you change some behavior of the Customer you might have to change your PaperBoy test, not such a big problem for the 2 tests, but if there are 50? if there are 100? that can be bad news.

It's not clear to me that inverting the control is the "right" thing to do, but I think if you're careful (and you want 100% unit test coverage), inverting the control and using mocks can help you cut down on test complexity and test maintenance, so... mock-on?

Thanks everyone who participated in the discussions!

Tuesday, September 22, 2009

Contract Tests

I had a post almost a year ago Hard Contracts vs Soft Contracts that was I reminded of when I came across this post on Testing with generic abstract classes. At our company we've been using the abstract test case pattern for a while, but have been struggling with naming... why not just call it FooAbstractTest you ask? Because, well, our build looks for classes that are named Foo*Test* in our test package and tries to run the abstract test cases and it breaks our build. So like any good software engineer instead of solving the problem, we just tried to work around it (sigh).

Anyway, we were struggling for a good naming convention, the best we could come up with was FooBase (terrible) but then as I mentioned I came across Mark's post, which in turn lead me to this wonderful page on c2 http://c2.com/cgi-bin/wiki?AbstractTestCases. The first line says it all, "Contract Tests" and really I knew it all along. I had been thinking of them in terms of hard contracts vs. soft contracts. So now I can feel good about myself and continue being a good software engineer, I have a better name, FooContract.

UPDATE - If you followed the link to the c2 page, you'll see that J. B. Rainsberger is referenced all over the place. Well he just republished his initial thoughts on the Contract Test. Also, if it wasn't clear, I was being very tongue in cheek about not fixing our build, we should do it, but finding a good name for these kinds of tests is also important.

Thursday, August 27, 2009

Builder Pattern in Clojure

We've been working steadily on our toy traffic simulator and doing TDD along the way. Of course a major concept in a traffic simulator is a car, so we of course have a car struct + cars have some behavior patterns so we also have a behavior struct. They look like:

(defstruct behavior :accel-dist :decel-dist)
(defstruct car :name :position :length :speed :behavior)

So to construct a valid car you need to do something like:

(struct car :a 1 1 1 (struct behavior 10 5)))

Yikes, we constantly wanted cars for our tests and constructing a car like that was often more code than the real stuff we wanted to test. So, we made a bunch of convenience methods (object mother type stuff), like:

(defn slow-car [name position]
 (struct car name position 1 1 (struct behavior 10 5)))

(defn car-with-speed-position [speed position]
 (struct car :a position 1 speed (struct behavior 10 5)))

Suddenly we started creating lots of car-with-* methods. We got annoyed and accidentally started implementing the builder pattern.

(defn default-car []
 (struct car :a 1 1 1 (struct behavior 10 5)))

(defn car-with 
 ([key value]
  (assoc (default-car) key value))
 ([key1 value1 key2 value2]
  (assoc (car-with key1 value1) key2 value2)))

Ignore the total ugliness of the car-with function for a moment, this let us do things like:

(def a-car (car-with :speed 1 :position 4))

as opposed to:

(def a-car (car-with-speed-position 1 4))

Our new version, was not only easier to read, and didn't make us create new methods for each different thing we wanted to do, but hey, that looks really similar to the builder pattern. Now I'm sure there are better ways to implement car-with, but it works for now.

Wednesday, August 26, 2009

Null once again

InfoQ has a nice talk by Tony Hoare, Null References: The Billion Dollar Mistake. I've been in a few arguments in that past that languages would be much better without null, so it's nice to hear someone much smarter than myself, who also happens to have invented the null reference regret their existence. But he doesn't feel as bad as he thinks the C language designers should feel, because he says, they allowed the for the buffer overflow by abusing the get routine. And that allowed for viruses, which have cost industry much more than his billion dollar mistake. He's tough on the language designers (and himself): "Language designers should be responsible for the mistakes programmers make". Thanks Tony, for giving me someone to blame when I muck things up :)

Saturday, August 1, 2009

Returing Null... again

so... thinking more about returning null. I'm thinkin' returning null is allowing you to return a second type from a method. And a null pointer exception is equivalent to a class cast exception. AND a null check if (foo == null) is the same as an instance of check.

nulls are syntactic sugar for a type! I refuse to think of them as values for references any longer. They are types, returning them from functions is returning multiple types from a function (not in a polymorphic way, but in a type system abusing way) and null checks are instance checks.

Returning Null

I've always had a problem with returning null from a method. And I was reminded of this when reading a post at Misko Hevery's blog about how to think about OO

I think returning null is a problematic, it's often abused as a way to have two different return types from one method. A quick googling of "returning null" has the suggestion of returning a null object implementation of your return type. Returning a Null Object is appropriate in some cases, but not when you need to signal to your client two different things. Misko's code refactoring show's an example of this. He refactors some login code (I really like the steps he took btw) down to something like:

  Cookie login(Ldap ldap) {
    if ( ldap.auth(user, password) )
      return new Cookie(user);
    return null;
  }

When I read this code I see two things (structurally that is)

  1. If authentication succeeds then notify the client of the successful authentication with a new Cookie
  2. If authentication fails notify the client by returning null

What could a client of this method look like?

  public void authenticateUser(User user) {
     Cookie userCookie = user.login(ldap);
     if (userCookie == null) {
           //notify someone that auth failed
     } eles {
           //register them as logged in
     }
  }

We're doing the same work twice in each place, but with slightly different syntax, each place we need to check if login failed or not. What if instead we used IoC / "Tell Don't Ask" / "Hollywood Principle"

  Cookie login(Ldap ldap, AuthenticationRegistry authenticationRegistry) {
    if ( ldap.auth(user, password) )
      authenticationRegistry.authSucceeded(new Cookie(user));
    authenticationRegistry.authFailed(user);
  }

and the client

  public void authenticateUser(User user) {
     user.login(ldap,this);
  }

  public void authSucceeded(Cookie cookie) {
     //register them as logged in
  }

  public void authFailed(User user) {
     //register them as auth failed
  }

This new code is a little more complicated, but I think it is clearer, and more straight forward to implement. Now we have two entities that are communicating with each-other and we've defined the way in which they are communicating. Again I liked Misko's refactorings, I'd just take it one step further. It's all definitely arguable, but I think if you're ever in a situation where you want to be returning two types of data from a method using IoC is the way to go.

Tuesday, July 21, 2009

Clojure + Bowling Kata

Just the other day (yesterday) Uncle Bob had a post about Learning Clojure. He implemented a bowling scoring kata. So Dan P. and I decided to try it ourselves, but since we're from Boston we implemented candle pin bowling rules:

As we were talking through designs for this, and as we talked about scoring frames, we realized that there were three cases:

  1. Strike – score the first ball, plus the next two ‘bonus’ balls, then remove the first ball (the strike) from the list, then continue scoring.
  2. Spare – score the first two balls, plus the next ‘bonus’ ball, then remove the first two balls (the spare) from the list, then continue scoring.
  3. No-mark – score all three balls in the frame, then remove them from the list, then continue scoring. (Remember: candlepin!)
In all these cases you want to score three balls, the only difference was in how many balls you remove from the list before you continue scoring (i.e., how many balls were in the frame you are removing from the yet-to-be-scored list). So this is what we came up with: http://github.com/zdsbs/candlepin-bowling/tree/master
(ns scorecard)

(defn third [rolls]
    (first (next (next rolls))))

(defn first-two [rolls]
    (+ (first rolls) (second rolls)))

(defn strike? [rolls]
    (= 10 (first rolls)))

(defn spare? [rolls]
    (= 10 (first-two rolls)))

(defn remove-strike [rolls]
    (rest rolls))

(defn remove-spare [rolls]
    (rest (rest rolls)))

(defn remove-normal-frame [rolls]
    (rest (rest (rest rolls))))

(defn remove-frame [rolls]
        (if (strike? rolls)
            (remove-strike rolls)
            (if (spare? rolls)
                (remove-spare rolls)
                (remove-normal-frame rolls))))

(defn score [input-rolls]
    (loop [rolls input-rolls score 0 frame-counter 0]
        (if (or (empty? rolls) (= 10 frame-counter))
            score
            (recur 
                (remove-frame rolls) 
                (+ score (first rolls) (second rolls) (third rolls)) (inc frame-counter)))))

And the tests:

(ns scorecard-test
    (:use clojure.contrib.test-is 
        scorecard))

(deftest test-third
    (is (= 3 (third [1 2 3 4]))))

(deftest test-first-two
    (is (= 3 (first-two [1 2 3]))))

(deftest test-remove-frame
    (is (= [3 4 5] (remove-frame [0 1 2 3 4 5])))
    (is (= [3 4] (remove-frame [10 3 4])))
    (is (= [5] (remove-frame [6 4 5]))))

(deftest test-remvo-two-frames
    (is (= [] 
        (remove-frame 
            (remove-frame [0 1 2 0 0 0])))))

(deftest test-scores
    (is (= 0 (score [])))
    (is (= 6 (score [1 2 3])))
    (is (= 15 (score [1 2 3 4 5 0])))
    (is (= 19 (score [10 1 2 3])))
    (is (= 17 (score [5 5 1 2 3])))
    (is (= 300 (score [10 10 10 10 10 10 10 10 10 10 10 10])))
    (is (= 19 (score [5 5 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 ])))
    (is (= 21 (score [10 1 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 ]))))

Also check out:
Stuart Halloway's implementation. Besides just an implementation, he has a great discussion on how to approach the problem in a functional way. (his implementation is much nicer than this one)
Uncle Bob's son over at 8th light also wrote up an implementation

Sunday, July 19, 2009

Git Commands Part I

I'm always forgetting a very useful git command, so I'm posting it here in the hopes that: a) writing it down will help me remember and b) if I forget again, at least I can just goto my blog.

git add -u
(if you're like me and you rename or delete files without calling git rm git add -u takes care of staging the changes)

and thank you Stack Overflow: git rm multiple files that have already been deleted from disk

Oh and if you're pushing a Java project into a git repository, the .git/info/exclude file is very useful to ignore all the generated .class files.

Wednesday, July 15, 2009

Block Editing in Eclipse Galileo

Eclipse now has block editing hooray!

Ummm, what's the key binding for it? There's nothing in eclipse help, nothing in cmd-shift L, too many of my google searches took me to a crappy reddit page which doesn't tell you what the key binding is. Eventually someone decided to be helpful with this post. The key binding on OS X is cmd-alt-a

Anyway, hooray for block editing. Boo for wasting time looking for the keybinding, I hope this saves someone some time.

Wednesday, July 8, 2009

Hawthorne Effect

Apparently my post on measuring things was really about the Hawthorne Effect. Which in brief is: The simple action of measuring peoples productivity will increase their productivity. If you read that article though, there are lots and lots of criticism, but I prefer the BS approach, it's a cool idea, let's run with it!

I've been enjoying trying the Pomodoro Technique and have noticed a change in my productivity. Honestly, I'm not following it strictly, I haven't even read much of the website, but I did download a little app and I'm measuring tasks. I'm guessing one of two things is a result of the change in productivity:

  1. The Hawthorne Effect has some merit and by measuring my tasks, and measuring my goofing off, I'm improving the amount of time I'm staying on task
  2. There's something about a change in process that makes you notice inefficiencies in the way you do things

For the time being I'm going to assume #1 is true :) and that the Hawthorne Effect probably isn't valid in a general sense. You can always game metrics / measurements etc. etc. But on a personal level, if the metric you're measuring is of value to you, if you don't game your own personal game, then I think those metrics do have value and the Hawthorne Effect does apply. Or at least that's the BS I'm slinging today.

This post took 30 minutes to write, I'm now taking a 5 minute break.

Tuesday, June 30, 2009

Corey Haines Visit to Icosystem

Friday the 26th was a fun day at Icosystem. Through a random chain of events Corey Haines stopped by as part of his pair programming tour. I had the opportunity to pair with him for a few hours and talk a lot of shop.

Pairing is always a fun activity and it's really fun to pair with someone you've never paired with before. Not only do you get some work done, but you get a nice view into some else's coding process, asthetic, and you always learn a few new tricks. I picked up two things from Corey that I'll be trying out:

  • When doing a refactoring, only allowing one test to be failing at a time. It's hard to do, but I liked how it felt.
  • The pomodoro technique - Work for 25 min, take a 5 min break, use a timer. I installed Pomodoro 0.24 for OS X. It puts a nice little timer in my application (what is that thing called?) bar. Maybe it's a great process or maybe it's just something new, but so far it's a nice tool and is keeping me focused. Another nice feature of it is you note what the task is you're working on. I don't know about you but I have to fill out timesheets for billing, any tool that helps with that is great!
I'm sure there were other things I picked up but they're not coming to me right now.

Because of Corey's visit I met a bunch of the Ruby folk in the Boston area. It really made me realize how lacking the Java community is in having a... community. I might have to start going to the bostonrb meetings just to hang out with folks who like to talk about coding. Maybe they won't mind having a Java hacker in their midst :P

Writing this post took me, 27 minutes, I'm terrible at the Pomodoro technique

Tuesday, June 23, 2009

The Downfall of Agile Hitler

Who knew Agile could be so hilarious: The Downfall of Agile Hitler

Also a little less funny but also great: Hitler Does Unit Testing

Friday, June 12, 2009

Learning Clojure - Calling Clojure From Java

Last night, we played with some of Clojure's interop with Java. We tried out with great success Jay Fields little example. Next up was compiling Clojure to Java class files (this was much trickier).

The documentation is pretty good and can be found at: http://clojure.org/compilation and under the (gen-class) API entry. There are two tricky bits, 1) the extra 'this' arg 2) the classes compilation directory.

But first the code sample:


(ns printer
  (:gen-class
   :methods [[printString [String] void]]
  )
)

(defn -printString [this arg]
        (println arg))

:gen-class is the directive to the clojure compiler that it should compile this .clj file into a java class. The :methods section allows us to define methods, we're defining the printString method which is a void and takes a String as it's arg.

The clojure function must begin with a '-' and then there's the 'this' arg. It took a little bit to find the 'this' gem in the documentation on the compilation entry (seriously, who reads everything before they start experimenting)

hasNext and next are implementations of methods in the Iterator interface. While the methods take no args, the implementation functions for instance methods will always take an additional first arg corresponding to the object the method is called upon, called by convention 'this' here. Note how the state can be obtained using an ordinary Java field access.

So no matter what method you expose to java it will alway have at least one arg which is the instance of the object. I can't tell you how many times we were so confused why we were getting wrong number of arg error messages when first trying this out.

Now to compile:
java -cp clojure.jar:. clojure.main -r
user=>(compile 'printer)
java.lang.RuntimeException: java.lang.ClassNotFoundException: printer$_printString__4 (NO_SOURCE_FILE:0)

This is because you didn't create 'classes' directory and add it to your classpath, it's exactly what the error says right?
create the directory, add it to your class path and try again
java -cp clojure.jar:.:classes clojure.main -r
user=>(compile 'printer)
printer

Great, hopefully there are no more exceptions, try javap on printer.class you should see something like:

zacharyshaw$ javap classes/printer
public class printer extends java.lang.Object{
    public static {};
    public printer();
    public java.lang.Object clone();
    public java.lang.String toString();
    public boolean equals(java.lang.Object);
    public int hashCode();
    public void printString(java.lang.String);
    public static void main(java.lang.String[]);
}

Now you should be all set to call through to your printer.class

public class Foo {
 public static void main(String[] args) {
  new printer().printString("hello world");
 }
}

There's loads of different things you can do, like implementing interfaces, extending classes etc. I'm really looking forward to seeing how I can integrate clojure into one of my projects (only where it makes sense of course :P )

Monday, June 8, 2009

Regurgitation

  • Mark Levinson has a nice blog post on agile mailing lists, it's a good collection of interesting lists.
  • Started a new project and am using infinitest it's great!
    I love how hard-core it makes testing. When I suggested to a few co-workers that they install it, I started getting questions: "so how do I turn off those compilation errors it creates?" Answer: "fix the tests or turn off the plugin"
  • Kent Beck had an interesting blog post To Test or Not to Test? That's a Good Question.
    I really recommend checking out his blog, the content is great (I think I'll have to suck it up soon and try out junitmax, maybe for my next project)
  • My weekly Clojure learning sessions are still going strong, got my Programming Clojure book in the mail last week, it's nice to have a paper copy.
    We're working on putting penalties (in the form of delays) if you hit the direction keys too frequently. I finally feel like I'm getting a feel for the language.
  • and apparently Rich Hickey doesn't like testing: http://blog.objectmentor.com/articles/2009/06/05/rich-hickey-on-testing

Wednesday, June 3, 2009

Unit Testing in a Different Language Than Actual Code

I've been at talks before where it is encouraged if you're interested in learning a new language to write your unit tests in that language, even though your source code is in another language. For example, if your code base is in Java the suggestion is that you should write your unit tests in Groovy, or Scala, or something else that is awesome.

I understand certain pragmatic reasons for this. Sometimes, it's hard to find the time to learn a new language, and it's less risky to experiment with a new language in your unit tests than in your production code.

But if you're trying to practice TDD (which I think is a pretty good idea) writing tests in a language that differs from your source code is risky. TDD allows you to explore and try out your new APIs like the clients of those object would. It's not only about making sure the code as you envision works, it's a methodology for writing new code. But if you're using a different language to unit test your code, you are loosing out on that exploratory capability. Sure you're using the API, but you're not using it in any way that resembles how your clients would use it.

It's a different story when writing integration / acceptance tests. These tests are at a higher level and are more about general application behavior than specific APIs. I think it's very appropriate in these cases to use a Groovy or a Scala or a DSL or a framework (e.g. selenium).

Sunday, May 10, 2009

Continuous Testing - Infinitest

If you check out the comments on configure-your-ide-to-run-your-tests-automatically there are a slew of references to Infinitest which is a continuous testing tool, which has a very similar feature list to JUnitMax, which is also free.

I got the plugin up and running on a small - medium project (387 unit-tests). My project is laid out
src/main
src/test
src/integration
Immediately I had a problem when trying out the plugin, it was running all my integration tests. After much rooting around it turns out you can add the special infinitest.filters file:

From readme.pdf of http://infinitest.googlecode.com/files/infinitest-4.0.3.zip

You may have tests in your classpath that you don't want Infinitest to run. These tests can be filtered out by creating a file in the working directory of your project named infinitest.filters. It should contain one regular expression per line. Any class names (not file names) that match any regular expressions in that file will not be run. For example: org\.myproject\.acceptance\..* .*\$.* will filter out all the classes in the com.myproject.acceptance package, and any inner classes (which always contain a $).

I added my filters and everything seems to work. Infinitest doesn't run all your tests, just a subset of them (it does some voodoo to look for dependencies), it tells you how many it ran, but it doesn't tell you which ones it ran... which is fine (I guess) but the anal part of me really wants more insight into what tests it's running. For example, I modified a class, Infinitest informed me that it ran 51 tests, but really which ones did it run... I just really want to know!

Also another interesting tidbit, from http://www.benrady.com/2009/04/comparing-infinitest-and-junitmax.html

The other function that I think a CT runner needs to do is test selection. If you're doing TDD, you're probably running a single test every time you make a change. If you're doing CI, you're running all your tests on a semi regular basis. Somewhere in the middle of these two approaches is a good balance of feedback quality vs speed. I think that's where CT tools should be focused. Infinitest uses dependency analysis to determine what tests need to be run for a given change.

Infinitest isn't particularly speedy, all my unit tests took .6 seconds to run, and the 51 Infinitest chose to run took 3 seconds. So maybe it's important for Infinitest to trim what it's running, but if your unit tests are fast to run than it's more of an Infinitest implementation detail vs a real time to run issue.

Anyway, I can't wait to start trying this tool as part of my workflow.

Friday, May 8, 2009

Running Tests On IDE Save

Misko Hevery just put up a blog post describing how to configure Eclipse to run your test suite after every save. It doesn't seem like a bad idea, and I'm definitely going to try it out, but even with a test suite that runs in under a second, I wonder how annoying it would be. I'm an obsessive saver, I can't seem to help myself. Even if I'm only looking at a file I need to format it then save it... how would that be if it took a second to do.

"Here is a common scenario. Your tests are green and you start doing whole bunch of refactorings which you think are trivial and safe. When you are done you run the tests and it is broken. The problem is that you did ten little things and you don’t know which of the ten things you did broke the code. The solution is to run the test more often, but we just forget."

I'm not sure this really is a common scenario I run into, but it's an intriguing idea to run tests on save. I really believe that a change in process effects your product. Run on save would certainly change my process, but how would it change my product?

Misko's post reminded me of JUnit Max Kent Beck's Eclipse Plugin, which has the similar feature of run tests on save. There are a bunch of interesting features, like displaying test failures like compilation failures, and keeping JUnit unobtrusive. There is one un-interesting feature, it's in beta, and has a monthly subscription. I'd love to try it, even pay for a demo (I think :P), but knowing myself, whenever I subscribe to something, I never unsubscribe, even if I'm not using the software or reading the magazine. So I'll have to wait on trying out JUnit Max.

Sunday, April 19, 2009

Pair Programming - What makes programming different?

Pair programming is a pretty big movement in the software world and advocates of pair programming often believe all software should be worked on by two people. The question: "Why practice pair programming?", has lots of really well thought out answers. But after some google searching I have yet to read someone talking about what makes programming different.

The wikipedia entry on Pair Programming says nothing about pairing in other industries / professions. Neither does the Extreme Programming entry or the C2 entry

Why did pairing emerge in computer programming? Why is there a lot of literature on pair programming, that doesn't reference other professions? Here are a few possible thoughts:

  • There are lots of professions where pairing would be as beneficial as in programming, but for what ever circumstantial reasons pairing emerged, and was squashed.
  • Pairing exists in lots of other professions, but for some reason it's not as formalized as in programming.
  • The pairing movement is just as big in other professions, but I just haven't heard about it or been able to find any information about it.
  • Pairing doesn't exist nearly to the extent as it does in computer programming because there is something fundamentally different about writing software.

I don't really know which of those thoughts I believe is true. But I am surprised that pairing seems to have emerged from programming, and it doesn't appear to have emerged for other industries. Is programming really that different from other kinds of knowledge professions?

Thursday, April 16, 2009

Shortcuts

There must be a mathematical proof out there that says, coding outside of your design / idiom will always comeback and bite you. I swear it must be true. I've been coding away on a project for a few months now. Things are really starting to come together, the light is at the end of the tunnel. There were a few places, that I took some shortcuts, hey I was in a rush, I wanted to finish up a little component before I left for the day, I was tired, it's not going to be so bad.

But doggonit each time I hit one of those shortcuts, they screwed me. Without fail they turned out to be problematic, in ways I couldn't even have imagined when writing them. And, they were way more time consuming to fix, than if I had written them correctly the first time.

I'm not talking about totally egregious shortcuts either. Some revolved around being cute or tricky or just slightly blurring tiers. But it is amazing to me how each one of the shortcuts turned out to be problematic enough to need to be fixed.

Away, there must be some mathematical proof about this, there must be.

Wednesday, April 15, 2009

Learning Clojure

Well I've started down the path of learning a new language (Clojure) the past few weeks I blame it all on going to NFJS and going to too many Stuart Halloway talks.

Learning Clojure has definitely been challenging. It seems like the total opposite from Java. Beside being a functional language, it feels like it was built to be terse. It makes heavy, heavy use of symbols, who knew the ":" could mean so much!

A friend and I have been working on a snake example (apparently, everyone writes a snake example, just google "clojure snake" there are jokes like, YACS (yet another clojure snake)). I think it took us a good 7-8 hours just to understand all the code. Destructuring was I think the hardest concept to learn.

Destructuring is also called abstract structural binding check out (let [bindings* ] exprs*) where bindings == binding-form and initial-expr. In my limited exposure destructuring is often used in (defn ([params*] body) where params == binding-form and body = expr, AND using your function is applying the initial-expr. Somehow it helped a lot to understand defn in terms of let.
For example:

user> (defn foo [a b] (+ a b)) user>(foo 1 2) 3
So in that example [a b] is your vector binding form (+ a b) is your exprs and (foo 1 2) is the application of the initial expression.

You could view the same behavior with let

user>(let [[a b][1 2]] (+ a b)) 3
Anyway, once I made this connection a lot of things started to fall into place when looking at clojure code. This might have been more obvious to me if I had read more carefully the fn special form, so I would certainly spend time looking through the special forms documentation if you're interested in learning Clojure.

Also to blame on Stuart + NFJS is I setup a github repository which will probably change drastically, but if you're interested in checking out my progress on snake.clj it's up there. We now have 2 snakes, are detecting collisions and are working on setting up a wall.

Oh running clojure is really easy, just download the clojure jar, java -cp clojure.jar clojure.lang.Repl will give you a terminal, and java -cp clojure.jar clojure.main snake.clj will let you run the snake example.

Sunday, March 22, 2009

moreUnit 1.3.3 released

MoreUnit 1.3.123 was released today! From the release notes:

  • Prefix for testmethod names is now configurable.
  • Marker in the editor can be configured via preferences
  • Bugfixes
This release makes it more JUnit 4 friendly, allowing you to configure your own testmethod name prefixes

Thursday, March 19, 2009

Corey Haines' Pair Programing Tour

Corey Haines is a "Software Journeyman" who's involved in the software craftsmanship movement. He's done a lot of programming interviews and what I think is very interesting is he's currently on a pair programming tour.

On the pair programming tour Corey goes around the country pairing with developers for a few days in exchange for food and shelter. After each stay with a developer he records a video where they talk about their experience pairing. It's really interesting stuff, and the interviews give you a lot of insight into how different shops deal with pair programming and questions of software craftsmanship.

InfoQ has a nice introduction to the tour. Just a side note it's interesting that Corey was inspired by Paul Erdos the crazy touring mathematician.

Friday, February 20, 2009

Java Broke Computer Science

So... yeah, Java broke computer science. But first some background, I'm doing agent based modeling these days, and a common thing you have 2+ nested loops. For example I'm working on a project right now where I'll be looping an outer loop somewhere in the range of 100,000+ times and an inner loop maybe 10,000 - 20,000. Suffice to say, I need to make it as fast as I can. I wrote some little tests so I could get a sense of how long it would take, just to run through the loop and do something small.

A class to do stuff with:

public class Foo {
 private int count;
 private boolean inc;

 public Foo(boolean inc) {
  this.inc = inc;
 }

 public void tick() {
  if (inc) {
   count++;
  }
 }
}

My Test:

private int outerLoop = 100000;
private int innerLoop = 10000;

@Test
public void arrays() {
 Foo[] foos = new Foo[innerLoop];
 for (int i = 0; i < innerLoop; i++) {
  boolean inc = i % 2 == 0 ? true : false;
  foos[i] = new Foo(inc);
 }

 long start = System.currentTimeMillis();
 for (int i = 0; i < outerLoop; i++) {
  for (int j = 0; j < innerLoop; j++) {
   foos[j].tick();
  }
 }
 long fin = System.currentTimeMillis();
 System.out.println("arrays took: " + (fin - start));
}

Takes on my machine in java 1.6 ~2,000 ms I'd like to point out here, that Foo[] foos will not change, so I don't care about speed of modifying a data structure, just the fastest way to iterate.

Right, iterate, what's an arrayList looklike?

@Test
public void arrayList() {
 ArrayList arrayList = new ArrayList();
 for (int i = 0; i < innerLoop; i++) {
  boolean inc = i % 2 == 0 ? true : false;
  arrayList.add(new Foo(inc));
 }
 long start = System.currentTimeMillis();
 for (int i = 0; i < outerLoop; i++) {
  for (Foo node: arrayList) {
   node.tick();
  }
 }
 long fin = System.currentTimeMillis();
 System.out.println("ArrayList took: " + (fin - start));
}

This runs in ~3000 ms

Okay the Java Iterators aren't cutting it, but what about a real linked list? not java.util.LinkedList but, Linked_list the data structure. This as far as I can figure should be ideal. All there is to iteration is pointer de-referencing. There are no lookups to find the a given index in an array, just following the pointers.

Here's my implementation:

public class LinkedListNode {
 public T data;
 public LinkedListNode next;

 public LinkedListNode(T data) {
  this.data = data;
 }
}

public class LinkedList {
 private LinkedListNode first;
 private LinkedListNode last;

 public LinkedList() {}

 public LinkedListNode first() {
  return first;
 }

 public void addToEnd(LinkedListNode linkedListNode) {
  if (first == null) {
   first = linkedListNode;
   last = linkedListNode;
  } else {
   last.next = linkedListNode;
   last = linkedListNode;
  }
 }
}

And the test:

@Test
public void linkedList() {
 LinkedList linkedList = new LinkedList();
 for (int i = 0; i < innerLoop; i++) {
  boolean inc = i % 2 == 0 ? true : false;
  linkedList.addToEnd(new LinkedListNode(new Foo(inc)));
 }

 long start = System.currentTimeMillis();
 LinkedListNode startNode = linkedList.first();
 for (int i = 0; i < outerLoop; i++) {
  LinkedListNode node = startNode;
  while (node.next != null) {
   node.data.tick();
   node = node.next;
  }
 }
 long fin = System.currentTimeMillis();
 System.out.println("linkedList took: " + (fin - start));
}

Any guesses to how this performed? try ~5500 ms Like I said Java broke computer science, they must be doing some amazing compiler optimizations, how is it that node.next is slower than foo[499]. It boggles the mind. What's the take away here? When you can use a primitive array do so?

oh, just a note, yes I know ArrayList is backed by a array, and yes I tested a java.util.LinkedList as well, and it was the worst of the bunch.

Monday, February 9, 2009

Test Data Builders

I've been meaning to post something about this for a little bit, not exactly sure what I had to add to the subject besides, "hey that's a good idea", and after about a month thinking about it I think it's safe to say I don't have much to add except for evangelism.

So without further ado, I'd suggest reading a few articles on test data builders:
http://blog.jayfields.com/2009/01/most-java-unit-tests-consist-of-class.html
Test Data Builders

In short Test Data Builders allow you to minimize maintenance cost in your tests and allow you to easily inject objects into your test objects, it's great, great stuff.

I guess I do have an addition, a story:
On my last project a co-worker made a perfectly reasonable api change, and added a parameter to a constructor, after making the change he realized this would effect ~100 tests (whoa), so he used Eclipses magic refactoring tools and initialized the value to null. The problem was his changes really required that new parameter to be non-null (in fact if it was null a NPE would be thrown), and even though the code compiled all the tests broke (with NPEs). He didn't want to fix the tests. Why should he fix all 100 unrelated tests, maybe 5-10 tests but 100, that was just too much. And really I understood that. And I was lucky, I had just read Jay Fields post about Test Data Builders. 1/2 a day later a co-worker and I added all the Builders we needed for our project and started updating our tests to use those builders. With the builders in place, fixing the NPEs was in one place. And now, if there is a similar situation and one change breaks hundreds of tests, there is one place to go and fix them all.

Anyway, I would not start a new project without using Test Data Builders they really pay for themselves when maintaining your tests and your code.

Friday, February 6, 2009

Stack Overflow #38

There's a big old brouhaha regarding the Stack Overflow podcast #38 Joel summarizes the pod cast: http://www.joelonsoftware.com/items/2009/01/31.html He comes across as very anti-unit test, which is fairly surprising to me. I was surprised, because I feel that unit testing has only made me a better developer and allowed me to deliver higher quality software faster. Anyway I just came across Uncle Bob's response: http://blog.objectmentor.com/articles/2009/01/31/quality-doesnt-matter-that-much-jeff-and-joel. From the comments on Object Mentor, looks Uncle Bob will be participating in a stackoverflow podcast, that should be interesting to to hear.

Another blogger I follow also posted a good response: http://blog.jayfields.com/2009/02/thoughts-on-developer-testing.html

Anyone come across anything else interesting?

Monday, January 12, 2009

More about Mocks and Mockito

I've been digging around for more about Mockito and how it's different from EasyMock / jMock here's what I got:

I think there are very few use cases for mocks. They produce brittle tests and are hard to read. In addition 99% of the time you don't want a mock, you want a test spy. So why if you had the choice would you choose a mocking framework over a test spy framework?

MoreUnit Test Method Names

I got a patch accepted to the MoreUnit project. If you pull down Head and build / install the plugin there is a new option which allows you to specify whether you want your methods to be created in the style of "testFoo" or just "foo"

I've been using moreUnit pretty steadily for about 2 weeks and it is a huge productivity enhancer. if you're doing TDD you should definitely install the plugin!

Thursday, January 8, 2009

EasyMock vs Mockito

I've been meaning to write about this for a little bit, but first check out a Jay Fields post Ubiquitous Assertion Syntax. I really like the idea that tests follow a similar structure and I'm okay with the JUnit style.

@Test public void methodFoo_should_do_X_when_Y() { test setup test setup test setup assertEquals(a, b); }
What's important to me is that the assertions always come at the end of the test and it's clear what you are asserting, without needing to rely on the method name. Here's an example:
public class Foo() { private Bar bar; private String something = null; private String somethingElse = null; public Foo(Bar bar) { this.bar = bar; } public void setStuffUp() { this.something = bar.a(); this.somethingElse = bar.b(); } public Foo callBarC() { return bar.c(something,somethingElse); } }
How a Mockito test might look:
@Test public void callBarC_reallyBadTestName() { Bar bar = mock(Bar.class); Foo foo = new Foo(bar); when(bar.a()).thenReturn("A"); when(bar.b()).thenReturn("B"); foo.setStuffUp(); foo.callBarC(); verify(bar).c("A","B"); }
How an EasyMock example might look:
@Test public void callBarC_reallyBadTestName() { Bar bar = createMock(Bar.class); Foo foo = new Foo(bar); expect(bar.a()).andReturn("A"); expect(bar.b()).andReturn("B"); expect(bar.c("A","B").andReturn(null); replay(bar); foo.setStuffUp(); foo.callBarC(); verify(bar); }

In the Mockito version it's clear what behavior you are testing... it says verify(bar).c("A","B"); But in the EasyMock version the code itself does tell you what you're testing, you have to rely on the bad test name. You could argue that I'm testing all the expectations, but most often you're not. It's not uncommon to have two mocks one that sets up state for another one, the one you're really interested in testing, the focus of your test. Something like:

@Test public void verifyBar2_is_called_correctly() { Bar1 bar1 = createMock(Bar1.class); Bar2 bar2 = createMock(Bar2.class); Foo foo = new Foo(bar1,bar2); bar2.foo(); expect(bar1.a()).andReturn("A"); expect(bar1.b()).andReturn("B"); expect(bar1.c("A","B").andReturn(null); replay(bar1,bar2); foo.setStuffUp(); foo.callBarC(); verify(bar1,bar2); }

In this example except for the test name, it's unclear what the intent of the test is. Here it is in mockito

@Test public void verifyBar2_is_called_correctly() { Bar1 bar1 = mock(Bar1.class); Bar2 bar2 = mock(Bar2.class); Foo foo = new Foo(bar1,bar2); when(bar1.a()).thenReturn("A"); when(bar1.b()).thenReturn("B"); when(bar1.c("A","B").thenReturn(null); foo.setStuffUp(); foo.callBarC(); verify(bar2).foo(); }

In mockito, even if I put in a bad test name, the syntax of the test preserves the intent. This is really important. Easymock was a great library, but I think as Jay put it Mockito starts to bring us to testing 2.0

The google testing blog just published an article Use EasyMock I guess I just disagree. Mockito grew out of EasyMock, and I think they took a great library and made it even better, so I really think the title of the post should have been "Use Mockito" not EasyMock. Anyway... there's a whole lot more that Mockito does check out the examples and get off the EasyMock and start drinking the Mockito :P

 
Web Statistics