Thursday, September 18, 2008

Continuously translating requirements into code in production fulfilling user expectations

This is a long phrase, but that is the term that I use when I refer to what I am doing as a developer through consultancy. Being a Senior Consultant, my workday consists of much more than just writing code. Although I like to refer to myself as a programmer, just coding won't do it. It is all about coding the right stuff. Avoid coding to much of the wrong stuff, and get the code into production as fast as possible. This is my mission, that is what i want to be good at.

Mary Poppendieck is talking about waste. Waste is pretty much anything that you do in your production line (aka project :-) that does not provide value for customers either directly or indirectly. I just came from a talk where she was talking about how to maximize throughout and how to reduce utilization. It is funny how many metrics not directly related to providing value for customers we have been measured against. It has been a long time since I have have been measured against how many lines of code I produce. Now we are measured using Story Points. This is better but in most cases, far from measuring the right thing. 
The right thing is value for end-users delivered in production, this is what we should measure, or, we should at least know when we provide it :-)

Wednesday, September 17, 2008

Nordås on domain-driven design

I must say, very nice introduction on Andres Nordås' talk on Doing Domain driven design better at JavaZone. He has really raised the bar with respect to getting someones attention to start with. Unfortunately It was no space left in Lab III for me and my co-worker. But now we are chilling out in the Overflow area, with really good audio and video so this is really great. Star Wars, get outa heeee....good work Anders.

Being able to provide infinite flexibility in the borderline between your domain and your infrastructure and to be more specific, repositories. When you want infinite flexibility, you also need to be sure that your coupling is loose so that you may adjust implementation strategies without afecting your domain, e.g what an order looks like or what it means to place an order.  
Being able to refer to a repository in form of a generic repository interface is a very nice thing. It is even better that use you generically typed interface without knowing if it is an in-memory repository, or a Hibernate reposiory. Dealing with persistent lifecycle is in concept trivial, you store/delete and retrieve objects by query or by id. This is how all interaction with repositories should be stated.

Anders presens several examples that shows how easy it is to achieve loose coupling using generic types a container and pluggable strategies. You should really take a look to see how our code may be improved. Eirik Maus and myself will touch briefly into the same topics in our talk on Dealing with one to too many relations in Hibernate. I beleive that if you are able to correctly model your repositories as Anders does, all the other bits and pieces will fall into place.

Talk about dynamic languages using Glassfish.

Just came from a talk of using dynamic languages in Glassfish. I would actually have expected some more in-depth information about practical appliances of dynamic languages, but the examples was pretty basic. I am really fond of the idea being able to pick the language of choice when confronted with a problem. If you are encountering a problem that would call for a functional language, pick Scala. If you want to leverage your existing investments in Rails-development, pick Ruby or Jruby. I don't thing that the strength of actually being able to do this cross-language is something that we are going to see much of. However, being able to use a hug range of languages in the same runtime is a very good thing. 

Bringing web into all this is a problem. The package and deploy-step is a mess, and one of the reasons why I am looking into actually moving away from java for web. War-files is a mess, deployment is a mess and app-servers and standards (and deviations of them) is a mess. Why cant we just get some mod_java stuff for Apache and just use apt-get to install it so we can get faster into production. This is where I want to go.

Javazone 2008.

It is finally time for doing JavaZone 2008 which I have been looking forward to quite some time. This year, I will try to go to as many hardcore presentations as possible. The reasons for that are pretty simple. Usually when I read articles and watch conference videos online, it is usually late in the evening after a long days work. My ability to dig into hardcore stuff is limited. Whereas, when I attend conferences, which I really enjoy, it something I can do fully rested, therefore I want to dive into technical stuff, closely related to what I do the most, programming.

The program this year looks OK, a good mix of technical and non-technical sessions. I think you will find something to your taste. What kind of sessions to you prefer yourself?.

Friday, August 29, 2008

Testing code or testing requirements?

I have been in several projects where multiple attempts to classify tests into different categories has been attempted. Unit-tests, Web-tests, Behaviour-tests, Fitnesse-tests, Requirement-tests, Integration-tests, all of them written in Java in some ways or another. As you will see, the typical categories refers to different properties of a test. In some cases related to which layers of the code it touches. A typical unit test typically tests the contract of a given class, but will often test intentionally or unintentionally also test adjacent classes unless the rule is strictly enforced. A typical Web test could possibly be Selenium test that verifies various steps of a wizard with or without the back-end systems or databases to drive the data in place.
Some definitions of tests refers to the layer of code it refers to and how many interconnected classes they may include such as a unit-test or an integration test. Others may be more technology specific like Fitnesse-tests or Seleniums test that refers to the technology being used when implementing the test.

I believe that the core property of any test should be to capture and verify the expectation you have related to how the class, module, layer or application should work. That is in most cases why you actually write a test to start with. This is a very code-centric endpoint of the spectrum of continuously transforming user expectations and needs into a running system that provides value. Actually verifying the user-requirements and expectations is in the other end of this spectrum. There are other (possibly subordinate) properties of the process of writing tests also. If you use the same language for both tests and running code or supportive libraries, you will also verify if a class, interface or module is easy to use, and as part of the process you may actually improve it while writing the test. That makes that process of writing the test itself into something that validates more subtle and less quantifiable properties of the code. If doing TDD, writing a test is a starting point for writing code.

There are some bits and pieces missing in this picture. Very often I read about or hear about developers doing various kinds of testing in their project while applying some kind of label to what they are doing. The label may vary but terms like Requirement driven tests are becoming more and more widespread. I believe that this is good, because verification of requirements is probably the most difficult and important thing we are dealing with as system developers. But I have also seen this urge to classify everything as requirement test lead us in the wrong direction. Requirements means different things depending on who you are talking to.

I will try to address that using a brief description taken from a User Story document in one of my previous engagements:

"It should be possible to search for customers by first-name, last-name and birth-date. If multiple customers are returned a list of customers with the current address of residence should be presented along with the result"

We can discuss if this is a good definition of a requirement or not. This is not the point here. The point is, it captures a fragment of a user-expectation, a requirement. We may think of multiple tests in many of the categories above. But when does a written test really capture a requirement? I will say that depends, because requirement means different things depending on who you talk to. For me, as a coder, currently developing a jsp-based solution, one requirement applicable to the actual code I am writing may be that the web-controller returns the customer from a search as an array-type rather than a Collection based type (even though we have generics) simply because there is no way to refer to such a type using the useBean directive in JSP 2.0. This will therefore be a non-functional requirement in my code. It does not mean that I will be writing a test for that requirement in particular, but the unit test of my controller will most definitely be aware of this property.
The part of the code I am writing may also need a utility that merges two arrays into one. The SDK does not provide a utility that does that for us, but if a create one myself, i will most certainly update ArrayUtilsTest to provide a test for the new merge method in ArayUtills. It this a test of a requirement? most definitely, if verifies my expectation. Is it a requirement of the application itself that the system provides such a function? not necessarily, the primary property of the system is to provide customer search by the means necessary as defined by lead-developers and programmers on the project.

The primary conclusion put forward is that tests addresses the expectation of a whole spectrum of what we refer to as requirements. Quite a few of these requirements manifested as code in tests may not be easily translated into functional requirements owned and understood by the customers. Trying to be dogmatic about what kind of tests we write and to say that every line of code should be directly translated into a customer requirements may turn out to be a side-track. Very often when writing tests, the limitations of the test-framework and intrinsic properties of the interfaces or libraries you are using will force you to simplify and limit the number of assertions you apply to you test harness. It is important to understand that the requirement coverage provided by such tools will never be perfect. Strict tests will almost always end up being to brittle.

Getting your automated builds running the right set of tests is difficult. In my experience it ends up with a mix of unit tests, integration tests, web-tests and some flavor of requirement tests like fitnesse. These tests will test customer requirements and quite a bit of other properties. These tests tends to be something owned and maintained by developers more than by domain experts and customers, those that actually understand the problem domain.

What are your experiences?

Saturday, January 05, 2008

Using Macintosh keyboard in Ubuntu

I use various computers during a normal working day. I use a Macbook-pro as my laptop, a windows workstation running XP at the client-site where I am currently contracting, and at home I use (probably my favorite computer) an AMD workstation running Ubuntu Gutsy. Since I am primarily a Java developer, I use IntelliJ as my primary workspace, which is of course available on all platforms, the same goes with firefox and quite a few of the other applications I work with as well. One thing that has been annoying me lately, though is that I have not been able to find a really nice keyboard. The key bindings for shortcut keys in some of my favorite applications also varies slightly when using the different platforms. One thing i do know is that it is quite unlikely that I will change the keyboard on my Macbook, which i quite good anyway. I like way the keys both sounds and works.

Some years ago I used to really enjoy typing with those old IBM-style PC-keyboards when using OS/2 workstations at the university. They had really hard keys and made this really load "click" sound. Awfully noisy of course, but I really liked both the way they sounded and behaved. These are anyway not possible to get a hold of anymore.

I really like the looks of the new mac 105-keys keyboards in aluminum, so I got one ow those. The cool ting about this is that it will be much easier for me to switch between the macbook and my buntu workstation. I had a little trouble making the keyboard working as it is supposed to, but after some tweaking, I got it working.

What I had to do

Selecting the correct keyboard layout in Ubuntu is really simple. Just open the "Keyboard" application and you are all set to go. Select the appropriate keyboard layout, which in my case a PC-keyboard with the Norway Macintosh as the variant as shown in the figure.
The next thing you will have to do is enabling the Command-key as a third level chooser (this is usually the windows key on a regular PC-keyboard). Just set it like this:

Now I thought I was almost set to go, having the ()[]{} thing working for me, which is pretty damned important since I am a programmer, and I use these braces all the time. The only thing I discovered was that the keycode=49 was not mapped according to my keyboard. According to my layout it was supposed to be apostrophe bu it was bar. This does not correspond with my current layout, fortunately there are simple ways around this. I didn't know that the keykode was 49 for this key, so then I used "xev" to find it.
After finding the correct keykode, I just launched:

sudo xmodmap -e "keycode 49=apostrophe bar"

to change the mapping to get the apostrophe in the right place. Now I am all set to go. I am probably going to buy myself one of these keyboards for the windows-workstation I am using at the client-site as well.