Att lära sig av kodanalys



Relevanta dokument
Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

F4. programmeringsteknik och Matlab

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Verktyget FindBugs. Djupstudie i kursen EDA 270 Coachning av programvaruteam. Christofer Bach dt05cb6 Daniel Nilsson dt05dn4. Lunds Tekniska Högskola

Att skriva till och läsa från terminalfönstret

Editering, Kompilering och Exekvering av Javaprogram

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Labb 1: Vad, hur, och varför?

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

725G61 - Laboration 7 Implementation av ett API. Johan Falkenjack

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

DAT043 Objektorienterad Programmering

Eclipse. Avsikt. Nu ska ett fönster liknande figuren till höger synas.

Idag. Exempel, version 2. Exempel, version 3. Ett lite större exempel

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl

Verktyg och Utvecklingsmiljö. Föreläsning 2 Eclipse

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Objektorienterad Programkonstruktion. Föreläsning 4 8 nov 2016

Djupstudie Verktyg för att förebygga problem i källkod. Anders Forslund Anders Lund

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 2

Chapter 4: Writing Classes/ Att skriva egna klasser.

Översikt 732G11 PROGRAMMERING 1. Personal. Kursens mål. Litteratur. Kursens innehåll

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Petter Berglund. Sammanfattning

NetBeans 7. Avsikt. Projektfönster

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Objektorientering. Objekt och metoder. Objektorientering. Viktiga begrepp. Klass. Objekt. Deklarativ programmering

Examination i. PROGRAMMERINGSTEKNIK F1/TM1 TIN212 (Dugga) Dag: Onsdag Datum: Tid: (OBS 3 tim) Rum: V

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design Alex Gerdes, 2016

Tentamen FYTA11 Javaprogrammering

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

Laboration 10 - Eclipse

NetBeans 5.5. Avsikt. Projektfönster

Outline. Objektorienterad Programmering (TDDC77) En frukt har ett namn. Man kan lägga en frukt i en korg... Hashing. Undantag. Ahmed Rezine.

Objektorienterad programmering i Java Undantag Sven-Olof Nyström Uppsala Universitet Skansholm: Kapitel 11

Objektorienterad Programmering (TDDC77)

Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU

Att deklarera och att använda variabler. Föreläsning 10. Synlighetsregler (2) Synlighetsregler (1)

Djupstudie Code smells / Refaktorisering. Martin Larsson dt08ml5 Stefan Johansson, dt08sj7

TENTAMEN OOP

Classes och Interfaces, Objects och References, Initialization

Användarhandledning Version 1.2

Objektorienterad programmering i Java

TENTAMEN PROGRAMMERING I JAVA, 5P SOMMARUNIVERSITETET

2I1049 Föreläsning 5. Objektorientering. Objektorientering. Klasserna ordnas i en hierarki som motsvarar deras inbördes ordning

Objektorienterad programmering i Java Undantag Sven-Olof Nyström Uppsala Universitet Skansholm: Kapitel 11

Programmeringsteknik och Matlab. Dagens program. Viktiga datum. Repetitionsexempel. Repetition av if/else, for, while och Scanner

Lösningsförslag tentamen FYTA11 Java

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

Verktyg och Utvecklingsmiljö. Jochim von Hacht

Föreläsning 3-4 Innehåll

Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Jonas Lindgren, Institutionen för Datavetenskap, LiU

TENTAMEN. Kurs: Objektorienterad programmeringsmetodik 5DV133 Ansvarig lärare: Anders Broberg. VT-13 Datum: Tid: kl

Arv. Fundamental objekt-orienterad teknik. arv i Java modifieraren protected Lägga till och modifiera metoder med hjälp av arv Klass hierarkier

Föreläsning 10 Datalogi 1 DA2001. Utskrift på skärmen. Syntax. print( Hej ) Hur är det? Hej. print( Hej,end= ) print( Hur är det? ) HejHur är det?

Introduktion till Datalogi DD1339. Föreläsning 3 29 sept 2014

Verktyg för statisk kodanalys

Lösningsförslag till omtentamen för TDA540 Objektorienterad Programmering

OBJEKTORIENTERAD PROGRAMVARUUTVECKLING. Övningstentamen 1

Vad kännetecknar en god klass. Vad kännetecknar en god klass. F12 Nested & Inner Classes

Tentamen Programmering fortsättningskurs DIT950

Command line argumenter. Objektorienterad Programmering (TDDC77) Vad blir resultatet? Nu då? Ahmed Rezine. Hösttermin 2016

Objektorienterad Programmering (TDDC77)

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Inledande programmering med C# (1DV402) Ditt första C#-program med Visual Studio

Översikt MERA JAVA OCH ECLIPSE. Uttryck och tilldelning. Uttryck och tilldelning. Uttryck och tilldelning. Uttryck och tilldelning

System.out.println("Jaså du har "+ antalhusdjur+ " husdjur"); if ( antalhusdjur > 5 ) System.out.println("Oj det var många);

DIAGNOSTISKT PROV. Tid. Hjälpmedel. Antaganden. Rättning. Övrigt. Diagnostiskt Prov. Klockan Inga

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Diagnostiskt Prov. Antaganden Om förutsättningar saknas I en uppgift skall rimliga antaganden göras och nedtecknas.

"if"-satsen. Inledande programmering med C# (1DV402)

Kompilera och exekvera Javakod

TUTORIAL: KLASSER & OBJEKT

Innehåll. dynamisk bindning. och programmering CRC) u Arv, polymorfi och

Föreläsning 2 Programmeringsteknik och Matlab DD1312. Programspråk. Utskrift på skärmen

Typkonvertering. Java versus C

Tentamen i Grundläggande programmering STS, åk 1 fredag

Objektorienterad programmering E. Telefonboken, än en gång. Gränssnitt. Telefonboken med gränssnitt specificerat, del 1.

Grundläggande programmering med C# 7,5 högskolepoäng

Föreläsning 2 Programmeringsteknik DD1310. Programmering. Programspråk

Föreläsning 2 Programmeringsteknik och C DD1316. Programmering. Programspråk

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Uppgiften är att beskriva en kvadrat i ett Java program. En första version av programmet skulle kunna se ut så här:

Objektsamlingar i Java

Lösningsförslag till tentamen för TDA540 Objektorienterad Programmering

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Muddy. Funktioner / metoder. Punktnotation. Evalueringsordning

DAT043 Objektorienterad programmering för D, DIT011 Objektorienterad programvaruutveckling för GU

tentaplugg.nu av studenter för studenter

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

Klasshierarkier - repetition

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 2 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 3

Objektorienterad programmering. Fält som funktionsresultat. Mer om fält: att uppdatera ett parameterfält. Kontrast: Parametrar av primitiv typ

Transkript:

Att lära sig av kodanalys Om att använda kodanalysverktyg i utbildningssyfte tillsammans med XP Daniel Bengtsson, c02db@student.lth.se Mikael Piotrowski, c04mpi@student.lth.se Lunds Tekniska Högskola den 20 februari 2007

1 Abstract Det finns ett flertal verktyg för statisk kodanalys tillgängliga. Går det att använda sig av dessa i utbildningssyfte? I den här studien gör vi dels en jämförelse mellan några olika verktyg för kodanalys och en diskussion kring hinder och fördelar med kodanalys i kursen Programvaruutveckling i grupp - projekt. Rapporten avslutas med tips om hur man som bäst kan införa kodanalysverktyg i kursen. 2 (18)

2 Inledning Denna rapport är resultatet av en djupstudie i kursen Coaching av programvaruteam, vårterminen 2007. Syftet med denna studie är att undersöka möjligheten att använda verktyg för statisk kodanalys som ett komplement i pågående programmeringsutbildning. Verktyg som utför en statisk kodanalys innebär att kontroller utförs utan att någon exekvering av kod behövs. Det finns olika typer av kodanalysverktyg: dels verktyg för stilanalys och dels verktyg för bugganalys, så kallade style checkers respektive bug checkers. Förutom dessa typer av analys så finns det även kodanalysverktyg som undersöker beroenden och paketkomplexitet, t.ex. Lattix, JDepend och NDepend. Dessa är dock ämnade åt större projekt för mjukvaruarkitekter som behöver en översiktlig bild som stöd. Eftersom studenternas projekt inte blir särskilt stort så kommer rapporten att enbart titta på några enkla kodanalysverktyg. Djupstudien består av två delar: dels en recension av kodanalysverktyg och dels en praktisk jämförelse av verktygen. I djupstudien jämförs verktygen PMD, FindBugs och Checkstyle. Jämförelserna mellan verktygen genomförs med hjälp av programmeringsteamen i kursen Programvaruutveckling i grupp projekt vårterminen 2007 [3]. I djupstudien undersöks studenternas attityd till kodanalys och vad de kan lära sig av verktygen. Från studien vill vi få svar på följande frågor: Kommer framtida studenter att ha nytta av kodanalysverktyg i kursen Programvaruutveckling i grupp - projekt? Vilken typ av verktyg är bäst lämpad för kursen? Följande avsnitt i rapporten recenserar tre olika verktyg för statisk kodanalys. Vidare följer en jämförelse mellan projekt med samtliga verktyg. Till slut avslutas rapporten med en diskussion vad kan motivera ett team till att använda och dra lärdom av statisk kodanalys. 3 (18)

3 Recension Det finns ett flertal verktyg för statisk kodanalys av Java-program. Statisk kodanalys innebär att programmet inte behöver exekveras för att analyseras. Vi har valt att beskriva tre olika verktyg: Checkstyle, FindBugs och PMD. Checkstyle och PMD är stilanalysverktyg och FindBugs är ett bugganalysverktyg. 3.1 Checkstyle Checkstyle är ett lättviktigt källkodsanalysverktyg som kontrollerar att ett utvecklingsteam följer kodkonventionerna för ett programmeringsprojekt [4]. Checkstyle finns tillgängligt som plugin för Eclipse och andra integrerade miljöer. Som standardinställning följs Suns kodstandard för Java [2]. För att använda Checkstyle efter installation i sitt Eclipse projekt måste man först aktivera det i projektets inställningar. Man kommer åt dessa inställningar genom att gå till Project > Properties i menyn och letar efter inställningarna för Checkstyle där. Det finns en kryssruta för att aktivera Checkstyle för projektet. Figur 1 Inställningarna för Checkstyle i Eclipse Checkstyles kontroller sker i Eclipse automatiskt varje gång som javaklasserna byggs om. Alla anmärkningar presenteras via Eclipse problemvy och som markörer i editorn. Man kan säga att verktyget fungerar som en utökning av Eclipse egna källkodskontroll vilket gör att man kan använda Checkstyle under tiden som man utvecklar sitt program. 4 (18)

Figur 2 Checkstyles anmärkningar fungerar som utökning av varningar i Eclipse Man är inte bunden till att använda alla kontroller i Checkstyle då dessa kan konfigureras för varje projekt genom att utvecklaren väljer vilka kontroller som denne vill ha. Det går att utöka källkodsanalysen med att skriva en egen kontroll enligt Checkstyles API som är en implementation av designmönstret Visitor. Källkoden traverseras och byggs upp som ett träd som sedan vistas av alla valda kontroller. Checkstyle har några grupper av kontroller som standard. Dessa kontrollerar javadoc kommentarer, namnkonventioner, filheaders, importer, storleksöverträdelser, whitespace, modifierare, kodblock, klassdesign, duplicering och det finns också en grupp som har hand om vanliga mätningar i kodkomplexitet. Även om Checkstyle har en del kontroller för mätningar som cyklisk komplexitet och storlek av klasser så är dess huvudsyfte att se till att man följer kodkonventioner i javakod. Eftersom Checkstyle kan användas under tiden som en utvecklare skriver kod kan det verka en aning pedantiskt av verktyget att ge anmärkningar för allt som man skriver. Men även om det kan gå på nerverna för en utvecklare så är det en ganska praktisk lösning att hålla sig till en kodstandard. Alternativet är annars en långdragig politisk debatt inom ett utvecklingsteam om vad som fungerar eller får kastas. 3.2 FindBugs FindBugs hittar problem i program genom att jämföra programkoden med olika s.k. buggmönster [5], [6]. Buggmönster är kodmönster som är kända för att leda till fel i programmet. Det vanligaste är att dessa kodmönster gör något annat än vad de ser ut att göra. FindBugs letar också efter en del mönster som inte är buggar men som vanligtvis är onödiga, t.ex. s = new String("hej") som kopierar den ursprungliga strängen till ett nytt objekt. Vanligtvis kan man skriva s = "hej" istället. 5 (18)

Det finns ett Eclipse-plugin som kan hämtas via Eclipse Update Manager på länken http://findbugs.cs.umd.edu/eclipse/. När det är installerat högerklickar man på den fil eller den mapp som ska kontrolleras väljer menyalternativet Find Bugs > Find Bugs. Resultatet visas som varningar i fönstret Problems och som små ikoner i källkodsfönstret, se Figur 3. En mer ingående beskrivning finns i manualen på FindBugs hemsida. Figur 3 FindBugs i Eclipse Fördelen med verktyg som FindBugs är att de leder en till de områden i koden som troligtvis är buggar, medan stilanalysverktyg är mer känsliga och åtminstone i våra egna tester ger fler varningar. En nackdel med FindBugs är att det inte verkar gå att ignorera varningar för ett visst ställe i koden. Om man konstaterat att en av varningarna är felaktig vill man inte att verktyget ska klaga på samma ställe nästa gång man använder det. Det går visserligen att stänga av varningar av en viss typ, men i så fall kanske man missar en bugg på ett annat ställe. 3.3 PMD PMD, en förkortning som inte har någon officiell förklaring, inspekterar källkod i Java efter potentiella problem [7]. Det finns plugin för PMD till olika utvecklingsmiljöer bl.a. Eclipse. Alla anmärkningar som PMD hittar klassificeras efter hur allvarliga problemen är. De regler som utser anmärkningarna kan i sin tur filtreras inom ett projekt. Dessutom kan nya regler skrivas till PMD antigen som en Java-klass eller uttryckt i XPath. Verktyget har ett antal olika regelkategorier exempelvis grundläggande regler, designmässiga regler, storlekskontroll och kontroversiella regler. Samtliga regelkategorier och deras regler finns listade på hemsidan. PMD är inte kopplad till en viss kodstandard istället kontrolleras att koden följer generell programmeringspraktik. Fördelen med detta är att verktyget koncentrerar sig på mönster där fel lätt kan uppstå. Nackdelen är att verktyget är långsamt jämfört med FindBugs och Checkstyle. Tyvärr var det plugin som finns till Eclipse för tillfället instabilt. Vissa installationer fungerar utan några problem, medan andra installationer knappt fungerar. 6 (18)

Figur 4 Beskrivning av en PMD regel som ger en anmärkning i källkoden 7 (18)

3.4 Jämförelse mellan verktygen I Appendix A Exempelprogram finns ett exempelprogram som visar vissa av de fel som verktygen anmärker på. Vi har valt att filtrera bort Checkstyles anmärkningar om tabbar eftersom detta ger varningar på nästan varenda rad i koden. Tabell 1 visar en översiktlig jämförelse mellan de tre verktygen. Samtliga verktyg finns som plugin till Eclipse. I dessa plugin finns det möjlighet att konfigurera vilka regler som verktygen ska använda vid analysen. Det finns också möjlighet att anpassa reglerna och lägga till egna. Checkstyle och FindBugs visar sina anmärkningar som Eclipse-varningar. Detta kan göra det svårt att skilja på de varningar som Eclipse genererar och de varningar som verktygen genererar. PMD visar sina anmärkningar i en egen lista. Både FindBugs och PMD ger användaren möjlighet att läsa mer om anmärkningen i Eclipse medan man i Checkstyle är hänvisad till informationen på verktygets hemsida. Den information som PMD ger är vanligtvis tydligare i jämförelse med de andra verktygens och har även konkreta exempel. PMD innehåller en del funktioner för bugganalys och är därmed lite mer generellt än Checkstyle. Å andra sidan håller den sistnämnda hårdare på att koden ska följa en specificerad kodstandard. Checkstyle FindBugs PMD Typ av analys Statisk analys av källkoden Statisk analys av den kompilerade koden Stilanalys Ja Nej Ja Bugganalys Nej Ja Delvis Icke-optimal kod 1 Nej Delvis Delvis Tabell 1 Jämförelse mellan verktygen Statisk analys av källkoden 1 T.ex. onödiga objektinstantieringar 8 (18)

4 Analys av verktygen I detta avsnitt redovisas resultatet från en testkörning av verktygen på källkoden hos utvecklingsteamen i Programvaruutveckling i grupp projekt vårterminen 2007. Testerna har utförts mellan iteration fyra och fem, vilket betyder att två tredjedelar av projektets iterationer har genomförts. En jämförelse mellan verktygens resultat och teamens uppfattning om sin kodkvalitet görs i avsnitt 5.2. 4.1 Checkstyle Team 1 2 3 4 5 6 7 8 9 10 Checkstyle 1681 978 3049 1521 1137 913 506 1906 1585 1422 Tabell 2 Antal anmärkningar som Checkstyle rapporterade på teamens källkod. Checkstyle är inställt på att följa Suns Javakonventioner, modifierat för att passa Eclipse. Om teamen valt att använda en annan kodkonvention eller, vilket är troligare, en modifierad variant av denna kodkonvention kommer Checkstyle att ge många falsklarm. De flesta av ovanstående anmärkningar bygger på att det saknas mellanslag, exempelvis mellan ordet if och den efterföljande startparentesen. För att använda verktyget på bästa sätt måste man antigen följa Suns Javakonventioner eller anpassa Checkstyle till sin egen kodstandard. Annars ger verktyget för många anmärkningar vilket motverkar dess syfte. 4.2 FindBugs Team 1 2 3 4 5 6 7 8 9 10 FindBugs Errors 43 27 70 34 24 9 18 36 44 38 Tabell 3 Antal anmärkningar som FindBugs rapporterade på teamens källkod. FindBugs är det verktyg som ger minst antal anmärkningar, vilket beror på att verktyget letar efter buggar istället för att analysera källkodens stil. Det fel som blir mest anmärkt är nullpekarfel, t.ex. när oinitierade variabler används eller där det borde finnas tester för null. Ett annat fel som upptäcktes var koden s == "", som ser ut att testa om variabeln s är en tom sträng. I verkligheten testas det om variabeln s refererar till strängliteralen "". Vill man testa om två strängar har samma innehåll ska man använda metoden equals(object) och vill man, som i det här fallet, testa längden på en sträng ska man använda metoden length(). Det här kan vara en ganska svårhittad bugg, eftersom tomma strängar ibland refererar till den tomma strängliteralen och ibland inte. Ett exempel på när en tom sträng inte refererar till den tomma strängliteralen är om strängen skapats dynamiskt 9 (18)

4.3 PMD Team 1 2 3 4 5 6 7 8 9 10 Basic Rules 1 5 11 5 8 2 8 5 23 6 Braces Rules 38 15 42 55 15 20 2 37 58 28 Code Size Rules 2 2 11 8 3 0 2 13 6 7 Coupling Rules 12 16 11 20 14 9 14 16 17 15 Design Rules 21 45 40 53 39 27 30 25 67 37 JUnit Rules 20 32 2 36 3 4 17 4 29 50 Naming Rules 66 56 87 60 23 45 26 56 96 180 Strict Exception Rules 0 5 4 0 0 1 0 0 0 1 String and StringBuffer Rules 24 5 31 21 3 16 6 14 14 29 Totalt 184 181 239 258 108 124 105 170 310 353 Tabell 4 Antal anmärkningar som PMD rapporterade på teamens källkod. Vi har gjort en mer ingående analys av vilka regelkategorier som ska användas i PMD. Anledningen är att man annars får många anmärkningar ifrån kategorier som är irrelevanta. De regelverk vi har valt är de som man bör känna till eller ger något mervärde för studenterna som utför projektet. Av de grundläggande reglerna, Basic Rules, ser vi att de flesta gillar att skriva nästlade ifsatser. Exempel: if (a) { if (b) { } } som kan skrivas till if (a && b) { }. Parentesreglerna, Braces Rules, varnar för att man inte använder klammerparenteser även om villkorsblocken är en rad lång. Anledningen är att en utvecklare kan råka ta bort raden som påverkas av villkoret, vilket gör att villkoret påverkar nästa rad istället. Kodstorleksreglerna, Code Size Rules, kollar på storleken och den cyklomatiska komplexiteten hos klasser och metoder [8]. Kopplingsreglerna, Coupling Rules, vill att man ska deklarera eller returnera supertypen av en klass istället för den konkreta klassen. Designreglerna, Design Rules, anmärker t.ex. på att en abstrakt klass ska ha abstrakta metoder. De flesta anmärkningar som gavs för samtliga projekt var fält som aldrig omdefinieras kan lika gärna deklareras som final, en designprincip som de flesta studenter säkert inte har tänkt på tidigare. JUnit-reglerna anmärkte mest på att studenterna inte ger meddelanden för sina asserts eller att det finns testmetoder som saknar assertion. Namnreglerna, Naming Rules, kontrollerar att man inte skriver för långa eller för korta metodnamn eller variabelnamn. Kan verka en aning pedantisk eftersom det är många fall där korta variabelnamn är ganska klartydliga i sitt sammanhang. 10 (18)

Strikta undantagsregler, Strict Exception Rules, anmärkte mest på att man fångar och sedan kastar vidare utan att göra något med dem. Man ska även undvika att kasta de generella undantagsklasserna RuntimeException, Exception, Throwable eller Error. Strängreglerna, String and StringBuffer Rules, anmärkte som mest återkommande strängliteraler och strängkonkateneringar inom en StringBuffer.append(). 11 (18)

5 Slutsatser och framåtblickar 5.1 Motivation för statisk kodanalys Man kan ställa sig frågan varför verktyg statisk kodanalys finns och används. Programmerare som använder sig av dessa verktyg flitigt är medvetna om att människan gör misstag. I jämförelse mot människan så är datorn en kall, effektiv räknare, strikt och väl mottaglig för instruktioner. En människa kan inte lära sig alla goda praktiker på en gång och därför kan verktygen också lära en att hålla sig till nya kodpraktiker som man kanske inte hade någon aning om tidigare. En dator är ett idealt verktyg för att granska kod med. Den behöver bara sägas åt att vissa saker får en programmerare inte göra med källkod. Verktyg för statisk kodanalys kan producera en väldigt stor mängd data och anmärkningar, en del av dessa kan vara oriktiga eller irrelevanta, s.k. false positives. Dessa anmärkningar kan vara intressanta att titta på, men vad ska en programmerare göra med dem? En risk är att verktyget används som en lapplisa som bötfäller programmerare för att denne inte skriver på det sätt som verktyget vill. Speciellt märks detta om verktyget införs i ett projekt utan någon tanke för hur utvecklingsteamet ska använda det. Det är upp till utvecklaren eller teamet att vraka bland alla regler och mätningar för att se vad som är relevant för projektet.[1] Vi ser gärna programmering som ett hantverk. Precis som andra hantverk går det alltid att bli skickligare inom programmering. Om verktyg för statisk kodanalys används på rätt sätt kan de hjälpa programmeraren att snabbare dra slutsatser om hur ett projekt går och kontinuerligt förbättra sin skicklighet. Exempel på slutsatser är: Nya praktiker Regler som man inte har haft någon aning om tidigare kan belysa problem som kan uppstå senare. Det är enklare att ta till sig av nya praktiker när man ser vilka misstag man kan göra med äldre praktiker. Om man inte tar åt sig kodanalys riskerar man att fortsätta i invanda mönster istället för att förbättra sitt programmeringshantverk. Verifiering av testfall Även om man inte bedriver testdriven utveckling till fullo så kan testtäckning peka på om man råkar missa något när man utvecklar. Testtäckning som minskar i andel under en tidsperiod är en trend för att man borde vara vaksam över fulhack. Komplexa klasser Att titta på cyklomatisk komplexitet, ett mått för hur många vägar en kod kan exekveras, kan snabbt peka ut klasser vars ansvarsområden kan delas upp flyttas någon annanstans samt även visa klasser som har för lite att göra. Mått som komplexitet och stora metoder kan vara ganska intetsägande. En erfaren utvecklare ser ganska snabbt om en metod är komplex eller för stor utan verktyg, men för större system är det svårt att få en överblick över hela systemet. Det finns en annan stor fördel av att använda sig av dessa verktyg och borde anses vara en stor fördel för många utvecklare. Många av verktygen för statisk kodanalys till Java och många andra utvecklingsmiljöer är öppna källkodsprojekt. De kan alltså användas gratis med syfte att förbättra kvaliteten av källkod och programdesign i andra projekt. 12 (18)

5.2 Subjektiv bedömning av kodkvalitet Kodkvalitet är ett relativt begrepp. Det kan handla om enkel design, robusthet, säkerhet, full testtäckning m.m. Det är ofta upp till ett team att själva definiera vad kodkvalitet innebär för deras utvecklingsprojekt. För att få något att jämföra de data vi samlat ihop med diskuterade vi med teamen vad de själva tycke om deras kodkvalitet. En sammanställning av resultatet finns i nedanstående tabell, där ett betyder att kodkvaliteten behövs förbättras mycket och fem betyder att kodkvaliteten är tillräckligt bra. Team 1 2 3 4 5 6 7 8 9 10 Coacherna - 2 3 2,5 2 3,5 3 4 4 4 Teamet 3,5 3 3,5 4 3 4 2 3 3 4 Tabell 5 Teamets och coachernas uppfattning om sin kodkvalitet på en skala från ett till fem. Coacherna i team 1 hade inte någon uppfattning om teamets kodkvalitet. Värt att nämna är att team 7 är den som är mest självkritiska av alla team samtidigt som de placerar sig bland de bästa ur verktygens perspektiv. Frågan är om detta kan betyda att självkritiska team är mer noggranna, vilket är ett uppslag för framtida studier. I övrigt är det svårt att se några samband mellan teamets syn jämfört med vad verktygen visar. Team 3 kommenterade att deras kod saknar robusthet. Eftersom teamet får betydligt mycket fler anmärkningar av FindBugs än andra team, tyder det på att det finns många småbuggar i deras källkod. 5.3 Att använda statisk kodanalys i kursen Vår erfarenhet är att statisk kodanalys är ett utmärkt hjälpmedel för att hjälpa en utvecklare att förbättra sin skicklighet. Därmed borde verktygen vara ett bra hjälpmedel för studenter som går i kursen Programvaruutveckling i grupp - projekt. Med hjälp av verktygen kan studenterna lära sig om goda praktiker som inte täcks av andra kurser. De tre verktyg vi valt att fokusera på kompletterar varandra, eftersom de kontrollerar olika saker. Checkstyle har väldigt strikta regler vilket kan hindra studenterna från att utveckla den kodstandard som passar teamet. Om man ska införa Checkstyle måste man bestämma sig för vilken kodstandard som ska användas från projektets start. Risken med Checkstyle är att studenterna efter ett tag undviker att använda verktyget, på grund av de strikta reglerna. PMD har inte lika strikta regler, men kräver arbete för att välja vilka regelkategorier som är lämpliga att använda. I annat fall ger PMD många falsklarm, vilket precis som Checkstyle riskerar att göra att studenterna inte använder verktyget. PMDs utvecklare rekommenderar att man börjar med de grundläggande regelkategorierna och sedan lägger till en regelkategori åt gången, för att inte få för många anmärkningar på en gång [9]. FindBugs ger inte så många anmärkningar som de andra verktygen vilket gör att det är större sannolikhet att studenterna tar till sig informationen. Förmodligen är detta verktyg 13 (18)

det som är enklast att införa eftersom buggar är mer konkreta och intressanta att upptäcka än dåligt skriven, men fungerande, kod. Å andra sidan finns det en risk att studenterna nöjer sig med att koden inte innehåller de buggar som FindBugs hittar. Det finns naturligtvis fel som FindBugs inte hittar, t.ex. att utvecklarna missuppfattat kundens krav. Vi har försökt införa kodanalysverktyg i vårt team men har stött på problem på vägen. Studenterna har inte var lika entusiastiska att anamma sig verktygen som vi coacher. Det finns olika anledningar till detta. Verktygen anses som störande, att det läggs för många hinder än vad som behövs för studenterna. Studenterna vill koncentrera sig på att skriva kod istället för att tänka sig andra aspekter med mjukvaruutveckling såsom krav, design och testning. De flesta i vårt team går andra året i datateknik och lär inte ha någon vana att arbeta med programvaruprojekt. Den tid som är avsatt för projektet går åt de aktiviteter som de redan har att göra. Det finns lite tidsutrymme för studenterna att lära sig ytterligare nya verktyg än vad de redan har. Nyttan med kodkvalitet märks mer på längre sikt än i början. När det gäller sista punkten så vore det ideella att introducera kodanalysverktyg mot slutet av projektet eftersom studenterna börjar se nyttan med att kontrollera sig själva. Vi ser detta när de börjar använda testtäckningsverktyg för att se exakt vad som testas i sin källkod. Team med äldre studenter som har mer erfarenhet i programvaruutveckling borde tipsas om att använda kodanalysverktyg tidigare. Troligtvis kommer dessa ha större nytta av att ta till sig verktygen. Vår rekommendation är att börja införa FindBugs i projektet när teamet börjar inse vikten av kodkvalitet. Om FindBugs fungerar bra, kan man fortsätta med att införa PMD. 14 (18)

6 Referenslista [1] Jeff Atwood. 2006. A Visit from the Metrics Maid. 2006-sept-13, Coding Horror, http://www.codinghorror.com/blog/archives/000681.html [2] 1999. Code Conventions for the Java Programming Language, Sun Microsystems, Inc, http://java.sun.com/docs/codeconv/ [3] G. Hedin, L. Bendix, B. Magnusson, 2003. Teaching Software Development using Extreme Programming, Dept. of Computer Science, Lund Institute of Technology [4] Checkstyle, 2007. http://checkstyle.sourceforge.net/ [5] FindBugs, 2007. http://findbugs.sourceforge.net/ [6] David Hovemeyer and William Pugh, 2004. Finding Bugs is Easy, Dept. of Computer Science, University of Maryland, http://findbugs.sourceforge.net/docs/oopsla2004.pdf [7] PMD, 2007. http://pmd.sourceforge.net/ [8] Thomas J. McCabe, 1976, A Complexity Measure, IEEE Transactions On Software Engineering, http://www.literateprogramming.com/mccabe.pdf [9] PMD, 2007. Best Practices, http://pmd.sourceforge.net/bestpractices.html 15 (18)

7 Appendix A Exempelprogram 1. public class Misc { 2. public Misc(String s) { 3. if (s == null s == "") { 4. s = new String("hej"); 5. } 6. for (int i = 0; i < 20; i++) { 7. s += " "; 8. s += i; 9. } 10. } 11. 12. public void use() { 13. } 14. 15. private void complex() { 16. int x = 2; 17. int y = 4; 18. int z = 3; 19. if (x < y) { 20. for (int i = 0; i < y; i++) { 21. x = y + i; 22. } 23. } else if (z < x + y) { 24. for (int i = 0; i < x + y; i++) { 25. z = x + y + i; 26. } 27. } 28. while (z < x) { 29. if (z < 2) { 30. z++; 31. } else if (z < 4) { 32. x++; 33. } else if (z < 10) { 34. y++; 35. } 36. } 37. 38. switch (y) { 39. case 4: 40. x++; 41. case 5: 42. y++; 43. break; 44. default: 45. System.out.println("Detta var inte bra"); 46. System.exit(0); 47. break; 48. } 49. } 50. 51. public static void main(string[] args) { 52. Misc misc; 53. if (args.length == 1) 54. misc = new Misc(args[0]); 55. Else 56. misc = new Misc(new String()); 57. } 58. } 16 (18)

7.1 Testresultat från PMD Prioritet Rad Beskrivning 3 1 All classes and interfaces must belong to a named package 3 1 The class 'Misc' has a Cyclomatic Complexity of 5 (Highest = 11). 3 3 Avoid variables with short names like s 2 5 Avoid instantiating String objects; this is usually unnecessary. 3 14 Document empty method 3 18 Avoid unused private methods such as 'complex()'. 3 18 The method 'complex' has a Cyclomatic Complexity of 11. 3 19 Avoid variables with short names like x 3 20 Avoid variables with short names like y 3 21 Avoid variables with short names like z 5 24 Found 'DD'-anomaly for variable 'x' (lines '24'-'24'). 5 28 Found 'DD'-anomaly for variable 'z' (lines '28'-'28'). 5 38 Found 'DD'-anomaly for variable 'y' (lines '38'-'38'). 5 44 Found 'DU'-anomaly for variable 'x' (lines '44'-'53'). 5 46 Found 'DU'-anomaly for variable 'y' (lines '46'-'53'). 2 49 System.out.print is used 3 58 Parameter 'args' is not assigned and could be declared final 3 59 Avoid unused local variables such as 'misc'. 3 61 Avoid using if...else statements without curly braces 5 61 Found 'DU'-anomaly for variable 'misc' (lines '61'-'64'). 3 63 Avoid using if...else statements without curly braces 5 63 Found 'DU'-anomaly for variable 'misc' (lines '63'-'64'). 7.2 Testresultat från Checkstyle Rad Beskrivning 1 Missing a Javadoc comment. 2 Missing a Javadoc comment. 2 Parameter s should be final. 6 '20' is a magic number. 12 Missing a Javadoc comment. 15 Missing a Javadoc comment. 15 The method complex() from the type Misc is never used locally 17 '4' is a magic number. 18 '3' is a magic number. 31 '4' is a magic number. 33 '10' is a magic number. 39 '4' is a magic number. 41 '5' is a magic number. 51 Missing a Javadoc comment. 51 Parameter args should be final. 52 The local variable misc is never read 53 'if' construct must use '{}'s. 55 'else' construct must use '{}'s. 17 (18)

7.3 Testresultat från FindBugs Rad Beskrivning 3 ES: Comparison of String parameter using == or!= in Misc.Misc(String) 4 Dm: Misc.Misc(String) invokes inefficient new String(String) constructor; just use the argument 15 The method complex() from the type Misc is never used locally 40 SF: Switch statement found in Misc.complex() where one case falls through to the next case 46 Dm: Misc.complex() invokes System.exit(...), which shuts down the entire virtual machine 52 The local variable misc is never read 56 DLS: Dead store to misc in method Misc.main(String[]) 56 Dm: Misc.main(String[]) invokes inefficient new String() constructor; just use "" 18 (18)