Archive for category Mjukvarukvalitet

Code kata: visualizing crontab using “higher level” TDD

For a number of reasons I had to write a snippet of Java code in my spare time. However, I wanted to learn something new, so I treated it as a code kata, the purpose of which was to discover how well you do if you drive your code using higher level tests. So, instead of using class-level unit tests, I wrote tests that exercised 3-4 classes at the same, thus testing the API at the outermost interfaces. This is what I arrived at (click to enlarge):

Until this point, I’ve either been test-driving code using high-level acceptance tests from a framework like Concordion or FitNesse, or tight unit tests. What made me try something new was Uncle Bob’s Transformation Priority Premise in conjunction with the TDD style presented in the book called “Growing Object-Oriented Software Guided By Tests”. Let me explain:

The way I understand the TPP, it makes us narrow our tests and changes as much as possible. By applying tiny transformations we stay very safe. However, there’s the time factor… How many unit tests do you need/want to write, and do they really feel meaningful, or do they need to be written just for the sake of introducing certain branchings in the code?

As for the book… It has it’ goods and bads (I will review it very soon), but what’s special about it is this style of TDD.

So what did I actually implement in this experiment? A simple parser that understands the standard case of the crontab format “* * * * * <command>”, and that can print it to the screen taking different time scopes into account. While I had to stop somewhere (it was a kata after all), I feel that I have discovered enough to present the conclusions. The first test looked sort of like this:

@Test
public void executableScheduledFirstDayOfEveryMonth() {
    CronCommand command = new CronCommand("runme", new DayOfMonthField(1), new HourField(0), new MinuteField(0));
    ExecutionYear executionYear = new ExecutionYear();
    executionYear.addCommand(command);
    final String expectedOutput = "January\n1\t0:00\trunme\n" +
        "February\n1\t0:00\trunme\n" +
        "March\n1\t0:00\trunme\n" +
        "April\n1\t0:00\trunme\n" +
        "May\n1\t0:00\trunme\n" +
        "June\n1\t0:00\trunme\n" +
        "July\n1\t0:00\trunme\n" +
        "August\n1\t0:00\trunme\n" +
        "September\n1\t0:00\trunme\n" +
        "October\n1\t0:00\trunme\n" +
        "November\n1\t0:00\trunme\n" +
        "December\n1\t0:00\trunme\n";
    assertEquals(expectedOutput, executionYear.outputScope(new YearScope(), new StringOutputFormat()));
}

It’s very verbose, but that’s more a result of the fact that I wanted to go for output immediately. At this point your IDE does a lot of work for you by creating all missing classes and methods. But stop, where did all the class and method names come from? They didn’t come into being through emergent design! No, they did not. I actually spent some time thinking about what the correct API should look like. It did evolve over time, but the fundamental structure still remains.

When implementing the functionality, I tried to write good and correct code that would not need a round of refactoring, i.e., I didn’t evolve the code by duplication elimination. That’s not pure TDD either. Of  course, as tests were added, I followed the methodology and removed duplication and refactored both test and production code.

Another sin I committed was mixing in “test-last”. On the whole I relied on the high level tests, but when working with logic I felt uncertain about, I added unit tests until I felt secure again. Since I kept the code very clean with extremely short methods, not many additional tests were required.

The image above shows the coverage I reached using the method, and I think it’s as good as it gets. (Not that coverage says anything about quality, but it shows that no code has been added without being driven by tests).

I guess this technique isn’t controversial for many people, but for me it was. I’ve been stuck doing TDD that’s close to TPP, and I’ve always had to struggle with code locked down by unit tests and package-access methods. This way of working feels very intuitive, and I will definitely explore it further. To sum up:

  1. Come up with a rough design. Think for a while.
  2. Write a high-level test that captures the essence of that design and verifies the API.
  3. Make the test pass, and don’t be stupid about it. Implement the solution well, but without any bells and whistles.
  4. Add another high-level test that captures another aspect of the functionality.
  5. Make it pass, and refactor your existing production and test code.
  6. If you feel uncertain about some logic or boundary conditions, add unit tests that secure that part of the code.
  7. Iterate between steps 4-6.

No Comments

On programming and the thinking process

Once in a while you hear that programmers/developers have strong logical skills, which is why they are drawn to the profession. After years of browsing code I’m not sure if I’d bet my life on it. After all, programming has three elements: sequence, selection and iteration. That’s it.

The ability to combine these into better or worse structures is what distinguishes good software developers from bad ones. Yes, it may be an over simplification, but the fact remains: Sometimes you see programs written in a way that would make you want to switch profession immediately and become a psychiatrist.

You’d like to place the developer in a comfortable couch and ask: What went on in your head when producing this? Do you really need ten levels of nesting to perform a trivial operation on a collection? Is the best way of attacking a sequence of operations by creating a monster method? Are these random names helpful to you in any way? Does commenting the obvious make you feel better? Please explain.

Now to the thinking process. The scary thing is this: If the developer visualizes the solution to standard programming problems using overly complicated and seemingly random code structures, how does the same person view everyday problems like getting out of bed or crossing the street?

No Comments

SSSSS för Java

Det är tråkigt att rippa något rakt av, men det här var så bra att det är värt med lite copy’n'paste. I boken “Implementing Lean Software Development” diskuteras ett verktyg som heter the five S’s.

Principen kommer från Japan och handlar om att organisera sin arbetsplats. S:en i sin tur har sina motsvarigheter på både engelska och japanska.

Sort (Seiri)
Systematize(Seiton)
Shine(Seiso)
Standardize(Seiketsu)
Sustain(Shitsuke)

Fär en längre förklaring hänvisar jag till Lean-litteratur. Det viktiga, eller kanske gulliga är att de fem S:en finns för Java:

Sort - Reducera kodbasens storlek; ta bort död kod. Ta bort:
- Död kod
- Oanvända importer, variabler, metoder, klasser
- Refactora redundant kod

Systematize - Organisera projekt och paket. Allt ska ha sin plats:
- Lös upp cykliska beroenden mellan paket
- Minimera beroenden

Shine - Städa upp. Problem blir synliga i en ren miljö:
- 100% unit-tester gröna
- Test coverage > 80%
- Snabbare unit-tester
- Kolla hur snabbt AllTests körs (lite föråldrat)
- Fixa checkstyle-warningar, PMD-varningar samt Javadoc-varningar
- Fixa TODO:s

Standardize - När allt är rent, behåll det så. Förenkla ytterligare.

Sustain - Gör ovanstående.

Listan har tagits fram av en Kent Schnaith, och jag har knyckt den rakt med små justeringar och översättningar. Tyckte att den var så fin…

No Comments

Code review vs parprogrammering

Vilket är bäst för kunskapsöverföring? Parprogrammering eller code review?
Tanken väcktes efter dagens code review, som innehöll ovanligt många bra diskussioner.

Idag hade vi en code review på ett ganska enkelt stycke kod som ändå hade tillräckligt många guldkorn i sig för att hålla oss syssellsatta. Dessa var:

* Integrationstest av triviala DAO-klasser: Ja eller nej? Spring? Tömma databasen eller lita på rollback?
* XML-serialisering, och vem har ansvaret.
* Ingen domänmodell, och vad gör vi under tiden?
* “Objektorientering”
* Och en massa annat 

Dylika ämnen är representativa för vad vi brukar avhandla och diskutera. Med handen på hjärtat, blir diskussionerna lite väl teoretiska ibland, men det är samtidigt otroligt givande att höra 5+ erfarna utvecklare argumentera för eller emot olika lösningar. Tyvärr blir svaret sällan svart på vitt…

Så som jag väljer att se det är en code review ett överlägset verktyg för inbördes synkronisering och kunskapsöverföring av följande skäl:

1. Gruppen synkroniserar sig i avseende på triviala arbetstekniska detaljer som code conventions.
2. Kunskap om nya verktyg och lösningar bubblar upp, för någon vill alltid styla. 
3. Den vars kod blir granskad får otroligt kvalificerad feedback på det han har gjort. 
4. Guidelines för framtida best practices kan lätt uppkomma under en code review.
5. Alla inblandade lär sig att arbeta med transparens och vänjer sig vid att få sitt arbete granskat. Detta underlättar agilt arbete och kollektivt ägande av kod.
6. Man snappar alltid upp något smart trick ens kollega har implementerat.

Alternativet är parprogrammering, som innehåller alla ovanstående element, men mindre av allting. Självklart löser de som programmerar i par ett konkret problem, istället för att käbbla om teoretiska abstraktioner, men hur man än vänder och vrider på det, så tycker jag att man får mer hävstång i en code review.

Jaja… Det viktiga med inlägget var inte att trasha parprogrammering, utan att promota code reviews. De som inte håller dem regelbundet måste testa!

No Comments

Varför är webbapplikationer ofta dåligt skrivna?

En ofta återkommande kvalitetsfråga är varför webbapplikationer ofta är så dåligt skrivna. Själv har jag erfarenhet av sådana applikationer skrivna i Java, Perl, och PHP.

Eftersom Perl och PHP inte direkt är objektorienterade språk (fastän bägge stödjer grundläggande OO-konstruktioner) verkar webbapplikationen bli en enda stor gegga utan någon som helst uppdelning av innehåll, navigering och presentation. Direkt databasaccess verkar vanligt och alla principer om att skapa lager och abstrahera verkar vara som bortblåsta. Det är inte alls ovanligt med tusentals rader stora filer som förutom att innehålla dåligt HTML även “gör allt”.

I Java-fallet kan man ha en snyggt skiktad backend, men om JSP och servlets blir inblandade kan vad som helst dyka upp. En extremt kraftfull kombination är tabell- och pixel-baserad layout med total oförståelse för JSP, tag libraries och servlets. Det finns inga gränser för hur “intressant” en sådan lösning kan bli.

Sedan har vi så klart diverse ramverk som ska hjälpa oss. Jag tänker faktiskt främst på Struts, men det finns många modernare, som gör ungefär samma sak. Det fina med ramverken är att de ofta är duktiga på “Hello world”-exempel, och är tänkta att leda utvecklaren mot en hållbar lösning genom att begränsa möjligheterna. Min erfarenhet är att så inte är fallet. Oftast kan man inte ramverket och arbetar runt det på bättre, eller oftast sämre, sätt. För att kringgå ramverken krävs oftast en viss typ av kreativitet… Som jag helst inte vill dela mjukvaruprojekt med.

Webbapplikationer är ofta ingångsporten för nya utvecklare och kvalitetsbristerna uppkommer i samband med att utvecklaren varken behärskar grundläggande programmeringsprinciper eller själva ramverket. Som vanligt kan man googla fram en tutorial, men de brukar sluta efter “Hello world”… Så länge detta mönster upprepas får vi nog leva med spagettin.

No Comments

Motargument mot XP:s parprogrammering och kollektiva kodägande

Idag har jag haft en dag, varefter det är enkelt att formulera motargument mot XP:s kollektiva ägande av kod och parprogrammering på detta.

I grund och botten är jag för dessa principer, men ibland kan 1 + 1 bli -1, och eftersom det är nyttigt att argumentera för och emot saker, så lägger vi in argumentet i kvalitetsspåret.

Det kan vara så att jag citerar fel person, men om jag inte minns fel, så är det Brooks som varmt talar om begrepper konceptuell integritet. I ett kapitel om arkitektur menar han att system ska designas av få personer för att just uppnå konceptuell integritet, d v s några få personers samstämda helhetsuppfattning om hur systemet är strukturerat. Ett fåtal personer kan lättare enas kring samma tanke, riktlinjer och designprinciper, och skapar därför någonting som konsekvent håller ihop och följer samma röda tråd.

Detta är motsatsen till kollektivt kodägande och indirekt till parprogrammering. Nu när jag har en dålig dag kan jag påpeka att XP:s principer bygger på att alla har samma uppfattning om lösningen, som känsla för kvalitet och bekantskap för verktygen. Om detta inte är fallet skapas ett system som är summan av olika viljor, idéer och tekniktillämpningar. Skalas detta ner till parprogrammering gäller samma sak här: att ständigt kompromissa fram “bästa lösningen” kan leda till någonting som är optimalt i termer av arbetspaket och dellösningar, men inte håller ihop i det stora hela p g a saknad eller fragmenterad helhetsbild. Alltså avsaknad av konceptuell integritet.

En för extrem variant av XP kan således ha negativ inverkan på såväl arkitektur som throughput. Det senare, eftersom olika personer gör om saker så att de passar in i deras vision.

Kanske lite grinigt, men förhoppningsvis har hänvisningen till Brooks gjort detta inlägg lite tankeväckande.

No Comments

Teknisk skuld vid 1000 rader!

Ok. PHP är inte mitt starkaste språk, och till mitt försvar kan sägas att språket är inherent trasigt. 

Jag har lyckats med konststycket att införa teknisk skuld i ett tusen rader stort CM-system. I detta fall tänker jag inte skylla på PHP 4. Ja, språket har en massa konstruktioner som är byggda för diverse dåligheter, men detta är nog inte problemet.

Jag har helt enkelt bara kodat på och tappat greppet efter tusen rader (fördelade på några filer). Koden var självklart inte objektorienterad och testdriven. Nu är det bara att gilla läget och porta www.techbookreader.com till PHP 5, något slags objektorienterad kod, och lära sig läxan för hundrade gången: bygger du något mot bättre vetande och rådande utvecklingsprinciper, så kommer du att få teknisk skuld omgående!

No Comments

Sätt en siffra på kvaliteten

Detta inlägg förtjänar en helt egen kategori, och jag misstänker att det kommer skapas flera i denna kategori. Som vi vet finns det otroligt många definitioner av kvalitet. Det vore kul att diskutera dem, men temat för dagens inlägg är ett mer konkret case.

Som vi också vet finns det projektledare i branschen som någonstans lär sig att kvalitet är en variabel, precis som tid och scope, som kan varieras. Man hör uttalanden som “good enough”, “det behöver inte vara snyggt, det behöver bara funka” m m. Dessa förtäcker egentligen antagnadet att kvaliteten har fått ett värde mellan noll och ett.

Vi kan hjälpa vår projektledare/chef genom att be om ett värde och ett antal parametrar som kommer att anta detta värde. Låt oss exemplifiera med 80%-ig kvalitet. Det kan t ex betyda 20% nertid, 20% felaktiga skrivningar i databasen, 20% slumpmässig korruption av interna data, 20% av beräkningarna blir fel, eller att beräkningarna blir 20% fel. Vi kan således ställa upp en tabell och rita färgglada staplar, som illustrerar vår målkvalitet. Det borde inte vara så många som committar sig till detta.

Argumentet ovan löser 95% av fallen, men det är bra att diskutera de resterande fem procenten.

1) Otroligt sällsynt, men det finns personer/organisationer som kan committa sig bristande kvalitet, speciellt i kvantativa sammanhang. Alltså: Vi ringer 10000 personer och försöker kränga vår pryl. Vi struntar om 2000 telefonnummer är fel.

2) Tid och scope har verkligen tagit slut, och kan inte varieras. Detta är väldigt sällsynt. Scope kan alltid skäras…

3) Det kända engångshacket. Se då till att inte spara filen med hacket och glöm allt som har med versionshantering att göra.

Det är bra att tänka på de tre antiteserna ovan (säker finns det någon till), men det är inte de som är problemet i kvalitetsdiskussionen med den oinsatte.

No Comments