tisdag 11 december 2012

TDD - behövs ett försvarstal?

Efter en diskunion in Jönköping Developer Dojo om just TDD ser det ut som att jag vill få ner några tankar om ämnet på pränt.

Det fanns en serie argument mot TDD.

  • Jobbigt
  • Ta längre tid
  • Dubbla kodbaser.

Jobbigt.

TDD har sina rötter i XP. I XP så kodar man aldrig ensam. Pair programming (PP) är en disciplin i sig som tvingar utvecklarna att följa ett visst förhållningssätt.

I PP har man två uttalade roller, driver och navigator. Rollen navigator indikerar just det som gör TDD möjlig. Förutsättningen är att man vet vart man är på väg, åtminstone i grova drag. Kanske har man skissat upp sin domän och vet vad man måste lösa. Hela user storyn har brutits ner i mindre delar och man angriper en isolerbar del. 

Detta gör att navigatorn inte sitter bak din rygg och idlar, utan har koll, förståelse för vart man är och vart man är på väg.

Traditionell utveckling sker mer ad-hoc. Man kodar själv och vet vad man måste lösa, men uppgiften man antar har oftast ett större scope. Utvecklingen kanske adresserar allt från persistens till ui (webb utveckling). 

Man har dessutom sällan skissat på en domän modell och ändamål (cohesion) för de klasser man skapar brukar vara låg. Argumenten för detta är ofta något i stil med: -Äh, jag måste bara få det att funka!
Det faktum att man inte på förväg kan säga, ungefär, vilka beroenden man måste mocka bort gör hela processen jobbig.

För att få arbetet mindre jobbigt så behövs det disciplin och en modell. Använder man sig Domain Driven Design (DDD) så har man mycket gratis eftersom DDD ger dig strikta förhållningssätt för din kod och TDD ger dig disciplinen  Det blir lite lättare att säga vart man borde stoppa logik och vilka beroenden man kan / får ha. Man får implicit kravet på sig att rita lite innan man börjar hacka.

http://www.infoq.com/minibooks/domain-driven-design-quickly

Jag skulle vilja säga att den agila processen som helhet kräver mer av utvecklare. Att skriva enhetstest är bara en del. Borta är den bekväma situationen där man bara bockade av punkter i ett användningsfall och gick hem.

Tar längre tid.


Kort sikt

Man måste skriva mer kod :(

Detta är sant. Men det finns många sätt att få upp tempot på testkodning. T ex kan man köra Kator  med målet att lära och tweaka sig sin IDE tills det inte går att göra Katan snabbare. 

Om du sätter dig vid en naken installation av Eclipse och känner att du inte kan använda den eftersom det kommer ta två timmar att få den precis som du vill ha den, då har du lyckats. Om du sätter dig vid din preparerade IDE och det sprutar importer och, via templat, genererade metoder, då har du lyckats.

I den situationen är tanken på att starta din runtime i debug mode för att kontrollera varför en metod returnerar fel värde väldigt långsökt. Du går bara till din testklass, utökar den med de testfall du funderar över. Kanske startar du JUnit processen i debug.

Läs gärna artikeln om just detta:
På längre sikt så är TDD en av de fundamentalt viktigaste delarna för att göra ett projekt: förvaltningsbart. Ett väl skrivet enhetstest är en dokumentation som inte blir inaktuell i takt med förändringar i systemet. Det är så enkelt och samtidigt briljant. Varför kom jag inte på det själv istället för att skapa alla dessa main metoder som man sparade lokalt? Jag kunde bott i Kalifornien och haft fyrtio tusen följare på twitter.

Kent Beck - the inventor of tdd. Yet, he claims he just re-discovered it.

Att man vågar förändra koden skall inte vara kopplat med att man har en dödslängtan eller väldigt dålig riksmedvetenhet.

Till det måste kopplas en process för att hantera teknisk skuld i backloggen. Det kan vi ha en diskussion över en öl om närhelst :)

Mot kunden

Kunden är i ett fåtal fall medveten om hur du skriver kod. Att sälja in TDD är svårt. Att argumentera för att det kommer att ta längre tid pga TDD är oftast omöjligt. Som utvecklare måste man själv nå den skill som krävs för att det inte skall bli en nackdel utan en fördel.

"There is only one way to get to Carnegie Hall-practice, practice, practice!

Dubbla kodbaser.

Att mer kod ökar komplexitet och en ökad kodbas är dåligt av ett antal orsaker är sant. TDD genererar otvetydigt mer kod. Kan man rättfärdiga detta?

Jag hittade en rätt rolig artikel som vände på alla argument för TDD. 10 orsaker att undvika TDD:

Läs punkterna och fundera på om din arkitektur är perfekt?

Personligen gör jag fel och jag har dåligt minne. Ett enhetstest är den dokumentation jag behöver för en klass.

Slutsats


Positiva bieffekter

Om man nu orkar köra TDD så finns det ett antal trevliga bieffekter. Bättre separation av kod och beroenden, högre cohesion och ett system som man vågar ändra i.

Visualisering

Har man en CI server så kan man dessutom koppla in olika verktyg för statisk kod analys. Mycket inom agile handlar om att visualisera. En open source produkt som Sonar gör just detta på ett så fint sätt att det är ett ämne för en helt egen Jönköping Developer Dojo eller @jkpgJUG session :)

Krav på TDD

Missa inte att koppla ditt bygge till en Continuous Integration server. Där körs dina tester löpande av alla som skickar in kod via något versions hantering.

Försök att ha ambitionen att aldrig bryta bygget!

Å andra sidan...

Finns det  en silverkula för allt ?

Har man en avgränsad del, som man bryr sig om. I mitt fall tycker jag om mina favorit appar. De väcker trevliga känslor hos mig och är batteriet urladdat på min telefon så blir jag ledsen. Om jag skulle utveckla den  typen av applikationer så kanske jag skulle agera annorlunda. Jag skulle kanske vara mer noggrann och vurma mer för min kod :)


"Are unit tests an invaluable tool for writing great software?" ...  "yes."
"Am I going to produce a poor product if I can’t unit test?" ... "no."


Åsikter?

Jag är tex väldigt intresserad i hur man gör i Ruby världen. Samtidigt är det mycket väsen om nästa nivå i testandet, Behaviour Driven Development, där Ruby / Cucumber är hett. 

Dessutom har jag till dag dato inte kopplat in JavaScript till någon tdd runner och CI server.



onsdag 31 oktober 2012

Scaling Xebium

Hello.

We really like the Xebium project and we are hoping to use Xebium for our functional testing.

All is well but we have trouble scaling up. Scaling Selenium is no problem with GRID 2 (one server and n node(s)). The unit test running manages to connect to the remote server and the test gets delegated to the node and ran perfectly. But we can’t really get Xebium work towards a Selenium hub.

In the Xebium installation there are an example suite containing the test: “Example 008 Running Tests with Selenium Server”.

Running this test generates the following error:

start browser Could not invoke constructor for StartBrowser[7]
firefox The instance decisionTable_3. does not exist on url
The instance decisionTable_3. does not exist
http://localhost The instance decisionTable_3. does not exist … and so on.

What on earth are we missing?

Environment:
  • Xebium server 
  • Selenium GRID 2 
  • A Selenium Web Driver node with Firefox. 

All three instances are currently on the same machine. A theory we have is that Xebium itself should be started as the server that the nodes should be registered against. But that really does not make sense.

I do not fully (or at all) understand how the Xebium server that wraps both Fitnesse and Selenium maps to the Selenium scaling architecture.

Please advice!

Best regards

@demassinner

måndag 29 oktober 2012

Java är hett i Jönköping

Jag får många frågor om vad man skall läsa på för att möta Java utvecklare kraven i Jönköping. Här kommer en kort sammanfattning.

Teknik

  • Seam 2
    • Bijection
    • Transaktioner (Conversation scope etc)
  • JPA implementation Hibernate 3.4 (ORM framework)
  • JSF (presentation framework)
    • Facelets
    • Richfaces 3.3
  • EJB 3

Infrastruktur

  • Maven 2
  • Jenkins
  • Subversion

SOA stuff

  • JAX-WS
  • JMS

Utvecklingsmiljö

  • Eclipse
    • Findbugs
    • Checkstyle
    • Cobertura

Strange stuff

  • Drools
  • JBoss BRMS

Metodik

  • Rup
    • Användningsfall
    • Arkitekturbeskrivning
  • Agile
    • Scrum
    • Domain Driven Design (DDD)
    • Wiki
    • XP
      • Test Driven development (TDD)
      • Code rules
      • Clean Code

Böker

Jag har läst en del, men dessa bör man inte missa.

Annat

För TDD, kolla på Clean Code filmerna och öva med Katas :)

torsdag 25 oktober 2012

Att välja webbläsare


Många aspekter att ta med i beräkningen.

Att ta fram en ny rekommendation för vilka webbläsare man skall stödja är en utmaning. I arbetet så måste  en mängd aspekter tas med i beräkningen, t.ex. kan man i drift smidigt uppdatera och administrera en viss webbläsare i organisationen.

Avgränsning

Idag har man höga krav på vad man måste kunna göra i webbläsaren. Centralt för många verksamheter är hantering av GIS (Geografiskt Informationssystem). Att kunna interagera med en karta i webbläsaren är ingen enkel uppgift. Med tanke på detta tittar vi gärna framåt (ur ett standard-perspektiv), med intresse på vad som hänt i webbläsarvärlden under senare år.


Jag fokuserar i denna artikel endast på standard- och teknik-aspekten av webbläsare för desktopen - och alltså inte för mobila enheter.


Standarder måste tas i beaktande eftersom den webbläsare som är vanligast i dag kanske inte är det i morgon. Följsamhet gentemot standarder minskar produktberoende och ökar valfrihet!

De tekniska detaljerna som nu följer är en del av det appendix som hör till utredningen.

Appendix A, Teknisk utredning

Standardiseringen görs huvudsakligen av W3C. Begreppet HTML5 är ett paraply för en mängd tekniker som använts på webben och nu standardiseras. Standardiseringsarbetet släpar per definition efter jämfört med innovation. Man standardiserar helt enkelt det som blev bra ute i community-sfären.

Det löpande arbetet (community-sfären) med att driva teknikerna framåt och hantera buggar sköts av WHATWG. Det finns ytterligare grupper att hålla reda på, såsom Khronos. Khronos arbetar för att standardisera WebGL.

De organisationer och företag som står bakom olika browsers är:
TODO: kommentera alla vendors. 

Microsoft

Microsofts Internet Explorer är ökänd för att gärna vilja gå sin egen väg. Detta kan historiskt ses ur två perspektiv
  • Browsern var surf-standard, även om den inte följde W3C standard. När Microsoft väl hade monopol så drev inte företaget plattformen framåt eftersom webben som plattform kunde konkurrera med deras operativsystem.
  • Microsoft är ett företag som inte förespråkar open source, utan hellre säljer propriotär mjukvara. Att måna om öppna standarder och implementera dessa ses inte som en konkurrensfördel.

HTML5 paraplyet

HTML5 är en term som rymmer en mängd tekniker. Dessa tekniker har florerat på webben under en längre tid och standardiseringsprocesserna har börjat hinna ikapp. Frågan är hur bra olika browsers implementerar dessa tekniker. 

Beroende på vad man vill uppnå så får olika tekniker större vikt. Men ett antagande är att nedanstående tekniker kommer att spela en stor roll.

JavaScript motorer

Utan motor går det inte att köra. Utvecklingen av JavaScript-motorerna går snabbt fram och skillnaderna mellan webbläsare och versioner är väldigt stor.

Dessa benchmarks är inte helt enkla att genomföra eftersom de viktiga parametrarna beror på lösningens domän. Dessutom är jämförelserna haltande när det gäller versioner. Chrome är vinnaren just nu. Men grafer kan visa det motsatta eftersom IE 9 jämförs med Chrome 10. Men eftersom Chrome uppdateras med täta intervall så är förhållandet i själva verket det omvända med Chrome v22. Vad gäller Javscript så finns även här standarder att ta hänsyn till.

Vanligt benchmark är Sunspider:

Web Socket

Web Socket (WS) är TCPIP som wrappas av HTTP, vilket används för att strömma data. För att uppnå denna funktionalitet så har tidigare polling  eller long polling använts. Comet  är en samlingsterm för tekniker som möjliggör push av data till browsern och strömning av data.

WS möjliggör så mycket mer, eftersom det ger möjlighet att kommunicera data i båda riktningarna på ett sätt som tidigare bara var möjligt i feta klienter. Vidare ger det bättre möjligheter att komma igenom  brandväggar, proxies och annan infrastruktur.

Google använder i tex Gmail SPDY som måste anses som likt Web Socket. Men eftersom standardiseringen och implementation av Web socket har kommit långt både klient och serversidan är tekniken i talande stund det enklare valet.


Binära data typer

JSON har likställts med webbens binära data format. Men med dagens rika användarinterfaces (UI) så krävs det att man kan hantera binärt data i JavaScript.


Rika renderings möjligheter

Möjlighet att rita upp kartor eller liknande rika ui:n ställer höga krav. I dagsläget använder man en 2D-produkt som heter OpenLayers.

2D
Tvådimensionell grafik uppnås genom att använda canvas som i princip är en yta man kan rita i via ett API. Det finns ett flertal standarder, som SVG, att ta hänsyn till här.

TODO: skriv något om Kanvas och SVG.


3D
För att uppnå tredimensionell grafik så finns det ett flertal tekniker. De proprietära teknikerna har dominerat segmentet under lång tid, såsom Flash och Silverlight. Även här har standardisering börjat hinna ikapp, och WebGL standardiseras av Khronos-gruppen och tekniken implementeras i tex Google Maps.

För Jordbruksverket är det mycket intressant att se på GeoExt som är den centrala kart-komponenten i GEO-dataapplikationer. Version 3 av GeoExt kommer att vara baserad på WebGL med bakåtkompabilitet för browsers utan stöd för WebGL.


CSS3

Teknik för att lägga stil på DOM:en. Eftersom tekniken har bliv allt mer kraftfull så glider dess användningsområde ihop med andra renderingstekniker.

CSS3 transitions
CSS3 transforms

TODO: skriv något om detta.

Cache

För att uppnå en snabb och smidig applikation så är lokal cache en nödvändighet. Områdena som man läser med olika tekniker är många och beror på domänen.

TODO: skriv något om detta.


Web workers

JavaScript är körs med en tråd, dvs single threaded. För att göra tunga beräkningar i browsern så måste man kunna tråda av processer. Detta löses genom tekniken Web Workers.

http://caniuse.com/#search=web%20workers

Denna teknik har ingen koppling till Document Object Model (DOM) utan får instruktioner och data via message passing. Denna teknik har lider av att den tidigare skett genom  ”by value”. Om den skall vara effektiv så måste kommunikationen ske ”by reference”, med hjälp av sk Transferable Objects. 

Endast browser som är baserat på Webkit, exempel: Chrome >= 17, stödjer denna teknik. 

Slutsats

Chrome dominans!

TODO: skriv något om detta.

Källmaterial

HTML5







tisdag 16 oktober 2012

Law!


För flera år sedan rammade jag på ett antal artiklar om principer och lagar när det gäller UX. Inget man normalt hittar på alla dessa UX sajter. Speciellt Laq of Proximity är intressant. Får iallafall mig att inte rama in allt som tillhör en grupp utan kanske bara separera det med lite    luft    .

Law of common faith:
http://ezinearticles.com/?Gestalt:-Law-of-Common-Fate&id=146000
Law of Similarity
http://psychology.about.com/od/sensationandperception/ss/gestaltlaws_2.htm
Law of Pragnanz
http://psychology.about.com/od/sensationandperception/ss/gestaltlaws_3.htm
Law of Proximity:
http://psychology.about.com/od/sensationandperception/ss/gestaltlaws_4.htm
Law of Continuity
http://psychology.about.com/od/sensationandperception/ss/gestaltlaws_5.htm
Law of Closure
http://psychology.about.com/od/sensationandperception/ss/gestaltlaws_6.htm

fredag 31 augusti 2012

Kod templat i eclipse för att snabba upp TDD.

I testdriven utveckling så är det repetitivt så att man börjar med testa att det går att skapa en instans av klassen som skall testas. Kod:

package se.sjv.samladkundbild.infrastructure;


import static org.testng.Assert.assertNull;
import org.testng.annotations.Test;
import se.sjv.samladkundbild.domain.entity.Kund;

public class KundQueryImplTest {

    @Test
    public void testCreate() {
        final KundQueryImpl sut = new KundQueryImpl();
        assertNotNull(sut);
    }


}

Livslängden för metoden är kort. När man skapat nästa metod så har man troligen gjort det genom att byta namn på create eller raderat den.

Dessutom så vill du ha med dig en massa junk i form av beroende till tex testNG och Mockito. Dessa importer vill man absolut inte reppetera för varje testklass man skapar. Momentet bör automatiseras så mycket det går.

Eclipse Templates

Templates to the rescue! Nås via:
/ Windo / preferences / Java / Editor / Templates

Här är mitt Eclipse templat för att skapa koden.

${staticImport:importStatic('org.testng.Assert.*')}
${imp:import(org.testng.annotations.BeforeMethod,org.testng.annotations.Test,org.mockito.Mockito)}

@Test
public void testCreate() {
    ${type} sut = new ${name};
    assertNotNull(sut);
}

Jag har bundit templatet till "create" och skriver altså följande:

create, Ctrl + space + enter

Väl inne i test stim så skapar man testmetoder en serie testmetoder. För detta använder jag följande template:


@Test
public void test${name}() {
${staticImport:importStatic('org.testng.Assert.*')}
${imp:import(org.testng.annotations.BeforeMethod,org.testng.annotations.Test,org.mockito.Mockito)}
${cursor} 
}


Jag har bundit templatet till "test" och skriver altså följande:

create, Ctrl + space + enter

som jag nämnde ovan så kan man radera create metoden efter att ha skapat en eller flera testmetoder.

Om du vill ladda ner templaten här:
https://www.dropbox.com/home/java/eclipse/public

Glöm inte att tweaka Eclipse så den gör precis som du vill:
http://sweethashtag.blogspot.se/2012/08/saker-jag-gor-for-varje-nytt-eclipse.html


Happy coding.

onsdag 29 augusti 2012

Varför GIT, det är ju inget fel med Subversion?

Den här frågan dyker helatiden upp. Jag använder båda men kan ibland känna mig lite dum eftersom alla andra ser ljuset så klart, men inte jag.

Jag kanske har sett ljuset, men jag kan inte förklara det. Vilket är lika illa i min värld.Distribuerat versions system
Yes, vi vet! GIT är distribuerat.
  • Alla har sin egen version av alltihop.
  • Man kan brancha ut lokalt.
    Utan att påverka omgivningen kan du skapa branches, merga och leva rövare.

Staging area

Du har en area som man kan trycka upp commits till innan man verkligen commitar. Helt tokigt! Precis vad jag alltid önskat!

Ponera att du skall fixa en bugg. Men koden i klassen ser ut som crap.

  • fixa buggen
  • Kör: git add.
    Du har nu stagat din förändring.
  • clean da code
  • git commit -m 'fixa buggen är nu i lokalt repo men inte min clean'

Det är faktiskt inte otrevligt att liksom lasta av det viktiga, det som skall med i en commit. Sammtigt som man kan fortsätta med att kanske rensa.

Mindre trevligt är att Git envisas med att blanda begreppen i en, för dem säkert helt tydlig, soppa.
http://www.benspaulding.us/weblog/2009/mar/17/git-staging-call-it-what-it-is/

Rename och move

GIT är bättre på att klara av det blotta faktum att man flyttar runt och refakturerar på saker. Det här är minsann inte en liten skillnad. Så använd inte git mv för det behövs inte.

http://stackoverflow.com/questions/6172037/really-a-concrete-example-that-merging-in-git-is-easier-than-svn

Debugging

Massively cool, git blame och git bisect. Mest coolt för att jag inte förstår riktigt ännu. But I will!

Socialt

Git är socialt också. Man kodar och commitar i en eufori av att få lägga sin fritid på kodande. Jag köper det rakt av :)

www.github.com

Övriga Källor

måndag 27 augusti 2012

Saker jag gör för varje nytt Eclipse workspace jag skapar

Detta är mitt första blogginlägg. Och så väljer jag att blogga om något så tråkigt som Eclipse inställningar, #dear.

TOC:

  • Konsoll utskrift
  • Validation
  • Checkstyle
  • Code templates *
  • JRebel
  • Findbugs
  • Templates *
  • Favorites
  • Utseende och snabb knappar *
  • Maven

Innan man gör sina Eclipse inställningar så måste man installera alla fina plugins. Dessa blir en del av Eclipse installationen och kommer inte att behöva göras om för varje workspace. TODO:Eclipse Plugins du inte kan leva utan.

Allt hittas under window/preferences.

Det är bara att erkänna. Jag borde automatisera det här. Men eftersom man är bekväm så väntar man på att någon annan skall göra det. Kanske har någon redan gjort det? Om du kan hjälpa mig att effektivisera detta så är jag mycket tacksam.

Vissa saker kan man exportera / importera mellan workspaces vi tex filer. Andra åtgärde måste man helt enkelt göra manuellt. Rubriker markerade med * kan man importera / exportera.

Konsoll utskrift

/run/debug/
bocka av: Limit console output.
Default trunkerar konsollen efter x antal rader.

Validation

/validation/
Backa av allt under Build som inte är ett måste för att projektet skall köra. Dear det gör skillnad :)

Code templates *

/Java/Code style/Code template
Importera:
  • Clean up
  • Code template
  • Formatter
Clean up och Formatter gör saker med din kod. De spar dig massor av knapptryckningar och du blir en bättre människa :)

Ladda ner dem här: Eclipse code style
TODO: Läs den detaljerade beskrivningen här.

Checkstyle *

/checkstyle/
Importera Checkstyle inställningarna samt sätt på checkstyle på alla projekt.
Ladda ner dem här: Checkstyle conf
När du importerar kontrollera att projekten kör med rätt profil.

Till skillnad från Code templates så gör checkstyle inget med din kod, den bara gnäller. Och som den gnäller, ojoj! Men rätt tweekad och med lite vana så är den en kompis du inte vill vara utan.

TODO: Läs den detaljerade beskrivningen här.

JRebel

Det finns vissa saker man måste kosta på sig, JRebel ären sådan. JRebel kommer att göra din värld mindre smärtsam, speciellt om du kör webb utveckling.

Om du kör maven, lägg till nödvändig Jrebel xml grunkor i parent pom.
Lägger till jrebel.xml till src/main/java samt src/main/webapp i alla projekt.

Findbugs

/findbugs/
Aktivera findbuggs för projekten. Bocka i: Run automatically. Jag har inte gjort någon förändring i Findbugs, den är bra som den är. Precis som checkstyle så gör Findbugs inget med din kod, den bara gnäller.

Templates *

Java / editor / templates
Lägger till mina kod templates för att snabba upp TDD:n.
Ladda ner dem här: Kod templates
TODO: Läs den detaljerade beskrivningen här.

Favorites

Java / editor / favorites
Lägg till alla de statiska importer som du använder ofta.

Exempel:
org.mockito.Matchers
org.mockito.Mock
org.testng.Assert
org.testng.Assert.fail

Utseende och snabb knappar *

Följande två inställningar exporteras och importers lätt via: file / export / general: apperance och keyes.

Java / apperance / Members sort order
Ställer om hur Eclipse sorterar klassernas medlemmar. Publika först och default sist.

General / keysEftersom jag inte står ut med default kombinationerna för att köra mina enhets tester så gäller tweakningen främst dem.

Alt + G -> Generate getter and setter.
Alt + R -> Run TestNG test
Alt + T -> Debug TestNG Test
Alt + C -> Clean
Alt + S -> Sort members
Ctrl + J -> Jump to Test / Member under Test

Maven

/ maven /

Kör du maven och Eclipse så är det i allmänhet lite synd om dig. Men glöm inte att ta ner javadoc och källkod. På så vis så får du intellisense och kan debugga även på inkluderade artifakter.

Bocka i:
  • Download Artifact sources
  • Download Artifact JavaDoc

Sweet, u are all prepared.