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.

 
Web Statistics