2014-03-31
Idag kom jag till ett läge där jag ville dra in ändringar som gjorts på origin/master. Jag hade dock gjort ändringar lokalt som jag inte ville commit:a eftersom jag inte visste om de ledde åt rätt håll eller inte. Gjorde git fetch && git rebase origin/master
trots att jag visste att git skulle vägra tt utföra rebase:en. I felmeddelandet som git gav ifrån sig stog det något om "stash". Hmm. Ytterligare ett git-kommando som jag inte vet något om. Man är ju inte direkt någon git-expert... Men man kan ju lära sig...
Googlade lite och hittade lite info om git stash. Det visade sig att git stash låter en spara undan ett ocommittat tillstånd på en stack och återställa branchen till ett tillstånd som om man gjort revert. Sedan kan man göra t.ex. rebase eller merge för att synka branchen med t.ex. origin/master. När detta är gjort kan man återställa de ocommittade ändringarna genom kommandot git stash apply. Lysande! Det var precis det jag ville göra.
Process:
- Kolla att ocommittade ändringar att stasha finns:
git status - Spara undan ocommittade ändringar. Detta kan göras flera gånger för att spara undan olika tillstånd.
git stash
- Inspektera stash-stacken:
git stash list
- Dra in ändringar från origin/master:
git fetch && git rebase origin/master
- Lägga på de ocommittade ändringarna:
git stash apply
- Kolla att de ocommittade ändringarna är pålagda:
git status
2014-04-16
Idag lärde jag mig att uttrycket ${a_string_variable^^}
i bash gör om värdet av variabeln a_string_variable
till upper case. I bash kan man göra mycket, men det blir inte alltid så tydligt...
Analogt gör uttrycket ${a_string_variable,,}
i bash gör om värdet av variabeln a_string_variable
till lower case.
Vill man bara gör om första bokstaven till upper respektive lower case använder man bara ^
resp ,
en gång istället för två.
2014-09-19
Idag när jag satt och skrev ett enhetstest erinrade jag mig att jag sett en kollega lägga in tre rubriker i sina enhetstest. Han använde alltid samma rubriker: Arrange, Act och Assert. När jag såg honom skriva ett enhetstest och lägga in de rubrikerna kommer jag ihåg att jag tänkte något i stil med "Det där ser bra ut. Det skall jag komma ihåg att använda!". Sen glömde jag bort det.
Idag kom jag som sagt i alla fall ihåg att jag sett det och att jag hade tyckt att det var bra. Eftersom kollegan gått för dagen beslöt jag mig för att googla lite för att kolla om man kunde hitta något på nätet. Det kan man ju nästan alltid. Om det inte gäller objektdatabasen Versant i alla fall. Det bästa man kan hoppas på då är en länk till någon obskyr artikel på franska. Huga. Tur att man inte behöver jobba med den databasen längre. MongoDB är en så otroligt mycket trevligare bekantskap. Oracle också förresten och MySQL och Postgres. Egentligen är de flesta databaser ganska trevliga att jobba med. Utom Versant.
Åter till ämnet. När jag sökte på nätet efter unit test arrange act assert fick jag en hel del träffar. Det visade sig att Arrange Act Assert var ett enhetstestmönster som beskrevs 2003. Hoppsan. Det hade jag verkligen missat. Det känns som om man verkligen skulle behöva fortbilda sig de där tre timmarna om dagen som Uncle Bob förespråkar i Clean Code för att hinna hänga med som man borde. Fattar bara inte hur man skall hinna med det. I varje fall visade googlingen att Arrange-Act-Assert är ett allmänt spritt mönster.
Vad går då Arrange-Act-Assert-mönstret ut på? Jo, det går ut på att man delar in sina enhetstest i tre delar där koden i varje del är ansvarig för en viss väldefinierad uppgift. Att de olika delarna kallas för Arrange, Act och Assert är kanske inte så svårt att lista ut, men vad skall då ingå i varje del? Jo...
- Arrange: sätta upp preconditions och skapa data som skall skickas in till koden som skall testas.
- Act: anropa koden som skall testas.
- Assert: verifiera att exekveringen gav det förväntade resultatet.
Ett litet exempel kan kanske var på sin plats. Antag att vi har en klass DoStuffer
som har en metod int multiplyByTwo(int)
. Antag att vi vill enhetstesta den här metoden. Hur kan då ett enhetstest som använder Arrange-Act-Assert-mönstret se ut? Kanske så här:
@Test
public int testMultiplyByTwo() {
// Arrange
int numberToMultiply = 42;
// Act
int restult = unitUnderTest.multiplyByTwo(numberToMultiply);
// Assert
assertEquals("", numberToMultiply * 2, result);
}
}
Vi har här delat upp testet i de tre delar som AAA-mönstret föreskriver. I den första delen, Arrange, sätter vi upp indatat som vi skall mata in till metoden vi skall testa. Här kan man även sätta upp mock-objekt och vilka metodanrop man förväntar sig på dem om det nu är så att man använder något mock-ramverk som t.ex. EasyMock eller Mockito.
I den andra delen, Act utför vi själva anropet till det vi vill testa. Det är också det enda vi gör i den här delen.
I den tredje och sista delen, Assert, verifierar vi att anropet till den metod som skulle testat gav det förväntade resultatet. Om mockobjekt används kan vi här verifiera att de förväntade metodanropen gjordes på dem.
Vad är då fördelen med Arrange - Act - Assert-mönstret? Det verkar ju inte vara något speciellt stort och grandiost mönster direkt. Som jag ser det finns det en rad olika fördelar. En fördel är att det är lätt att se var de olika delarna i testet finns när dessa är väl avgränsade. Kommer man in som ny utvecklare och skall ändra eller utöka ett befintligt test är det lätt att hitta var koden man behöver ändra finns. Behöver man ändra indatat görs detta i Arrange-delen, behöver man ändra själva anropet gör detta i Act-delen och behöver man ändra verifieringen av resultatet görs detta i Assert-delen.
En annan fördel är att man inte frestas att göra "flera tester i ett test". Dvs först testa en sak och verifiera den, sedan testa en annan sak och verifiera den i samma test. Eller ännu värre: blanda flera testaanrop och verifieringar med varandra i en enda röra. Använder man Arrange - Act - Assert-mönstret så tvingas man att separera kod för testuppsättning, testanrop och verifikation. Man kan i och för sig fortfarande testa fler än en sak, men det kräver i så fall att man gör fler än ett anrop i Act-delen, och det har vi ju slagit fast ovan att man inte skall göra;)
Notera att exemplet ovan givetvis är ett mycket enkelt exempel och att de testerna man skriver i verkliga livet oftast är bra mycket mer komplicerade och ofta använder diverse mockramverk. Faktum kvarstår dock. Strukturerar man sina enhetstest enligt Arrange - Act - Assert-mönstret kan man öka läsbarheten och minska kostnaden för underhåll av testen. Inte så dumt.
Länkar:
2014-09-23
Ibland händer det mig att jag träffar på någon sak som får mig att tänka: "det här var ju pinsamt att jag inte kunde". Det händer inte så ofta. Inte på grund av att jag kan så mycket, utan mest för att jag är medveten om hur lite jag kan. Det blir därför inte så pinsamt att erkänna för mig själv och för andra att jag inte kan en viss sak. Men ibland händer det, som sagt var, att jag stöter på något som jag tycker att jag borde kunnat. Idag var en sådan dag.
Kollegan och jag diskuterade ett problem med att skicka UDP-trafik från en dator till en annan. Problemet vi hade var att trots att vi visste att meddelandena skickades från avsändardatorn kom de inte fram till UDP-servern vi startat på mottagardatorn. Jag hade dagen innan kollat upp om det inte var något brandväggsproblem, men det verkade det inte vara. Nu hade i alla fall kollegan löst problemet.
När jag frågade honom hur han löst problemet förklarade han att fixat det genom att starta om UDP-servern och speca dess host till 0.0.0.0 istället för localhost.
- "OK. Hur kunde det avhjälpa problemet?", undrade jag.
- "Startar man en server på adress 0.0.0.0 så lyssnar den på alla nätverksinterface på datorn. Inte bara ett specifikt. Det kan vara bra om det finns flera nätverksinterface på datorn, och så var det i det här fallet. Använde man localhost när man startade började servern lyssna på fel interface".
Aah. Det verkade ju verkligen användbart. Varför visste jag inte om det här? Jag hade sett adressen 0.0.0.0 vid olika tillfällen, men aldrig funderat över vad den kunde betyda. Nu fick jag en anledning att läsa på lite.
Surfade in på in på Wikipedia som jag brukar när jag vill läsa på lite kort om någon sak eller något ämne. Artikeln där listade flera olika användningsområden för 0.0.0.0 varav den sista i listan var just: "A way to specify any IPv4-interface at all". Det stog även att addressen när den användes på detta sätt kallades för INADDR_ANY.
Eftersom wikipediasidan var ganska kortfattad så googlade jag vidare på INADDR_ANY och kom då till man-sidan för IP i Linux Programmers Manual (länk här). På den sidan står följande att läsa om INADDR_ANY: "When INADDR_ANY is specified in the bind call, the socket will be bound to all local interfaces." Dvs precis det som kollegan hade sagt! Inte för att jag för ett ögonblick tvivlade på honon, men det är ju alltid bra att läsa på lite själv ;)
Summa summarum: idag har jag lärt mig att man kan binda till IP 0.0.0.0 för att få sin lyssnare att lyssna på alla lokala interface. Lite jobbigt att jag inte kände till det sedan länge, men det är väl bara att bryta ihop och komma igen som Per Elofsson sa ;)