Pages

01 April 2006

Fitnesse and Rails : bridging the business/technology gap

I have been so far quite enthusiastic with 2 frameworks: Fitnesse and Rails.

Fitnesse: executable specifications for the developers

Fitnesse is a framework that allows you to create HTML specification pages in a wiki. Those specifications can include any form of text, images and HTML links. But they can also include tables that specify acceptance tests for your system.

Then, provided that a developer (or better: a pair of developpers,...) has provided a "fixture", that is, a java class that will implement the table, the HTML page is executable! Once executed, the page shows the expected/actual results and uses the famous green/red colors to display those results.

I see many advantages to this approach:
  • The HTML pages look like a classical specification to the analyst
  • Having the analyst specifying very precisely expected values results in much better specifications
  • This makes the analyst and developer discuss very precisely the requirements and their possible implementation (when creating the fixtures)
  • This forces the analyst and the developer to think about the testability of their system, which usually results in better designed systems
  • This is the start for a global Test-Driven approach to system development
There are still some points that could be improved:
  • The wiki markup language itself is weak and would really benefit something like Confluence (if Atlassian guys hear me,...)
  • The integration into a continuous build system is not standardized (with an ant task for instance)
  • The implementation of some concepts is not first-class (try to add something like ${myVar} in a table,... Fitnesse will try to evaluate it, even if it is in fact part of your specification)
Anyway, this is the first time that I come across really useful and not deprecated specifications, which is quite uncommon in the industry.

Rails: a bliss

It is hard not to come up with glorious adjectives when speaking about Rails. I have not been specifically a web application developer knowing all the nitty-gritty details of web application development: urls, sessions, security, html specifics, javascript,...

And Rails makes it so easy. Each time I asked myself: "how can I do that"? I found an elegant solution in the Rails framework. And when I dont find it, I think "I have to search harder,..."

Of course, part of the success of Rails is due to Ruby, enabling beautiful code with minimum of syntax. I have been, for instance, very easily refactoring some test code by intercepting calls to my tests methods to assert the same thing in several methods.

There are 3 other reasons in my mind:
  • the famous "convention over configuration". Having nothing to do when implementing the default/most common behavior is productivity at its maximum
  • the dynamic aspect of the language: you don't have to redeploy to see the changes
  • the people that designed the framework really know about web application specifities. And they did their maximum to leverage Ruby and the DRY principle (Dont Repeat Yourself) to reuse this knowledge
All this gives a very fast track to implement business rules and applications.

I am really wondering what is going to be the success of Ruby and Rails in the next years. Certainly Java won't die (21st century cobol), but what I know for sure is that Ruby and Rails is really fun and productive to program with.

Those are 2 really strong arguments for people with squared fingertips !

02 March 2006

Relationships as first-class citizens

Here is a link to a research project for having relationships as first-class citizens in Java:

http://www.cl.cam.ac.uk/%7Eaw345/talks/ecoop05.pdf

Not a new idea, the article mentions another dating back from 1987:
  • J. Rumbaugh. Relations as semantic constructs in object-oriented development. (OOPSLA 1987)
This is for sure a topic that will make its way to a programming language someday. However, the above article indicates that this is a tough subject and that many of consequences of having relationships as first-class citizens are not yet mastered: inheritance, multiplicities, construction,...

I would bet that adding this kind of functionality via a mixin in Ruby could be a great way of getting the details right, in the manner of what is been done for ActiveRecords in RubyOnRails.

28 February 2006

Techno-thriller and change management

The oath is broken. I wanted to add a new entry in this blog at least every 15 days, and failed miserably for one month.

Let's compensate that with 2 light subjects in one entry.

What if we were trapped in the energy shortage?

Michael Crichton has just released (at least in France) a new book where some eco-warriors are triggering massive natural catastrophies in order to make the world join their cause. I don't feel very inclined to what appear to be M. Crichton views on the climate (from what I know), however there is an issue I have been thinking of, that would be interesting to be written as a novel,... or maybe to be taken more seriously!

In 2 or 3 or 4 decades, we'll be short of petrol. In 60 years or so, we'll be short of gas. Uranium won't last much longer.

Ok, let's develop new technologies, new energies,... But how do we do science, research, technology? With computers, labs, cyclotrons,... All of these are pretty much energy intensive (and water, but that's another debate). What if 60 or 80 years were not enough time to find any viable solution to the energy crisis? Our scientists would be back to wood and stones to find the new super energy of the future? But how could they do that in a world that would certainly be a complete mess? You got it.

This could be interesting as a novel, but I would personnally prefer having a public announcement in the next 10 years saying that a major breakthrough has occurred in cold fusion,... Otherwise, how the hell would I be computing until my fingers are crippled? I really plan on living 60 more years!

You can't change the world alone

I am currently learning an interesting lesson. Since my arrival in my current company, I have introduced several practises, either for development or for management:
  • TDD
  • pair-programming
  • features driven iterations
  • more participation from the group to development decisions (let people decide what they want to do, as long as what need to be done is done)
So far, there have been some successes and some areas could really be improved. For instance, our java team had a moderate consciousness of the absolute need of a permanent green light for unit tests:
  • we had in one month 426 builds (99 OK / 327 KO). Maximum OK in a row = 12, maximum KO builds in a row = 126
  • the whole "unit" test suite takes 1 hour to run (for 1800 tests)
Those 2 examples are clear signs that true TDD is not practised around here. Among the many causes of that, I would register my lack of success at making people change their practises.

The white knight

We recently hired one of the best developers I ever met, in order that he could take some, if not all, my activities as a tech project leader. I had a second objective in hiring him. I knew that he would be good at reinforcing the messages that I had been somehow unsucessful to convey. He was my white knight,...

I really needed him: 2 is better than one, and a newcomer, with a different background is even better. We know software development from different shops. This guy and me are much stronger at convincing -together- that there are good practises that should become mandatory.

And we feel that this is not enough. The "planning game" can also be improved. So we are hiring a "agile consultant" to help us start the new release the right way. One of my personal objectives for this year is to get a perfect consistency of our roadmap, our iterations and our day-to-day development. This is a difficult task. So we need our "white knight",...

Feel it with your guts

Having a white knight is great to trigger change. It can give legitimity to your ideas, better ways of introducing them. But if you want good development practises to survive your presence (something I have been missing this past months), you need to make people feel them with their guts. They should suffer from atrocious aches in their stomach, each time they develop a piece of code without any test for it for instance.

How would you do that? We plan to introduce Dôjô (now I know why there are '^' on the 'o' thanks to my japonese lessons,...) to make people practise TDD the extreme way. If the drug is good enough, they should be hooked on forever.

[ah, good to be back at work after a really pleasant vacation week ;-)]


22 January 2006

The hard piece - solved

What can I do as a kata tonight? Oh yes, the unsolved problem from this week's Dojo, of course!

Well, it was not unsolvable at all, you just have to cool down and try to write down things progressively.

The solution

The idea I had that evening is that, finding the position of the upper left corner of the ith subgrid in a grid, should be as difficult as finding the position of the ith square in a grid. Make as if the big grid is a small one with subgrids in each square.

So here are the formulas (perhaps it is clearer than my previous "explaining" phrase?):

# returns a square position (x, y) for the upper left corner
# of the "grid_nb"th subgrid in a grid
def get_subgrid grid_nb

square = Grid.new(@width / @sub_width, @height / @sub_height).get_square grid_nb
x = 1 + @sub_width*(square.x_pos - 1)
y = 1 + @sub_height*(square.y_pos - 1)
end

and

# returns a square position (x, y) for the "square_nb"th square in a grid
def get_square square_nb
x = 1 + (square_nb - 1)% @width
y = 1 + (square_nb - 1)/ @width
Square.new x, y
end

OK, and for the crazy ones, the formula that precisely calculates the position of the upper left corner of the "grid_nb" subgrid in a (w * w) grid with (subw*subh) subgrids (for instance, you can have a 6x6 grid with 6 2x3 subgrids):

1 + subw*((1 + (grid_nb - 1)% ((w / subw)) - 1) + w * (1 + subh*((1 + (grid_nb - 1)/ w) - 1))

No wonder why we couldn't get it rigth at once! Indeed, it took me slightly more than one hour to do that with 5 tests and 31 assertions in Ruby.

TDD as an unconscious habit

Thinking about the discussion I had about TDD after the Dojo, I feel that TDD should really become an unconscious skill. You have to train yourself consciously then to master it without thinking about it. You know the classical circle for learning:
  1. Something I don't know I don't know - unconscious lack of skill
  2. Something I know I don't know - conscious lack of skill
  3. Somethind I know I know - conscious knowledge
  4. Something I don't know I know - unconscious knowledge
Regarding TDD, the specific thing that should become inconscious is the exact rythm of what you are doing:
  • either defining test cases - green bar
  • either implementing test cases - green bar
  • either implementing code to pass the test cases - red bar
  • either refactoring code - green bar
  • either refactoring test cases - green bar
Practising the Dojo with an attentive animator or practising pair programming with a merciless mate is a great way to get the habit.

19 January 2006

Back from the Dojo

Gureto!! (Great in japanese)

The Dojo we had last evening was very instructive

The place

We were 11 people from various background sit around a computer and a keyboard with a videoprojector.

The master and the rules

The overall evening was really well mastered by the MC. He told us the rules:
  • a recap from last Dojo session
  • a brainstorming for the subject
  • a vote
  • several "randories" of 5 min each
  • pair-programming. The co-pilot becomes the programmer when the randori is over and a new person becomes co-pilot
  • TDD is mandatory and should be followed by the rule
  • watchers are only allowed to participate to ask for explanations or to state that the current development is out-of context
  • no more than 2 hours in a row (1 and a half is common)
  • the aim is not to be productive but to learn as much as possible
The session

First of all, we had the choice of the language: either Java or Python (my coworker is also proficient in Prolog, but she was the only one). I voted for Python because first I wanted to taste another dynamic language such as Ruby, but also because I feel this kind of language is pretty well adapted to the Katas.

The Kata

The kata we chose is an idea I proposed from Cédric Beust blog: solve a Suduku grid.

First of all we started from a list of tests that we wanted to pass. And we lowered our ambitions from that point on,... So we started with a kid's suduku of 4x4.

And we had a first objective that was to find the solution when only one square was uncomplete.

All in all, something like 16 unit tests were implemented and everything went with a smooth pace. Until the hard part!

The hard part

When you learn martial arts, there are times when you feel at ease with the movements and there are times when something seems unnatural, uneasy. Then you have to struggle with yourself to feel the right way to do it. Ok, enough for the metaphor.

Everybody in the room stumbled on one algorithm that we could not get straight. Even with such brilliant minds around the table. We wanted to implement a function that would return the uppermost left corner of the ith subgrid of the suduku.

This may sound easy for a 4x4 grid but, I don't know why, we had the madness to try to solve it for the general case:
  • a suduku of NxN
  • with subgrids of WxH
We fiddled with /, % +1, x W,... but nobody could either code it or explain the right algorithm to others in the room.

I was myself pretty much disappointed as I was too tired to get it right and I felt there was a really smart solution to the problem (something like a fractal approach).

So I think this will be the subject of an upcoming kata and I will post the solution if available.

Cooling down

Eating a delicious home-made tiramisu, we exchanged on this experience. I had great pleasure exercising TDD with an integrist as MC (I will certainly blog later about that. For instance, why would you need to execute the tests when you have just written a test with a missing method? You know that it will fail!).

I think this kind of session is the real way of learning the practise to a group of programmers.

We also had a discussion around the Cascade style for development thanks to Laurent Bossavit (the MC) that told us a funny thing:
This article was an inspiration for the great "V cycle", that spread so widely afterwards,...

13 January 2006

Roman code kata: MCMLXXIV => 1974

I want to share a small code kata I did tonight.

The kata

Transform a roman number "MCMLXXIV" into a decimal number: 1974. This kata is extracted from the XP french website (here).


What! Ruby is not perfect ?!

Another example of DiD,... In my implementation, I wanted to get access to all the characters of a string: "CIV" to ["C", "I", "V"].

So I grab the ruby doc and after a few searches on the web, I realize that no nice method such as String#chars or String#each allows to get the characters in an array (here's a ticket for that issue).

I had to resolve to my_string.split(//) which is not quite natural and expressive.

TDD of course

I used TDD to progress with my development:

assert_equal(1, r_to_i("I"))
then
assert_equal(2, r_to_i("II"))
...

and I was quite glad to get the right code fast enough. Ok, agreed, it is not rocket science. But small successes make a happy day.

Lessons learned

The interesting thing about code kata is the time to consider what has been done and how it has been done. Specifically I wondered about the possible use of an injecter to reduce the code (which was a question on the web site):

def r_to_i r
result = last = 0
r.reverse!.split(//).each{|n|
T[n] >= last ? result += T[n] : result -= T[n]
last = T[n]
}
result
end


[funny thing : copying-and-pasting the code on the blog, I found several ways to reduce the code size. However, I feel a comment is necessary on the algorithm. I may not be understandable at first sight,...]

But I don't how it is possible since injectors are repeatedly cumulating the same operation on elements of a collection. Anyway, it was a good pretext to re-read the paragraph on the subject in ProgrammingRuby.

Ok, back to hiraganas now (I am currently learning japanese,...)

11 January 2006

DiD : Devil in the Details,...

A new acronym, that can be encountered in so many workplaces, even literally speaking sometimes ! (Bwah, ah, ah, ah,...)

Time for a follow-up. I was pretty satisfied with my idea of implementing associations as first-class objects in our object-model. It truly serves its purpose : a fine management of relationships between objects: deletion, updating, adding,...

However, I would like to summarize also all the difficulties we had along the way, that's not always paved with flowers:

Transient/Persistent objects

We have some objects that are build only for the purpose of the application session. Those objects are displayed to the user but not meant to be persisted. Yeah, right. But hey, anytime you are associated with a business object, an underlying Observer-Observable relationship is build. It's fine until the business object is persisted and JDO kindly does "persistence by reachability" to persist anything connected. Bang! A transient object is persisted,...

Modification impacts outside the aggregate

With our framework, each time the marketing adds a new ProductRelease to the Product, the Catalog can be notified. All this stays in the same hierarchy of objects. But what if a corresponding new ManufacturedItem should be created in the Factory ?

Loosing my memory

Objects are cool, objects are fine and RAM is cheap,... but not infinite! Adding new objects to manage the relationships also adds more data and we had surprises with our memory consumption.

Redundant associations

Every relationship is managed as an association, even for redundant associations, that are only there for design reasons. As we also use our framework, in a very generic way, to create configuration files, we had never-ending instability each time a new association was added even if the business did not evolve.

Caches

A variant of the previous one. How should a cache of objects be managed? As a composition between the object owning the cache and the cached objects? Can the cached objects appear in compositions even if they are indeed shared?


Tackling the issues one by one

Ah the details,... They can truly turn any "brilliant idea" into "useless crap". Our current answers to those issues are:
  • Transient/persistent: no obvious solution. Delete the objects when not used. Persist them temporarily if necessary. We are waiting for our supplier to implement JDO2.0 to implement an elegant solution.
  • Modifications outside the aggregate: use the ubiquitous EventBus
  • Loosing my memory: some attributes were unecessary on the associations. This had a nice impact. However since we don't have any way in Java to know who's using a specific object, we need to add extra-pointers
  • Redundant associations / caches: this is a real case of "don't mess the business model with the design model". We redesigned our associations with more meaningful data. Is it a design association? Is the component object cached? And so on.
So far, so good, we didn't find a vicious little problem that could bring our framework down,... yet!

One more word: I wish we did all that in Ruby! Take a look at the ActiveRecords framework:
class Firm < ActiveRecord::Base
has_many :clients
has_one :account
belongs_to :conglomorate
end
or
class Account < ActiveRecord::Base
composed_of :balance, :class_name => "Money",
:mapping => %w(balance amount)
composed_of :address,
:mapping => [%w(address_street street), %w(address_city city)]
end
It seems so clean :-O

31 December 2005

Have you done your code kata today?

Scheme, ADA, Prolog,...

As I was reading Joel Spolsky's last post and the following discussion, I was reminded of my own education where I had to learn Scheme. So many parenthesis,...

I had a go at the test sample that Joel was referring to. It wasn't hard at all. But I realized why. At school, we were given so many exercises of money change management that anything like the sum of squares is a breeze:
  • can you write in Scheme an algorithm that gives the change for a given amount of money having w 1 cent coins, x 2 cents coins, y 5 cents coins, z 10 cents coins?
Yes, I remember blowing one or 2 neurons off!

What's left from that? Frankly, I don't know. I certainly don't exercize this kind of ability each day. However I think it gives me a kind of mental agility that's fine to use when needed.

The other languages we were taught were SQL, Prolog and ADA. ADA mostly. With ADA, the emphasis was on implementation hiding, abstraction, data types. Basically the survival kit for doing some kind of design.

Give me OO, but keep me down on earth!

The other language that we should have learned was Smalltalk. No object-orientation in 1992?! Luckily, I had to cope with an object library for geometry in C++ as my first internship.

My first big project was also in C++, then I jumped on the Java bandwagon. What a relief, no more pointers/memory management! I could at last focus on object analysis, design patterns and so forth. Too easy my friend,...

The law of leaky abstractions strikes again. As an object zealot, I like to live in a world where everything is an object. Yet this is not the real world! I also live in a world where I have to manage memory for any non-trivial system.

I learned it the hard way,... My first financial system was full of small objects representing financial parameters. The server RAM was full of them too! Here come lazy loading strategies, careful collections selection and garbage collecting. Why wasn't I taught all these? Superficial teaching? Maybe the reason is that teachers don't have to learn it the hard way,...

The bottom line is that learning Java in CS courses is certainly ok, even if it presents a limited approach to programming. It is ok if you also learn the subtleties of java, not to be an expert, but at least not to fool yourself.

Learning Ruby

I specially liked Joel's post since I started learning Ruby this month. First of all the syntax, then the API (no more code completion!), then what?

I remembered an idea from the pragmatic programmer's book (I think): code katas.

Code katas are small programming/designing exercises. Each of them aims at developping a specific ability that useful in programming:
  • Business analysis
  • Data munging
  • Data sorting
  • Estimating size or speed
  • ...
I would certainly add other katas to Dave's list:
  • Threads management
  • GUI building
  • Memory management
  • Network communication
  • ...
The nice thing about katas is that they are written in a way that you have to think about how you solved the kata and what did you learned from that. High education is not the end of it at all. We have to much to learn to grasp software, from technique to business. And we have so much to learn about how we learn (take a look at the Dreyfus model for instance)!

Again, martial arts as a metaphor for programming is pretty interesting:

-Sensei, I practised my code katas today
-Well, well, Eric-san, the spirit of software will flow through you. Now, wax-in, wax-out!

20 December 2005

What the market wants

I have been following a training session on the marketing of innovation. What a treat! Many times, the speaker told us: "if you should only remember one thing from this training, it is,..." which was a funny running gag (until he said "..., hum, not this one").

The market opportunity

Among the things to remember were:
  • where's the need? is it conscious/expressed, comfort/strategic, adressed/covered?
  • are you relevant -and- credible to cover it?
If there's a real need:
  • conscious -> if possible (otherwise, it will be really hard unless you're a big corp)
  • strategic -> necessarily (somebody has to start living again thanks to you)
  • adressed -> always (don't dream awake, the world is not waiting for you to turn),
and you have something relevant enough to convince other people,...

then go ahead! You have a market.

Those 3 questions were so appealing that I couldn't help but think: "ok what would be the next need that I could fulfill with a new innovative product?" (unfortunately, I found nothing yet,... but asking the question again and again should bring something!)

Stay focused and prioritize

The rest is only one thing: stay focused. It is not so original (see Geoffrey Moore book) but this is the real trick to succeeding.

Product development, commercial development, communication development -are- terribly expensive and error-prone activities. So gather all your energies on the right battlefield.

Oh, yes, one more thing (hence the running gag,...): define a strategy that will allow you to extend your playground, once your primary, tightly-focused market is covered.

Write it down

On the way home, I applied all those principles to 2 prospective markets for our products. I found out something: it really pays to write down things when you do any strategic planning. I have often observed, in our board discussions, that the more recent customer event took the lead over any previous experience. This must have something to do with our limited brain capacities (see Herbert Simon "limited rationality" concept). By detailing numerous facts, I could determine many different reasons why one market was better than the other, and which kind of product and value proposition were to be made on each of them. I think that any discussion on the subject could have driven us into circles.

Just do it!

Innovative Entrepreneurship is not a piece of cake but it really looks like the world will never be quite the same when you succeed. Well, maybe even if you try!

05 December 2005

Test-driven development : a practical guide - 2 years later

Oh well, this book (Test-driven development: a practical guide by Dave Astels) is not so new. Yet, I believe that not so many developers (including myself) have really acknowledged the messages it conveys.

Having read it 2 days ago, I take the opportunity to sum up some of the ideas that are exposed in this mind-agitating book.

  1. Tests are only a by-product of test-driven development (TDD). The primary aim is to develop good software confidently (see my previous post on Behaviour-driven development)
  2. Unit testing a java gui is possible
  3. Developing a system with TDD leads to a well-crafted system if we refer to the metrics ran at the end of the sample project
  4. Why would you ever need a debugger?
Now, more on my personal thought about this book and its messages:

Be humble

Dave insists (heavily,...) on that: do a tiny little bit at the time, and of course, as a real XPer, do the simple thing that could possibly work. I feel this is really not so easy. When I develop code, I am very, very, very tempted to write more than I have tests for. What in the hell could be wrong with that simple iteration on my collection to get the object with the right name?

The trouble is I have too often seen those kind of stupid mistakes:

int i = 0;
while (iterator.hasNext()){

t_object = (Entity) iterator.next();
if (t_object.getName().equals(p_name))
break;
}
return i;

OR

if (p_param >= 10);

doThat(p_param);

Yeah, it's so easy to write code, but it's so easy to write wrong code, even if you're more brillant than Marilyn vos Savant. By the way, did you spotted the errors? The first piece of code returned a counter that wasn't incremented,... and the second one had a supplementary semi-column after the decision in the if (I did this one at least 3 times in my coding career, and I am sick of it since my brain can be real slow on just spotting that parasite character).

So, be humble, don't trust your "best developer of the month" diploma, assume that every little bit has to be correct.

Use one set-up per fixture

This is a discovery for me. I always tended to think: "there should be at least a test class per production class". Yes, sure, but there can be so many more: the trick is to really use the setUp methods for factoring the fixtures for the assertions you want to make. And If you want to create another fixture, create an another class. This way you will end up with specific classes for specific contexts and with test methods that contain merely the minimum of what's needed.

There is no such thing as a free good design

From the beginning of his example, Dave shows us that he has a good idea of what should be a good design:
  • proper use of interfaces
  • clear separation between business code, UI code and persistence code
  • ultra-thin UI (this allows an easier testing of the UI)
I think that TDD can reinforce a good design (hence the proper metrics at the end of the experiment) but I am not sure that TDD leads you automatically to a good design, even if you refactor a lot. This is why XP mandates the use of exploratory design. At some point you may have to experiment in order to find the right ideas.

Using the debugger is a "smell"

I read this months ago, and I often remember this when using the debugger. Using the debugger makes me think that I don't really know the behaviour of the system I am using. Then, like St-Thomas, I have to take a look at it.

Moreover the use of the debugger tends to encourage a code-and-fix attitude: I code, then I will ask the debugger for what is wrong. And this gets worse with tools such as Eclipse where you can modify code on the fly and re-execute it in the same debugging session.

So when you want to ascertain the behaviour of your system, it is much better to make an hypothesis and write a test case to make sure you're right.

Eventually, there may be a 5th XP value: Disciplin,...

29 November 2005

Bouncing ideas

I had the great opportunity to participate in creativity and brainstorming trainings. When I first learned about brainstorming, we were taught the following rules:
  1. say whatever you have in mind
  2. the quantity is better than the quality
  3. don't judge
  4. you can copy on your fellows
This last rule is really interesting and was fairly reused in the creativity training I had 3 years ago (with a faboulous company: Synectics). It is the contrary of school (at least the french one)! Why not elaborate on other people ideas and catalyze new ones?

This why I feel great when I see that 2 of my recent blogs found an echo on the web. When I writed about the "attitude" of software testing, I wasn't aware that other people were already working on that matter, and they call that approach "Behaviour-driven development". This is not a revolution, just a different way of looking at the software we develop.

Similarly, I had heard a lot about Ruby on Rails and its ActiveRecord framework, but I just realized, reading Graham Glass's blog, that part of RoR popularity is certainly related to its support for associations and compositions. It really itches me to download Ruby and start using it. I wish I could have all these facilities of declaring properties such as "belongs_to" or "has_many" in Java.

So now, my only wish is that I have enough time to add my grain of salt to those developments,...

19 November 2005

Testing: disciplin, attitude and intuition (3/3)

Intuition

I had one other bug that I found really inspiring 2 days agos ("learn from your errors", they say,...). I had to create a project, open it, generate test cases, reopen the project and regenerate test cases to get the bug .

The question is: "why would you test that sequence"? Because you have testing experience? Because, it is written in the requirements? Hum, not really. I have never seen "REQ_451 : after 2 successive uses , the software should not crash". This requirement is really an implicit one.

In fact, this is actually an invariant that is worth writing down as such in a requirements document: "REQ_451 : whenever a project is opened, a test generation should not make the software crash ".

Then, you have several ways to test that requirement:
  1. The "classical" way. Trust your intuition/experience and find a naughty test case to drive the application mad
  2. The "LTG" way. Use LTG and define an operation that models your invariant: "if (one of my entities in the system has no parent entity) then the application is broken". Then, model valid operations that modify the parent of an entity and generate test cases, that will try to break the invariant.
At that point there are 2 possibilities:
  1. your requirements allow a valid sequence of events that may break the invariant. LTG may find tests that show this behaviour, but then you may just conclude that your specification is not tight enough! There's a breach in the specification and it's nice to know it.
  2. the broken behavior can only appear because of a broken implementation. Then use LTG to concentrate the fire on that specific spot. Generate more test cases that will vary the conditions where the entities parents are modified.
The second case is an automation of the tester's intuition. This makes the case for the trio "disciplin, attitude and intuition":
  1. Intuition because you focus on what could go wrong
  2. Attitude because you don't try to guess what could go wrong exactly but more likely you test the range of combinations that should be allowed
  3. Disciplin because you take time to produce many different combinations (of course LTG helps with that matter,...)

Testing: disciplin, attitude and intuition (2/3)

Attitude

I ran across a test today that I found interesting. The tested class was one of our association containers (see previous blog entries), a List to be more precise. A list can contain several times the same element.

Believe it or not, I am not sure that writing the tests for that class I would have thought to include that kind of specificity. I am glad I didn't develop the test case for that class,... because the developer that did, did it right. He had tests that included that specificity.

I am not sure that the first implementations of the class needed that kind of test, but surely the modifications I introduced afterward failed because of that blessed test!

I think the main difference between our 2 state of minds is that I tended to do white-box testing whereas the other developer did black-box testing. That's a very different state of mind:
  • when you do white-box testing, you know what could go wrong and you test it
  • when you do black-box testing, you define what you expect but since you have no idea of the implementation, you try to expect most of it. So you add the same element twice in the List. You dont want to guess what could go wrong, you just want to test what is ok for you
To that extent, testing is also a matter of attitude. Having the "tester" hat is quite different to having the "developer" hat. Switching between the 2 may not be so easy, hence the need for disciplin mentioned in the previous entry.


Testing: disciplin, attitude and intuition (1/3)

This is the first of 3 entries that make testing look like a martial art,...

Disciplin

Test-driven development is a really wonderful idea. Start doing it and you'll catch the fever. There are many sources that establish all the benefits of this approach. However, we're still human people,...

I personaly find it difficult to do pure test-driven development when:
  • In the process of implementing necessary code to make one test pass, I have to write new code in other classes that should also be tested. Sometimes, I am so much into getting that green bar, that it's not so easy to digress and start fully testing/developing something else
  • When I develop a new idea, a new implementation across a whole set of classes, I may want to write code that could end up not being the right approach for my current objective. Should I then write the tests for something that may really not function as planned and that should be thrown away?
The "sensible" approach to those 2 questions may be: "no Eric, don't sell your soul to the Devil, you have to test each and every line of code that you produce". So I should:
  • Set aside my first testing goal, clarify what I expect of each new operation I am developing and test it, even if it may cause a delay for the first green bar, or for the exploratory design
But I live in reality and I actually find it more rewarding and productive to do what I want to do to a certain extent without testing it first. The trick is,...

...to always have a tasks list for the things that should be tested:
  • Once you have the first green bar, go back to the list and test everything that hasn't been tested
  • Ditto for the exploratory design
I have exceptions for that process. If I need to develop something that's really not easy along the way, I switch back to the TDD mode, because I simply know that I will produce missing code faster.

"Ok, ok, Eric, it's nice to learn about your fascinating worklife, but what's the point?".

Well, the point is that one: in order to succeed, you need disciplin.

You absolutely need to get back to your list. I found that 2 nice ways to do that:
  • Use your buddy! When you practise pair-programming, your partner should always have the responsability for the tasks list. He is your Master that should help you with the disciplin stuff (this also goes for coding standards respect and so on)
  • If you program with Eclipse, you could use Mylar. This plugin keeps track of all the classes that you modified in the context of programming a given feature. That way, when you get your green bar, you can be confident that you got all the modified resources at hand.

15 November 2005

It's cool to have a tool

It's the positive "hammer" effect ("when you have a hammer, everything looks like a nail"). We were facing the following problem:

We want to enforce that, when an object is composed of other objects, those objects can not have the same name. This is a strong constraint on our domain model, however it allows us to define "paths" for our entities that are truly unique (a path is composed of entities names from the object to its root parent).

However, what if the user wants to rename an object that is part of a composition? This could break the rule. There are 3 design choices :

  1. have a "rename" method on the composite object doing the check and be careful never to give access to the component objetct (by cloning it when accessed through a getter method for instance)
  2. let the user rename the object directly and then let him validate the composite object (what if he forgets?)
  3. our design choice

I'll explain our choice, of course. Since we have Composition objects that observe their content, it is quite easy to notify them (through an Observer pattern) when the setName() method is called on any of our entity objects. Then, they can do the check (that they usually do when an object is added to them by the way).

This is one of the neat benefits of making the distinction between Compositions and Associations in a domain model (see Eric Evan's book Domain-driven design (DDD)). Many times, when associated objects evolve, the related objects need to be informed to change their state:

  1. when a component changes, the composite must be able to validate that change. A possibility would be to never give access to components in an aggregate (the advice in DDD). This can be pretty restrictive for some domain models.
  2. when an associated object changes (for instance is removed from the database), the related object needs to know about it (otherwise, he may have a dandling pointer). Usually this kind of rules is managed outside of the objects (through a data access layer). But why should this behaviour be separated from the domain behavior?

This is where the hammer hits: by having Composition and Association objects (and variants: Lists, Maps,...) it is really easy to control this behaviour in a very generic way. Each "association container" observes its associated entities and when they face "important" events (renaming, deletion), they notify their container. The container then knows what to do:

  • a OneAssociation has no more associated object: "oops, this must be a critical mistake"
  • a ZeroManyCompositionList is deleted. So should all the components inside the list
  • ...

If I had a hammer,....

10 November 2005

I am definetly a geek,...

Although I may not admit it in all circumstances, I seem to be quite a geek. I passed the nerd test today and got a "Migthy Nerd" score (or something like that, this means that 6% of the population is nerdier than I am).

Yet, I don't think I really qualify for much of geek knowledge. I know too little about computer internal (how to boost your cpu) or network (how to setup a virtual lan) or even Linux (this is a shame, I know). On the other hand, I know I would love to. It is just a matter of available time in a single day.

Anyway, one other clear sign that I am definetly a geek is that I just ordered one of the only DVDs about programming. Joel Spolsky has practically finished the editing of the movie of the Aardvark project. I have seen the trailer and I think this is gonna be a real inspiring movie for me to watch. Besides I really think that Joel's theory about how fundamentally running a software business is really appealing and I am really interested in seeing this in practise.

Welcome to geekland!

04 November 2005

Let computers be dumb so that you can be smart and smart, so that you won't be dumb

I recently found that this could be a kind of unofficial motto for our software product. But it might as well be the same for many other software products.

Here's the story:

you're a software tester, writing a test case, either a good old word table, or a java script or a Test Director script.
How many times did you think:

1. This test case is so dumb that even a computer could write it!
OR
2. This test case is so smart that only a computer could write it!

These are 2 of the true powers of the computers:

1. being so dumb and dull to calculate endless combinations of values without pausing at it (how many coffee breaks do you really need as a software tester every day?)
AND
2. at the same time being so smart to find meaningful combinations for special cases where you would have abandonned finding that- case-that-anyway-may-never-occur or most certainly where you would have not assumed its mere existence.

Yes, I know, in the end, computers are not-so-smart items. They are only smart because we feed them the right algorithms (thank god, we may still have a job forever!). But being able to exploit that dumbness to write down necessary but really uninteresting test cases or to let algorithms backtrack to death until they find the solution is really a bliss.

The only curse is that you have to feed them right:

-what are the rules they are supposed to work on (the model in model-based testing)
-how you want them to be smart, because this has a meaning only for you

So their true power is only realized if it's not too much work to set-up the data and if you can find algorithms that won't need too much customization to solve your specific problem. I think that most of the time, this is achievable. The trouble is that you may need to be really smart to do that!

26 October 2005

I had to use Google's software somehow,...


And here I am again finding that old blog that I created 2 years ago,... Blogger has evolved a lot so I decided to give it a start again with the messages I published since last september.

19 October 2005

Object modeling to code: associations as first-class citizens

I had this feeling for a long, long, long time. I always found that object modeling in UML helped giving birth to what Eric Evans calls the "ubiquitous" domain language (in his book "Domain-Driven design"). As a consequence, I thought that object programming languages were really missing an "association" type of attribute that would convey the kind of meaning you have in your class diagram.
This was just the kind of idea that could be somehow implemented someday in java10 after extensive academic research (that was certainly going on the subject - isn't it the classical way of promoting new programming languages?).
Anyway, all this was just day-dreaming and practically speaking I was more or less mentally mapping the object business model to my java classes. Alternatively, I used Together's java annotations to describe the collections.
But we are now facing a though challenge that many people must have dealt with in many places (the question is: who and where - please email me,...) : how can you evolve an existing graph of objects from an XML file that is supposed to represent its next state. This is not so easy because:
  • if an object is not present in the XML anymore, it has to be removed from the object graph everywhereit is used, and due exceptions must be sent if it shouldn't be allowed. Failing to do that properly would cause nasty errors in our object database
  • changing the state of objects can have various impacts on other objects in the graph and those impacts can trigger a "chain-reaction" from the bottom of the object graph to the top
My first idea was to have a metamodel of my application describing all the relationships between the objects: who is referencing/composedof who through a collection (well, our first idea was to use an Observer design pattern throughout the code).
Then I would use this metamodel for several things:
  • generically produce the XML equivalent of the business objects
  • computing differences between the "state before" and the "state after"
  • sending the differences to our internal "EventBus"
  • generically having the business objects subscribing for the changes that are applicable to them
  • let the business objects do their job and send other events for the possible impacts
Getting down to the details, this design seemed to fail for a fundamental reason: you have to declare some knowledge twice in the application:
  1. when you create your classes, they have relationships through pointers even if all the semantic of the association is not declared
  2. when you create your metamodel, you add more information to the existing one
And this week-end, I had "the" idea: why not add the missing information to the code itself?
So I decided to create Association classes that would satisfy all our requirements for minimum redundancy, maximum robustness and distributed behavior among classes:
  • ZeroManyAssociationList/Map (implementing List/Map)
  • ZeroManyCompositionList/Map
  • OneAssociation
  • ZeroOneAssociation
  • ...
And those association containers would be observers to the objects they contain.
  • when a business object is removed, all the containers are notified and can cleanly remove their reference to that object
  • a OneManyAssociation can check that the lower multiplicity is respected
  • a Composition association can now be used generically to know what to do in case of the removal of the owning object
  • an association can be constructed with its owner and warn him that its content has changed
  • ...
There would be more things to say about this design and how to implement it properly but I just want to end with 2 drawbacks:
  1. The type of a ZeroOne or a One Association is not the type of the referred object. It could be interesting to use a dynamic proxy here, however I don't think that it would work with JDO (the database API we use)
  2. Business objects diagrams with Together will be unnecessarily cluttered by those container classes.
Yet, as for any design where you have to decide between conflicting constraints, I think that if this solves elegantly our need for a more robust object model, this is really worth the price.

04 October 2005

Recruitement best practises

There's so much "soft" in software.
I have again the opportunity to recruit somebody for our development team and I think I should improve our practises in that field as in any other. I could say that recruitment is a crucial activity for a startup company such as ours.
But for what company is it not critical?
So, what are the best practises for software development recruiting? I found recently some litterature about it :
  • an article in JoelOnSoftware book ("Joel on Software: And on Diverse and Occasionally Related Matters ThatWill Prove of Interest to Software Developers, Designers, and Managers,and to Those Who, Whether by Good Fortune or Ill Luck, Work with Themin Some Capacity" - maybe the longest book title in history,...)
  • and a book by Joanna Rothman ("Hiring the Best Knowledge Workers, Techies & Nerds: The Secrets and Science of Hiring Technical People") which I did not read yet.
From Joel Spolsky book, I will add a few things to my interviews:
  1. a very simple set of criteria: I am looking for 2 qualities "smart" and "getting things done"
  2. the "impossible question" as a mean to challenge those qualities
  3. a new "let's write some code" exercise.
The later one I did for myself : "reverse a linked list" in java. With 3 levels of difficulty:
  • get a new List object when calling the operation,
  • reverse in place
    • by iterating on the list,
    • by using recursivity
In itself, it is really not difficult (it shouldn't be). However it really reveals development abilities:
  • use of names conventions
  • use of test-driven development
  • care for limit conditions : null input list, empty input list, list size = 1
  • use of exceptions
  • comments (not so easy to comment that code,...)
  • incremental approach to development
  • use of interfaces (should it work on List also?)
  • this can lead to patterns questions: "what pattern would you use to add that functionality to a LinkedList?"
I don't know how many interviewers really make developers code during an interview, but how would you hire a personal cook? By tasting the food and making sure that the kitchen is clean and tidy, wouldn't you?