Hovedopgave Master i IT - Softwarekonstruktion Aarhus Universitet, Institut for Datalogi ”Vurdering af SQALE som kvalitets evalueringsmodel” Af Carsten Christensen 14. juni, 2015 Carsten Christensen, studerende Henrik Bærbak Christensen,vejleder -1- Abstrakt Denne rapport indeholder en undersøgelse af professionelle udøveres holdning til SQALE kvalitets modellen, som værktøj til at håndtere teknisk gæld i kilde kode. Rapportens første del er en evaluering af SQALE modellen, implementeret i værktøjet SonarQube. Modellen evalueres ved at sammenligne teknisk gæld fundet af manuelle reviews udført af en gruppe arkitekter og automatiske reviews udført af SonarQube. Evalueringen danner grundlag for en panel diskussion mellem software arkitekter på Bankdata, der har deltaget i evalueringen af SQALE. -2- Indholdsfortegnelse 1 Motivation..........................................................................................................5 2 Problemformulering...........................................................................................6 2.1 Research question......................................................................................6 2.2 Afgrænsning...............................................................................................6 2.3 Læsevejledning..........................................................................................7 3 Metode...............................................................................................................8 3.1 Udvælge projekter til deltagelse................................................................8 3.2 Manuel evaluering af projekterne..............................................................8 3.3 Værktøjs evaluering af projekterne............................................................9 3.4 Sammenligning af manuel og automatisk evaluering................................9 3.5 Ekspert diskussion af værktøjets anvendelighed.......................................9 4 Teoretisk baggrund...........................................................................................11 4.1 Teknisk gæld.............................................................................................11 4.2 Kvalitets modeller, ISO 9126...................................................................12 4.3 SQALE.....................................................................................................13 4.4 Kvalitets attributter..................................................................................18 4.4.1 Testability (Testbarhed)....................................................................19 4.4.2 Reliability (pålidellighed).................................................................20 4.4.3 Changeability (forandrelighed)........................................................20 4.4.4 Efficiency (effektivitet)....................................................................20 4.4.5 Security (sikkerhed).........................................................................21 4.4.6 Maintainability (vedligeholdelig).....................................................21 4.4.7 Portability (porterbarhed).................................................................21 4.4.8 Reuseability (genbrugelighed).........................................................22 4.5 Relateret arbejde......................................................................................22 5 Manuel evaluering af projekterne....................................................................23 5.1 Udvælgelse af projekter...........................................................................23 5.2 Evaluerings metoden - reviews................................................................23 6 Værktøjs evaluering af projekterne..................................................................25 6.1 Introduktion til SonarQube......................................................................25 6.2 Konfigurering af SonarQube/SQALE......................................................29 6.3 Data fra SonarQube..................................................................................30 7 Evaluering af KROModel................................................................................32 7.1 Intro til projektet......................................................................................32 7.2 Manuelt review........................................................................................32 7.2.1 Testability.........................................................................................32 7.2.2 Reliability:........................................................................................33 7.2.3 Changeability:..................................................................................33 7.2.4 Efficiency:........................................................................................33 7.2.5 Security:............................................................................................33 7.2.6 Maintainability:................................................................................34 7.2.7 Portability:........................................................................................34 7.2.8 Reuseability......................................................................................34 7.2.9 Konklusion.......................................................................................35 7.3 SQALE evaluering med SonarQube........................................................35 7.3.1 Data fra evalueringen:......................................................................35 7.3.2 Testability:........................................................................................36 7.3.3 Reliability:........................................................................................36 7.3.4 Changeability:..................................................................................36 -3- 7.3.5 Efficiency:........................................................................................36 7.3.6 Maintainability:................................................................................36 7.3.7 Fil distribuering efter SQALE Score................................................37 7.4 Konklusion på automatiseret SQALE review contra manuelt review.....37 8 Evaluering af PUMJSFPortalUtil....................................................................38 8.1 Intro til projektet......................................................................................38 8.2 Manuelt review........................................................................................38 8.2.1 Summering pr. kvalitets attribut.......................................................41 8.2.2 Konklusion.......................................................................................42 8.3 SQALE evaluering med SonarQube........................................................43 8.3.1 Data fra evalueringen:......................................................................43 8.3.2 Testability:........................................................................................44 8.3.3 Reliability:........................................................................................44 8.3.4 Changeability:..................................................................................44 8.3.5 Maintainability.................................................................................45 8.3.6 Fil distribuering efter SQALE Score................................................45 8.4 Konklusion på automatiseret SQALE review contra manuelt review.....45 9 Evaluering af SAGOpgaveListeJsfPortlet.......................................................46 9.1 Intro til projektet......................................................................................46 9.2 Manuelt review........................................................................................46 9.2.1 Summering pr. kvalitets attribut.......................................................48 9.2.2 Konklusion.......................................................................................49 9.3 SQALE evaluering med SonarQube........................................................49 9.3.1 Data fra evalueringen:......................................................................49 9.3.2 Testability:........................................................................................50 9.3.3 Reliability:........................................................................................50 9.3.4 Changeability:..................................................................................50 9.3.5 Maintainability.................................................................................51 9.3.6 Fil distribuering efter SQALE Score................................................51 9.4 Konklusion på automatiseret SQALE review contra manuelt review.....51 10 Sammenlign manuel og værktøjsbaseret evaluering.....................................52 10.1 Konklusion på SQALE..........................................................................52 10.2 Konklusion på processen.......................................................................52 11 Udøveres vurdering af SonarQube / SQALE.................................................54 11.1 Fokus gruppe diskussion........................................................................54 11.2 Resultat...................................................................................................54 12 Konklusion.....................................................................................................57 13 Fremtidig arbejde...........................................................................................58 14 Referencer......................................................................................................59 A. Manuel review, checkliste.............................................................................61 B. SQALE Quality attribute træ, med sub-attributter........................................63 C. SonarQube reglersæt.....................................................................................65 D. Teknisk gæld i KROModel...........................................................................86 E. Teknisk gæld i PUMJsfPortalUtil..................................................................88 F. Teknisk gæld i SAGOpgaveListJSFPortlet....................................................90 G. SQALE data for kontrol projekter................................................................91 H. Sonar-project.properties eksempel................................................................93 I. jacoco_build.xml eksempel............................................................................94 J. Referat fra fokusgruppe diskussion om teknisk gæld og SQALE.................96 K. Duplikeret kode i OpgavelisteState............................................................101 -4- 1 Motivation Software systemer har ry for at blive vanskeligere og vanskeligere at vedligeholde i takt med at systemet ældes, og tilpasses nye krav som ikke var til den oprindelige udgave af systemet. Nogle gange har der ikke været tid til at indføre nye krav i systemet på den bedste måde, og nye krav er tilføjet som knopskydninger på den eksisterende arkitektur. Eller systemets oprindelige udviklere og arkitekter er måske ikke længere tilstede, i lighed med system dokumentationen. Og tanken bag alle beslutninger står ikke længere helt klart. Disse mangler og fejl i arkitekturen og i kode basen kan omtales som teknisk gæld. I nogle situationer kan det være fornuftigt at indføre teknisk gæld for at komme hurtigt videre, og betale tilbage senere. Men hvis denne gæld ikke bliver håndteret, ender man med en kode base der tager længere og længere tid at vedligeholde. Konsekvensen af det, er at produktiviteten for udviklerne falder, time to market stiger, og det bliver vanskeligere at nå aftalte deadlines. Det er derfor interessant at kunne måle og kommunikere om de, mere eller mindre bevidste, fejl og mangler der er i kode basen. Så man bevidst kan træffe beslutninger om hvornår man indfører gæld og hvornår der skal betales tilbage. SQALE er en kvalitets evaluerings metode, som hævdes at kunne gøre netop det, på baggrund af kilde koden at kunne måle på et antal kvalitets attributter, og give et samlet overblik over hvor meget teknisk gæld der er i en software komponent. Så man har mulighed for bevidst at håndtere den tekniske gæld. Værktøjet SonarQube implementere SQALE, og giver ved kontinuerlig inspektion et billede af hvordan den tekniske gæld udvikler sig over tid, og samtidig et billede på fil niveau, hvor den tekniske gæld befinder sig. Der findes meget lidt tilgængelig viden om anvendelsen af SQALE i praksis. Jeg vil derfor i dette projekt undersøge kvalitets evaluerings metoden SQALE og værktøjet SonarQube for at vurdere anvendeligheden heraf på Bankdata. -5- 2 Problemformulering Jeg vil i dette projekt vurdere anvendeligheden af SonarQube's implementering af SQALE metoden, som kvalitets evaluerings værktøj i Bankdata, ved at sammenholde manuelle ekspert vurderinger af en række kvalitets attributter, med værdier for samme attributter målt af værktøjet (SonarQube). Endelig vil jeg, efter en præsentation af SonarQube og SQALE, og sammenligningerne af de manuelle og automatiske review, i en panel diskussion med en gruppe arkitekter og projektledere, fremdrage fordele og ulemper ved værktøjet for at konkludere på dets anvendelighed. 2.1 Research question Kan man ved hjælp SonarQube's SQALE plugin til kontinuerlig kode analyse, benytte rapporteringen af teknisk gæld i en software komponent, så udviklere og ledelse finder det anvendeligt som værktøj til bevidst at styre kvaliteten, udtrykt som teknisk gæld for en række kvalitets attributter, i en software komponent. Jeg vil afdække professionelle udøveres holding til teknisk gæld som styrings redskab, og i særdeleshed til SQALE modellens evne til automatisk at afdække denne gæld. Baseret på sammenligninger af manuelle review og automatiske review vha. SQALE, af samme projekter, vil jeg sætte en gruppe af software arkitekter og projektledere i stand til at diskutere emnet. På baggrund heraf vurderes spørgsmålene - er teknisk gæld et begreb som kan benyttes i styringen af kvaliteten. Vil gruppen anbefale at mængden af teknisk gæld systematisk afdækkes i alle/udvalgte projekter. - Vil SonarQube og SQALE kunne benyttes til rapportering af den tekniske gæld, og er der overensstemmelse med den tekniske gæld fundet af manuelle og automatiske review? - Kan automatiske review, vha. SonarQube og SQALE, erstatte manuelle review. Hvis ikke, kan automatiske review supplere manuelle review, evt. for udvalgte kvalitets attributter, i et sådan omfang at det vil anbefales at projekterne altid gennemgår automatisk review inden manuelle review. Alternativt kan SonarQube og SQALE benyttes som guide for det manuelle review? 2.2 Afgrænsning Jeg vil udelukkende kigge på projekter på Bankdatas decentrale platform. Det drejer sig om Java projekter der afvikles på WebSphere Portal Server 7. Jeg vil således ikke kigge på analyse af Cobol moduler på mainframe. SQALE er sprog neutral og SonarQube understøtter også evaluering af Cobol moduler. Det -6- kunne være interessant på sigt også at vurdere værktøjet her, men det indgår ikke i dette projekt. SQALE udregner den tekniske gæld i antal mandedage der skal bruges på at udbedre hele den tekniske gæld. Det er ikke målet her at kalibrere modellen så dette tal passer med det faktiske antal dage der skal benyttes på Bankdata. Derfor benyttes der standard værdier for udbedrings omkostninger (remediation cost) af hver enkelt regelbrud, og standard værdier for omkostninger til at udvikle en linje kilde kode (line of code cost). 2.3 Læsevejledning Skønt rapporten er på dansk, er engelske udtryk benyttet hvor de bedst beskriver området, og forventes at være gængse brugt. Specielt er kvalitets attributterne holdt på engelsk da flere af de danske oversættelser er tunge at arbejde med. Lige ledes er review deltagernes roller, navngivet med de engelske termer. Rolle beskrivelserne er baseret på Fagans oprindelige definition [M. Fagan] og summeret op i [A. Aurum et al.] Følgende er en kort definition af begreber som de er brugt i denne rapport. Code smell – mønster i koden der angiver at der muligvis er et problem med koden eller struktureringen af koden her [M. Fowler, s. 63]. Reader – oplæser, der under gennemgang af kode, oplæser for de øvrige reviewere og 'styrer muse'. Moderator – Koordinerer review, står for indkaldelse og tildeling af roller til de øvrige deltagere, og sikrer al det praktiske, som møde lokaler, sikrer at alle deltagere har adgang til artefaktet der reviewes – her kilde koden. Author – den primære ansvarlige for kilde koden, og oftest den person der har skrevet koden. I nogle tilfælde er der flere personer der har bidraget til koden, i så fald udpeges blot en enkelt primær ansvarlig Review – Gennemgang af artifakter, med henblik på at finde fejl, mangler og uklarheder. I projektet her er den eneste artifakt der reviewes ved det manuelle review, kilde kode. Ved det automatiserede review, benyttes også de kompilerede binære. Reviewer – deltager i et review møde der kommer med input til reviewet. Scribe – sekretær til review møde. Sikrer at reviewet dokumenteres og at uklarheder om selve reviewet afklares. -7- 3 Metode 3.1 Udvælge projekter til deltagelse Jeg vil udvælge 3 projekter, til at indgå i dette projekt. Flere kunne være ønskeligt for at få en bredere fundering, men af praktiske grunde er projektet afgrænset til 3 projekter. Især de manuelle review er ret ressource krævende at gennemføre. I nedenstående argumenteres for at udvælgelsen af de 3 projekter, er dækkende for projekter, på den decentrale platform, på Bankdata. Langt den største kodebase, på den decentrale platform i bankdata, ligger i portlets, med over 600 aktive portlets. Den største værdi ligger derfor i at automatisere kvalitets evalueringen af denne type projekter. Det er derfor væsentlig at modellen dækker dette område. Et af de evaluerede projekter vil være en portlet, udarbejdet efter nyeste standard på Bankdata. En anden type af projekter er framework kode, til understøttelse af portlet udvikling. Mange projekter afhænger af kvaliteten her og det er muligvis andre kvalitets krav der stilles. Det er interessant om modellen også omfavner denne type projekter. Et af de valgte projekter repræsentere framework kode. En tredje type af projekter, på Bankdata, er projekter der ligger et sted mellem portletter og framework kode. Det er typisk projekter der har til formål at dele kode mellem en lille mængde portletter, typisk inden for et afgrænset forretnings område. Projekterne er typisk meget rene Java projekter, uden afhængigheder til underliggende containere etc. Det sidste projekt der vælges er af denne type. For at sikre at alle udvalgte projekter har gennemgået den vanlige kvalitets kontrol, udvælges kun projekter som er i produktion på evaluerings tidspunktet. Det vurderes at de 3 projekt typer er repræsentative for Java projekterne på Bankdata. 3.2 Manuel evaluering af projekterne Der gennemføres manuelle review af projekterne for at fastslå mængden af teknisk gæld, og kategoriser den tekiske gæld i projekterne efter samme kvalitets attributter som SQALE modellen (Testabilit, Reliabilit, Changeability, Efficiency, Security, Maintainability, Portability, Reusability), samt i høj grad for i processen, at gruppen af reviewere får en fælles forståelse af teknisk gæld. Den teknisk gæld vurderes for hver kvalitets attribut, som repræsentere review gruppens bedømmelse af den pågældende attribut for projektet. Hver attribut vurderes efter skalaen høj, middel, lav. Der er bevidst valgt en anden skala end SQALE for ikke at forveksle de to scorings metoder. Formålet med scoringen er at bevidstgøre gruppen om kvalitets attributten, ud fra et fælles syn på teknisk -8- gæld i projekterne, så den automatiske evaluering af projektet efterfølgende kan vurderes. Dette gøres ved at vælge et centralt team til review af koden. Det centrale team består bland andet af løsningsarkitekterne for de udvalgte projekter, og medlemmer fra Bankdatas afdeling for teknisk arkitektur. Det er ikke formålet at finde al teknisk gæld, og klassificere det. Det væsentligste bidrag fra det manuelle review er således ikke scoren for projektet, men bevidstheden om projektets tilstand, til brug i den efterfølgende behandling af værktøjs evalueringen. Review processen i det manuelle review er nærmere beskrevet i kapitel 5.2, Evaluerings metoden - reviews 3.3 Værktøjs evaluering af projekterne SonarQube opsættes med SQALE plugin og der gennemføres automatisk review af projekterne. Der benyttes standard kvalitets profil og standard værdier for udbedrings omkostning (remediation cost), og udviklings omkostninger (hvad koster det at udvikle en linje kilde kode). Endelig benyttes SonarQube's omregning til en SQALE rating (A,B,C,D,E). Det automatiske review beskrives nærmere i kapitel 6, Værktøjs evaluering af projekterne 3.4 Sammenligning af manuel og automatisk evaluering Efterfølgende behandles SonarQubes review af projektet og sammenlignes med reviewet givet på baggrund af den manuelle evaluering. De væsentlige fund fra SonarQube undersøges og diskuteres og sammenholdes med de væsentlige fund fra det manuelle review. Uoverensstemmelser mellem de to reviews noteres, og der konkluderes pr. projekt, former for teknisk gæld der ikke lod sig afdække af det automatiske review og omvendt. Hovedformålet i denne del af projektet, er at klæde fokusgruppen på til at kunne indgå i diskussionen om SQALE's anvendelighed til automatisk review af projekter, for at styre den tekniske gæld. 3.5 Ekspert diskussion af værktøjets anvendelighed Første del af undersøgelsen skal give svar på om der er sammenhæng mellem den tekniske gæld der findes af værktøjet og den opfattelse de professionelle der arbejder med koden har. Denne del skal give svar på om udviklere og ledelse finder værktøjet anvendelig til at styre den tekniske gæld. På baggrund af en præsentation af SQALE plugin, i SonarQube, med udgangspunkt i de konkrete projekter, diskuteres resultaterne i en gruppe bestående af løsnings arkitekterne og projektlederne bag de udvalgte projekter. Diskussionen foregår som en fokus gruppe diskussion, baseret på [R. -9- Krueger], ”Designing and Conducting Focus Group Interviews”. Herefter fremdrages konklusioner fra fokus gruppe diskussionen. - 10 - 4 Teoretisk baggrund 4.1 Teknisk gæld Begrebet teknisk gæld er en metafor først benyttet af Ward Cunningham [W. Cunningham], for bedre at kunne forklare, til ikke teknisk personale, hvorfor refaktorering af koden er nødvendig, i takt med at man opnår en bedre forståelse af problemstillingen. Han sammenligner det at have mangler og uklarheder i kilde koden, med at optage et lån, og dermed stifte gæld, for hurtigere at kunne komme i gang med forretningen, som kan give afkast og betale lånet tilbage. Lige som en opstarts virksomhed låner penge til maskiner etc. for at komme hurtig i gang, som der så betales renter og afdrag af når virksomheden er i gang og tjener penge, kan det være en fordel ved udviklingen af software, at levere tidlige versioner af programmet, velvidende at det ikke er perfekt i alle aspekter. Der kan være flere grunde til at indføre gælden. Det kan være manglende indsigt i den fulde problemstilling, som lettest lader sig afklare ved at lave prototyper og lade brugerne bruge dele af systemet. Det kan være vigtigere at nå en deadline her og nu, og lave et 'quick and dirty fix', velvidende at det tager længere tid at 'gøre det rigtigt' efterfølgende. Det kan være arkitektur som ikke påvirker brugen af system, men besværliggør vedligeholdelse og udvidelser af systemet. Det er stadig målet for Cunningham at ”skrive koden så den reflekterer den nuværende forståelse af problemet, selvom denne forståelse ikke er fuldkommen” [W. Cunningham, 2009] Sammenligningen med gæld baserer sig på, at al den tid der bruges på at arbejde på kode som ikke er helt rigtig, besværliggør udviklingen og trækker tempoet i udvikling ned. Det svarer jf. metaforen til at der betales renter, af den gæld der er oparbejdet. Gælden afdrages ved at refaktorere koden, så den igen er optimal at arbejde med. Da metaforen har vist stor værdi i kommunikation til ikke tekniske personer er begrebet med tiden blevet udvidet. Cunningham er dog, i lighed med Robet Martin [R. Martin, 2009] meget eksplicit i at dårlig kode ikke er teknisk gæld – det er bare dårlig kode. Martin Fowler [M. Fowler, Technical Debt Quadrant] argumenterer dog for at selv om kode er sjusket, giver det værdi at benytte teknisk gæld som metafor i kommunikationen, vedr. de udeståender der måtte være. Uanset om de er opstået bevidst eller ubevidst. Og uanset om de er resultatet af en fornuftig afvejning, eller om de er opstået ud fra en hensynsløs tanke om – 'vi har ikke tid til at gøre det rigtigt'. Det kan være så simpelt som at bruge System.out.println(), til logning, frem for at benytte et log framework. Velvidende at på et tidspunkt bliver man nød til at graduere logningen, for ikke at oversvømme i log detaljer. Eller duplikere kode, frem for at bruge tiden til f.eks. at designe og oprette det rette arve hierarki, for lige at tilføre en ekstra type. - 11 - Der er dog bred enighed om at fejl i koden ikke er teknisk gæld. Hvis produktet fejler og ikke udfører den aftalte opgave er det en fejl. At der ikke findes test der kunne afdække fejlen, kan der imod betragtes som gæld. Også ud fra den betragtning at hvis der ikke findes automatisk test af koden, vil den ofte ikke være designet så den er testbar. Og koden indeholder derfor teknisk gæld for at få den refaktoreret, så den er testbar [M. Bland, testing-culture]. I rapporten her benyttes den brede definition af teknisk gæld, hvor alt der gør at koden ikke er så optimal at arbejde med som muligt, betragtes som teknisk gæld. 4.2 Kvalitets modeller, ISO 9126 At kunne evaluere kvaliteten af software er nødvendigt af flere årsager. Både i forbindelse med vurdering af produktivitet og i forbindelse med indgåelse af aftaler, ved projekt ledelse etc. Produktivitets målinger, uden samtidig at måle den producerede kvalitet er meningsløs. Aftale indgåelse vil i reglen kræve at det er muligt at måle om den aftalte kvalitet er leveret. Projektledelse er afhængig af at kunne måle den leverede kvalitet jv. , Figur 1: Haughey's 'project management diamond' [Haughey, 2008] Figur 1: Haughey's 'project management diamond' Flere modeller til evaluering af kvaliteten har været foreslået gennem tiden. I 1991 blev en standardiseret model, ISO 9126, publiceret. Modellen baserer sig på tidligere modeller foreslået af Boehm og især McCale [Fenton s.343]. Fælles for modellerne er at de beskriver kvalitet ved hjælp af en dekomposition af flere faktore, som er høj niveau eksterne og interne kvalitets attributer [Fenton s.340]. For ISO 9126 er defineret attributterne functionality, reliability, efficiency, useability, maintainability og portability, som er interne og eksterne kvalitets attributter. Samt effectivenes, productivity, safety og satisfaction, som baseres på brugen af softwaren, i iso standarden kaldet 'quality in use'. - 12 - Hver attribut er yderligere nedbrudt i en række kriterier og sub-kriterier, som igen hver er nedbrudt ved hjælp af en række eksterne, interne og 'quality in use' metrikker (iso9126-2,3,4), som blev tilføjet ved revideringen i 2002 for at imødekomme kritik som fremført i [Fenton, s. 343]. Interne, eksterne, og 'quality in use' kriterier påvirker og er afhængige af hinanden, jf. Figur 2: Afhængigheder mellem metrik typer, fra ISO 9126 standarden. Figur 2: Afhængigheder mellem metrik typer, fra ISO 9126 standarden. Interne metrikker kan måles på ikke eksekverbare artifakter, herunder kravs specifikation, design dokumenter og kilde kode. Måling af interne metrikker kan give tidlig feedback, og hermed give mulighed for at korrigere kvaliteten tidlig i processen. Eksterne metrikker måles på det faktiske eksekverbare program, i det miljø hvor i det forventes at blive benyttet, eller et produktions lignende miljø. Og måler således den faktiske opførsel af programmet, og i hvilken grad kravs specifikationerne er indført i programmet. 'Quality in use' kriterier måler på brugerens brug af programmet, som f.eks., hvor effektiv er brugen af softwaren til at løse brugerens opgaver. Målingen kræver at softwaren er kørende i et miljø, som ligner produktion så meget som muligt, evt. produktions miljøet. Eksterne og 'quality in use' kriterierne kræver selvsagt et færdigt program, eller som minimum et eksekverbart program. Metrikkerne i iso 9126-2,3 & 4 er ikke tænkt som værende fyldest gørende, ej heller som værende obligatoriske. Metrikkerne er konstrueret så de giver et tal mellem 0 og 1, hvor 1 er bedst. Ved at tage gennemsnittet af de udvalgte metrikker for et sub-kriterie, findes ligeledes en score mellem 0 og 1, og så fremdeles for kriterier og attributter. Metrikker, sub-kriterier etc. kan evt. vægtes. Inden kvalitets bedømmelsen foretages, afstemmes hvilke attributter, kriterier og metrikker der skal benyttes, og hvordan metrikken måles og evt. vægtes. - 13 - 4.3 SQALE I 2009 publicerede J-L Letouzey, SQALE modellen (Software Quality Assessment based on Lifecycle Expectations), ud fra et ønske om en model der kunne ”evaluer en software application's kilde kode, på den mest objektive, præcise, reproducerbare og automatiske måde som muligt” [Letouzey 2010, s.5]. I det følgende gennemgås vigtige nøglepunkter vedr. modellen. Kravs baseret SQALE bygger i lighed med ISO9126 på en række attributter, i SQALE kaldet karakteristika, som nedbrydes i sub-attributter/sub-karakteristika, der yderligere nedbrydes i en række krav til kilde koden, jf. Figur 3: Nedbrydning af attributter, til sub-attributter og kilde kode krav [Letouzey, 2010]. Se evt. Appendiks B, SQALE Quality attribute træ, med sub-attributter, for en fuld nedbrydning af attributter og sub-attributter. Metrikkerne er udformet som regler eller krav til kilde koden, og SQALE er således en kravs model. Et krav kan f.eks. være at der ikke må findes udkommenteret kode, eller for et Java projekt, at System.out.prinln() ikke må benyttes som logning. Evaluering af kilde koden er dermed et spørgsmål om at finde forskellen mellem kravene og den faktisk kode. Modellen er ikke sprog specifik, men kravene til kilde koden skal tilpasses sproget, og i et vist omfang den enkelte opgave eller organisation. Se evt. Appendiks C, SonarQube reglersæt, for en komplet liste af de regler der er benyttet i evalueringerne i denne rapport Figur 3: Nedbrydning af attributter, til sub-attributter og kilde kode krav [Letouzey, 2010] - 14 - Lifecycle Expectations SQALE modellens attributter består af testability, reliability, changeability, efficiency, security, maintainability, portability og reuseability, og bygger på de ISO9126 kvalitets attributter som er relateret til kilde koden, men er udvidet med reuseability [Letouzey, SQALE V1.0]. SQALE modellen er baseret på 'Lifecycle Expectations', som angivet i navnet. Hermed menes at en fil (kilde kode), eller et program gennemgår forskellige faser i sin livscyklus, og de forskellige attributter er af interesse i de forskellige faser, se Figur 4: "File" livscyklus fra SQALE kvalitets modellen. Afhængigheder mellem aktivitet og kvalitets attribut. [Letouzey, 2010]. Det giver en herakisk afhængighed mellem kvalitets attributterne. Derfor er testability også lavet som selvstændig første niveau attribut, i stedet for at være et sub-kriterie til maintainability. Inden der kigges på reliability, efficiency eller maintainability – skal der først kigges på kravene til testability. Hvis koden ikke er testbar (for kompleks eller for tæt koblet etc.), vil man ikke kunne verificere reliability etc. Og ved vedligehold af koden, kan det ikke verificeres at en evt. rettelse er lavet rigtig. Det leder, for SQALE modellen, til den konklusion at testability er fundamentet for alle de øvrige kvalitets attributter [Letouzey, 2012]. Figur 4: "File" livscyklus fra SQALE kvalitets modellen. Afhængigheder mellem aktivitet og kvalitets attribut. [Letouzey, 2010] - 15 - Aggregerings funktion, udbedrings omkostninger SQALE er en kravs model som beskrevet ovenfor, og evaluering af kilde koden er dermed et spørgsmål om at finde forskellen mellem kravene og den faktiske kode. I SQALE måles denne forskel i udbedrings omkostninger, altså hvad vil det koste, i tid, at udbedre et brud på en regel, så kilde koden igen lever op til kravet. For hvert krav er altså knyttet et mål for hvor lang tid det vil tage at rette kilde koden til, så kravet overholdes. Udbedrings omkostninger svarer til teknisk gæld begrebet [Letouzey, SQALE V1.0]. Måling i udbedrings omkostninger eller teknisk gæld, løser flere formål i SQALE. Det gør det enkelt at repræsentere kvaliteten for en fil, så det let kan verificeres af brugeren af SQALE, at kvaliteten i filen stemmer overens med modellens repræsentation, og ændringer der f.eks. løser et krav, vil altid kunne afspejles i kvalitetsmålene for filen, i.e. den tekniske gæld falder. Modellen er dermed ikke belastet af masking effect, compensation effect eller treshold effect, som påvist i [Letouzey, 2010]. Det betyder også at bestemmelse af en fils samlede kvalitet blot er et spørgsmål om at addere udbedrings omkostningerne for hver enkelt regel afvigelse i filen. Og på samme vis kan kvaliteten for hele systemet bestemmes ved at addere udbedrings omkostninger for alle filer etc. Summen af alle udbedrings omkostninger kaldes SQALE Qualit Indeks (SQI) . Tilpasning af modellen til den enkelte opgave eller organisation er dermed, ud over at tilpasse kravene til kilde koden, også at bestemme og tilpasse udbedrings omkostnings beregningens funktionen, for hvert krav. Analytisk og ekstern view Et andet mål for SQALE modellen har været at evne at supportere to forskellige viewpoints for kvaliteten. Et udvikler orienteret, analytiske syn, som gør det muligt at forstå indvirkningen på udviklings aktiviteten i den aktuelle fase (se Figur 4: "File" livscyklus fra SQALE kvalitets modellen. Afhængigheder mellem aktivitet og kvalitets attribut. [Letouzey, 2010]) Og et ejer/manager orienteret, ekstern viewpoint, der viser den samlede tekniske gæld, for at nå til en given fase i udviklingen. For hver kvalitets attribut, adderes alle udbedrings omkostninger, fra krav tilhørende den aktuelle attribut. Det giver et kvalitets indeks, pr. kvalitets attribut – og giver således det udvikler orienterede syn på den teknisk gæld. Det ejer-orienterede syn opnås ved, at lave et konsolideret indeks pr. kvalitets attribut, bestående af summen af kvalitets indekset for den pågældende attribut, samt for kvalitets attribut indekserne fra alle underliggende faser. Det repræsenteres i SQALE modelen som et pyramide diagram, hvor der horisontalt vises hvert kvalitets indeks, i.e., den tekniske gæld pr. kvalitets attribut. Og vertikal vises de konsoliderede indekser, i.e., summen af krav for at - 16 - nå den pågældende fase, se Figur 5: SQALE pyramiden, der viser de to view, det interne horisontale, og det eksterne med summer vertikal [Letouzey, SQALE V1.0]. Det er dermed afgørende for SQALE modellen at teknisk gæld for en kravs afvigelse kun tælles med én gang, på det laveste niveau jf. faseopdelingen, for at det er muligt at summere indekserne uden at få dobbelt repræsentation. Eksempelvis kan høj kompleksitet i en funktion både udgøre et problem i forhold til testbarhed, og der med være gæld for testability. Men det kan også være et problem i den efterfølgende vedligeholdelse, og dermed for maintainability. I SQALE medregnes denne gæld derfor jf. fase-opdelingen kun i testability. Figur 5: SQALE pyramiden, der viser de to view, det interne horisontale, og det eksterne med summer vertikal [Letouzey, SQALE V1.0] SQALE rating Da den tekniske gæld i et projekt på 10.000 kode linier alt andet lige er større end i et projekt på 1.000 kode linier, definere SQALE modellen også en rating på en ordinal skala, pr. artefact (fil, class, system) – der gør det muligt at sammenligne kvaliteten på tværs af projekter. I SQALE benyttes typisk en skala fra A-E, men det kunne også være en f.eks. god, middel, dårlig etc. - 17 - Karakteren beregnes ved at sætte mængden af teknisk gæld i forhold til størrelsen af artefactet. Da den tekniske gæld er i tid, omregnes artefactets størrelse til tid det har kostet at udvikle, ved at definere den tid det tager at udvikle en linje kilde kode og gange med antal linier i artefactet. Dermed kan udbedrings omkostningerne sættes i forhold til udviklings omkostningerne, for artefactet. Der kan så defineres hvilket forhold der giver en given karakter. Tilpasningen af SQALE modellen til et givent projekt eller en given organisation, indebærer dermed at definere hvad udviklings omkostningen er for at udvikle en linje kode, samt at definere tærsklerne på skalaen. Se eksempelvis Figur 6: Eksempel på SQALE rating skala og tærskel værdier[Letouzey, SQALE V1.0] Figur 6: Eksempel på SQALE rating skala og tærskel værdier[Letouzey, SQALE V1.0] 4.4 Kvalitets attributter Software kvalitet består af en række funktionelle krav og en række ikkefunktionelle krav. Skønt de funktionelle krav afhænger af andre kvaliteter, er det ofte kun de funktionelle krav der beskrives [L.Bass et al, c.4 p71]. De funktionelle krav er typisk velbeskrevne og testet, medens de ikke funktionelle krav kun sjældent er klart definerede, f.eks. ved hjælp af kvalitets attribut scenarier. I det følgende interesserer vi os kun for de ikke-funktionelle krav, beskrevet ved en række kvalitets attributter. Der findes ikke en universel navngivning eller beskrivelse af ikke-funktionelle kvalitets attributter. Følgende er en kort gennemgang af de kvalitets attributter som benyttes af SQALE, og en beskrivelse af hvordan de enkelte attributter opfattes. I litteraturen benytte mange forskellige navne om samme eller overlappende attributter. Eksempelvis Changeability som benyttes i teksten her dækker over meget af det samme som modifyability [L. Bass et al] men har - 18 - også et vist overlap med maintainability som beskrevet i [Microsoft, Application architecture guide]. Navngivningen her er valgt så den matcher de kvalitets attributter der benyttes i SQALE, og beskrivelsen og eksemplerne er tænkt som en vejledning til den manuelle vurdering af projekterne, sammen med checklisten Appendiks A, Manuel review, checkliste. Eksemplerne er ikke fyldestgørende, men ment som inspiration til hvad der hører til den enkelte attribut. Kvalitets attributterne er beskrevet i prioriteret rækkefølge, jf. SQALE's fase opdeling, da flere 'code smells' påvirker flere attributter. F.eks. vil kompleks kode både påvirke testability, men også maintainability. Den tekniske gæld fra f.eks. kompleks udtryk, 'bogføres' således under testability, jf. SQALE modellens krav om at en kravs-afvigelse kun skal tælles én gang. 4.4.1 Testability (Testbarhed) Testability beskriver hvor testbar koden. Dermed hvor let det er at udføre test, typisk automatisk test, der afslører de fejl der må være i systemet. Test udgør mindst 40% af omkostningerne ved at udvikle systemer [Bass et al p.88]. Hvis denne del kan reduceres er der væsentlige besparelser at hente. Eksempler der påvirker testability: Design klasser og metoder efter 'single responsibility princple' som beskrevet af Robert C. Martin [R. Martin, Clean Code p. 109]. Klasser med høj sammenhæng (cohesion) og lav kobling er lettere at teste fordi de er lettere at isolere fra resten af systemet i en unittest. Klasser der er for komplekse og har for mange afhængigheder er vanskelige at unitteste. Hvis der er mange afhængigheder er det vanskeligere at instantiere klassen til brug i unittest, da mange afhængigheder skal mockes. Constructor for komplekse. Initialisering eller oprettelse af andre objekter, som der er afhængigheder til, gør at der bliver en hård binding til de øvrige klasser. Brug af 'new' i constructoren er et tegn på sådan en hård binding der gør klassen vanskelig at teste, med mindre det er simple 'value' objekter, som f.eks. HashMap, LinkedList etc. eller simple beans. I stedet, så send afhængighederne med som input til constructoren (dependency injection). Så har test klassen let ved at konstruere objektet, og indsætte sine egne mocked/testbare afhængigheder. Høj kompleksitet for metoder, gør det også vanskeligere at lave gode unittest, da det bliver vanskeligt at strukturere testen så der bliver en god dækning af alle udfald. Komplekse udtryk i kontrol strukturer, mange and og or's, gør det vanskeligt at strukturere testen så der opnås dækning af alle udfald. - 19 - Brug af static metoder og variabler gør det vanskeligt at kontrollere testen, da de er vanskelige at mocke ud og ændringer af en static variabel et sted påvirker andre objekter etc. Undgå derfor også public non-final variabler. Law of Demeter, benyt de faktiske afhængigheder som metode kald og ikke et objekt der holder reference til et andet etc., så de reelle afhængigheder skjules i API'et. Et tydeligt tegn på det, er objekter der aldrig bruges direkte eller hvis der er mere end et '.' i en kæde, eks., request.getSession().getLastAccessedTime(). Ved at erklære de faktiske afhængigheder, vil metoden kunne testes uden at skulle tilvejebringe det store overordnede objekt. 4.4.2 Reliability (pålidellighed) Reliability beskriver hvor sandsynligt det er at koden gør det den skal, under de givne forudsætninger, over tid. Afgørende for reliability er fejlhåndtering. Både hvis input parametre til systemet er uden for det interval der er designet efter, og hvis output fra eksterne systemer er anderledes end forventet, samt evt. exceptions fra eksterne systemer. Eksempler der påvirker Reliability Høj dækning af unittest – med en høj dækning af unittest, kan det verificeres at koden gør det der er forventet. Kod efter at undgå null pointers ved f.eks. at have string literals på venstre side ved en sammenligning. Benyt tomme arrays i stedet for null etc. 4.4.3 Changeability (forandrelighed) Beskriver hvor godt ændringer til systemet kan implementeres. Det vil sige hvis en ændring til funktionaliteten specificeres, hvor enkelt er det så at tilpasse systemet til den specificerede ændring. Hindringer for dette kan f.eks. være duplikeret kode, som så skal rettes mange steder. Brug af 'magic stings' i stedet for konstanter og enumerations. Brug af arrays og strenge med positions bestemt betydning, frem for at skabe klasser til at holde en sådan struktur. Eksempler der påvirker Changeability Dybe kontrol strukturer til styring af flow. Få mennesker kan forstå mere end 3 niveauer af nestet if's [S. McConnell, Code Complete p. 485] 4.4.4 Efficiency (effektivitet) Evnen for et system til at give tilpas performance, i forhold til hvor mange ressourcer systemet forbruger. Ressourcer kan være både cpu tid, hukommelse etc. Indikatorer for dårlig effektivitet kan f.eks. være forkert brug af syncronization. Gemme objekter i større scope end nødvendigt eller mangelfuld oprydning, f.eks. efter at have gemt objekter på session. - 20 - Eksempler der påvirker Efficiency Undgå at benytte f.eks. StringBuffer som er syncronized, benyt i stedet StringBuilder hvis muligt. Af samme årsag, udskift Vector med ArrayList, Hashtable med HashMap, og Stack med Deque. Konstanter skal erklæres static final, i stedet for blot final for ikke at spilde memory. Undgå string concatenation med + operator i loops, benyt StringBuilder 4.4.5 Security (sikkerhed) Security beskriver evnen for et system til at sikre at uautoriserede personer eller systemer ikke kan læse eller ændre data, og at data ikke mistes. Eksempler der påvirker Security Sikre at følsomme data ikke logges forkert, benyt f.eks. ikke System.out til logning men benyt systemtes log. Arrays, undgå returnering af interne arrays, eller gem af input arrays i intern variabel. Benyt i stedet kopier for ikke at give eksterne objekter adgang til at ændre i objektets interne værdier. Input validering, valider for grænseværdier. Opmærksomhed ved input injektion f.eks. ved SQL, regular expression og xpath udtryk. Kan være problematisk både ved at give adgang til følsomme data, og ved stort ressource forbrug i forbindelse med DOS angreb. 4.4.6 Maintainability (vedligeholdelig) Maintainability beskriver hvor let det er at vedligeholde systemet. Det drejer sig i høj grad om hvor læse venlig og forståelig koden er. Er god kodeskik fulgt, benyttes standard konsistent, f.eks. ved navngivning af metoder og variabler. Ryddes der op i koden i takt med at den udvikler sig, fjernes deprecatede metoder over tid, bliver udkommenteret kode hængende, fjernes input parametre der ikke skal bruges etc. Læsbarheden vanskeliggøres også hvis der benyttes meget lange metoder, med mange linier, eller hvis der er flere statements pr. linje. Eksempler der påvirker Maintainability Udkommenteret kode bør fjernes, det tager fokus fra den reelle kode, hvis man har brug for det igen kan det findes via source kontrol systemet. Switch statemens skal ikke være for små, f.eks. blot to cases, da en if sætning i så fald vil være lettere at læse. Indholdet i hver enkelt case skal heller ikke være for stort, da der bliver for stor linie afstand mellem hver case, og man mister overbliket. - 21 - 4.4.7 Portability (porterbarhed) Portability beskriver hvor let systemet kan flyttes fra et miljø til et andet. Problemer kan være hvis der benyttes native kode etc. En af afgrænsningerne for alle systemerne her er at de afvikles på en IBM WebSphere Portal Server. Systemet betragtes ikke som uporterbar, på grund af denne afhængighed. 4.4.8 Reuseability (genbrugelighed) Reuseability beskriver evnen for komponenten til at blive genbrugt i et andet system, med minimale ændringer. Reuseability opnås gennem modularisering af koden. Afgrænsning af klasser, metoder, komponenter, så de udfører en opgave (separation of concerns). Mulighed for konfiguration, f.eks. gennem property filer. Det kan være konfiguration af tekster eller kontrol flows parametre. 4.5 Relateret arbejde Arbejdet her basere sig i høj grad på litteraturen som redegjort for og citeret oven for i kapitel 4. Men i litteraturen er der fundet meget lidt vedrørende SQALE modellen, og modellens evne til at afdække og teknisk gæld, samt professionelle udøveres brug af modellen til at styre teknisk gæld. ”Using source code Maintainability measures, for risk evaluation in insourcing” af Dennis Bohnstedt Hansen [D. B. Hansen, 2014], arbejder i et vist omfang med metrikker opsamlet vha. af SoanrQube, men behandler ikke SQALE modellen. Og den tekniske gæld der evalueres, tænkes benyttet til at vurdere maintanability, i forbindelse med insourceing, og ikke for at overvåge og reagere på den tekniske gæld der løbende opstår. ”On the Quality of Quality Models” af J.H. Hegeman [J.H. Hegeman, 2011], benytter ligeledes SonarQube til at give et kvalitets mål for et projekt, i forbindelse med vedligeholds opgaver på eksterne systemer (i lighed med insourcing). Projektet basere sig også på SQALE modellen, og forsøger at validere SQALE modelens mål for 4 kvalitets attributter, ved at holde dem op imod ekspertvurderinger af samme kvalitets attributter, for kilde koden. Der vurderes både på Java og .Net projekter, og der konkluderes at der er signifikant lighed mellem scoren givet af eksperter og af SonarQube implementeringen af SQALE. - 22 - 5 Manuel evaluering af projekterne 5.1 Udvælgelse af projekter For at udvælge de projekter der skal indgå i analysen, er nedsat en gruppe af løsnings arkitekter fra forskellige afdelinger i Bankdata. Tre arkitekter er hver blevet bedt om at stille med et projekt der kan indgå i evalueringen. De tre områder er udvalgt så de repræsenterer tre forskellige, men markante udviklingsområder, der alle afvikles på Bankdatas decentrale java platform. De tre projekter repræsenterer således et projekt indeholdende frameworkkode til brug for portletudvikling, en portlet baseret på førnævnte framework projekt. Det sidste projekt indeholder forretningslogik, der benyttes på tværs af flere portlets i samme udviklingsområde. Som beskrevet i kapitel 3.1, Udvælge projekter til deltagelse , vurderes det at de udvalgte projekter er repræsentative for udviklings projekter på den decentrale platform i Bankdata. 5.2 Evaluerings metoden - reviews Formålet med evalueringen af projekterne er at få en vurdering af projekterne, baseret på et fælles syn på teknisk gæld, så den automatiske evaluering af projektet efterfølgende kan vurderes. Det er ikke formålet at finde al teknisk gæld, og klassificere det. For at evaluere projekterne og klassificere den tekniske gæld er valgt inspektion eller review af kilde koden. Kilde koden er valgt som eneste artefakt der reviewes, for at kunne sammenligne med det automatiske review, som kun kan baseres på kilde koden og de kompilerede binære. Metoden for reviewet er mere en walk-through end en traditionel Fagan inspection, men dog i et vist omfang inspireret heraf. I resten af dette dokument omtales processen som review. I forhold til en Fagan inspection som beskrevet i [M. Fagan] er flere roller er dog slået sammen på en enkelt person. Således er scribe og moderator rollen slået sammen til en person. Mere bemærkelsesværdig er det at author og reader, også i nogle tilfælde er samme person. I de tilfælde hvor author og reader ikke er samme person, har reader forberedt sig på projektet i samarbejde med en eller flere udviklere fra projektet. Årsagen hertil er et ønske om at opnå en høj fart i reviewet. Ulempen ved at benytte walk-through, er at reader/author rollen har en tendens til at styre gennemgangen. Uklarheder i koden trækkes dermed ikke så tydeligt frem, da reader med sin kontekst baggrunds viden, forklarer sammenhænge for de øvrige reviewere. Det vil ofte gå ud over fordybelsen i problemstillingen. Den benyttede metode vil derfor forventelig have en tendens til at under repræsentere nogle aspekter af understandability, især navngivning af variabler og metoder – og dermed maintainability. Det er i evalueringen af SQALE - 23 - accepteret at denne underrepræsentation vil finde sted, da værktøjet ikke forventes at erstatte peer reviews, men i stedet være et supplement hertil, og optræde som en quality gate i forbindelse med Continuous Delivery. I øvrigt forventes værktøjet heller ikke at kunne vurdere på valget af metode og variable navne. Det væsentlige output fra reviewet er således en klassificering af mængden af teknisk gæld for hver af de 8 kvalitets attributter, og en overordnet score. Samt en fælles forståelse af teknisk gæld, i gruppen af reviewere, og for den reviewede kilde kode, sådan at gyldigheden i fund af det automatiske review kan verificeres. Selve reviewet tager udganspunkt i beskrivelsen af kvalitets attributter fra 4.4 Kvalitets attributter og den afledte checkliste i Appendix A og en samlet scoren bedømmes på baggrund af SQALE skalaen A-E, som beskrevet i 4.3, SQALE. Alle reviewere er erfarne arkitekter med lang erfaring i kode og arkitektur review. Studier viser at en enkelt review gennemgang af et dokument kun finder mellem 30 og 88 procent af alle fejl [T. Gilb]. Det må derfor forventes at den valgte metode generelt vil under repræsentere teknisk gæld, sammenlignet med automatisk review, som forventes at finde alle forekomster af den teknisk gæld værktøjet er istand til at påvise. Det er derfor mere interessant at finde forskellige typer af teknisk gæld, end at sikre at alle forekomster af en given fejl opdages. Det er derfor væsentligt at checklisten opfattes som inspiration og ikke som udtømmende for hvilke former for teknisk gæld, reviewerne må bringe på bordet. - 24 - 6 Værktøjs evaluering af projekterne 6.1 Introduktion til SonarQube SonarQube opsamler data for hvert projekt, som vises via web grænsefladen, som giver let adgang til at behandle de fundne problemer. Eksempelvis udtrækkes antal filer, antal klasser, linier kilde kode, funktioner og accessors (get/set metoder) fra dashboardet, se Figur 7, som er en overbliksside der giver et overordnet indtryk af projektet. Linier kode (LOC), benyttes til at udregne den samlede udviklings omkostning, i tid, baseret på opsæt af Udviklings omkostninger pr. linie. Eksempelvis for nedenstående beregnes den samlede udviklings omkostning til 4801 LOC * 30 min/LOC = 2400,5 time. SonarQube udregner på den baggrund SQALE scoren baseret på forholdet mellem en sammentælling af udbedrings omkostningerne for den tekniske gæld og den samlede udviklings omkostning i tid. - 25 - - 26 - projektet Figur 7: Dashboard fra PUMJsfPortalUtil I SQALE perspektivet, se Figur 8, vises filernes distribuering pr. SQALE score. Samtidig vises også gældens distribuering pr. kvalitets attribut, for de 9 kvalitets attributter. Bemærk at der ikke findes regler for validering af Useability i java projekter (se evt. appendiks C, SonarQube reglersæt), hvorfor denne gæld altid vil være 0. Figur 8: Distribuering pr Score, og teknisk gæld pr. kvalitets attribut for PUMJSFPortalUtil projektet Sunburst grafen, se Figur 9: Sunburst diagram over teknisk gæld for PUMJsfPortletUtil projektet, giver et overblik over fordelingen af den tekniske gæld i op til 3 niveauer. Inderste niveau er hver af de 9 kvalitets attributter. I 2. niveau er gælden delt op i under karakteristika, se (B, SQALE Quality attribute træ, med sub-attributter). Og endelig i yderste ring, er gælden delt ud per regel. - 27 - Figur 9: Sunburst diagram over teknisk gæld for PUMJsfPortletUtil projektet Fra Sunburst diagrammet, er det let at grave sig ned til de faktiske problemer i kildekoden. Ved at klikke på f.eks., en regel i diagrammet vises en oversigt over de filer hvor den pågældende regel er brudt. I eksemplet nedenfor, se Figur 10, er der trykket på 'Generic exception should never be thrown', fra 'Exception handling' karakteristikken fra Reliability attributten. Figur 10: Oversigt over filer der bryder reglen 'Generic exception should never be thrown' fra PUMJsfPortalUtil projektet Herfra er det igen muligt, ved at klikke på en af filerne i oversigten, at få vist den faktiske kilde kode, der bryder den pågældende regel, se Figur 11: Kilde kode med markering af regelbrud, fra PUMJSFPortalUtil projektet. - 28 - Figur 11: Kilde kode med markering af regelbrud, fra PUMJSFPortalUtil projektet 6.2 Konfigurering af SonarQube/SQALE Til evalueringen af kilde koden er brugt SonarQube v. 5.0.1 . Installationen er med default H2 database, med SonarQube, database og web server kørende på samme maskine. Som beskrevet i afsnit 4.3,SQALE, er en væsentlig del af konfiguration af SQALE valget af regler og metode til beregning af udbedrings omkostninger, pr. regel. Da kalibrering af SQALE ikke er et fokus emne i denne rapport er der i de automatiske review brugt standard SonarQube regelsæt, se Appendiks C, SonarQube reglersæt, som er opsamlet og vedligeholdt af SonarQube. Reglerne er konfigureret med default metoder for udregning af udbedrings omkostninger. Disse benyttes også uden yderligere konfiguration, ligesom SoanarQube's standard værdi for udviklingsomkostninger pr. linje kode er benytte. SonarQube er kørt med følgende konfigurationer for teknisk gæld. Udviklings omkostninger pr. linje kilde kode, 30 min Arbejdstimer pr. dag, 7 Unit test, minimum dækning af forgreninger, 65% Unit test, minimum dækning af linjer, 65% SQALE Score, baseret på forhold mellem estimeret tid det tager at indfri al teknisk gæld, i det efterfølgende kaldet udbedrings omkostninger, og udviklingstiden. Denne er lige ledes baseret på SonarQube standard værdi, og repræsenteret i Tabel 1. - 29 - Score Teknisk gæld udbedrings omkostning / udviklingstid = x A 0 < x =< 0,1 B 0,1 < x =< 0,2 C 0,2 < x =< 0,5 D 0,5 < x =< 1 E x>1 Tabel 1: SonarQube standard værdier for omregning til SQALE score Analyserne er kørt via sonar-runner fra command prompt, og konfigureret via sonar-project.properties, se eksempel i appendiks H, Sonar-project.properties eksempel. Unittest er kørt og opsamlet via jacoco 0.7.4 [Jacoco]. Udførelsen er sket ved kørsel af ant script, se eksempel i appendiks I, jacoco_build.xml eksempel. Jacoco rapporten er efterfølgende analyseret af SonarQube i forbindelse med kilde kode analysen. 6.3 Data fra SonarQube I de efterfølgende behandlinger af projekterne udtrækkes for hvert projekt følgende data til videre behandling. Linjer kilde kode, Lines of Code (LOC). Antal linjers kilde kode. Blanke linjer og kommentarer er ikke indregnet i kilde kode. Udviklings omkostninger i timer, beregnes på baggrund af LOC, som LOC * Udviklings omkostning pr. linje. Teknisk gæld, samlet mænge tid der skal benyttes for at udbedre alle fundne fejl, angives i minutter, timer eller dage. Hvis dage er benyttet, omregnes mellem dage og time ved hjælp af antal timer / arbejdstimer pr. dag. Teknisk gæld i procent, tid for udbedring af teknisk gæld i forhold til beregnet udviklingsomkostninger. SQALE score, overordnet score for hele projektet på A-E skalaen, baseret på teknisk gæld i procent og opsætningen af SQALE skalaen i SonarQube. Filer, antal filer analyseret i projektet Metoder, antal metoder i projektet, eksklusiv accessors Accessors, antal get/set metoder Statements, antal statements i projektet. I java projektet regnes pakke beskrivelse, import, klasse og metode erklæringer, kontrol strukturer (if, for, - 30 - while, try,catch etc.) ikke for statements. Complexity, kompleksitet for hele projektet. Kompleksitet beregnet jf. [McCabe], hver gang kontrol flowet splitter øges kompleksiteten af en metoder med 1. Alle metoder har minimum 1 i kompleksitet. Complexity/Funtion, gennemsnitlig kompleksitet pr. metode Complexity/Class, gennemsnitlig kompleksitet pr. fil. Fordeling af teknisk gæld pr. kvalitets attribut. Fil distribuering efter SQALE Score. Antal filer med Score A, B, C etc. Endelig har jeg lavet et data udtræk fra databasen, for at kategorisere den tekniske gæld. Data udtrækket repræsenterer samme data som SonarQube viser med SunBurst diagrammet. Men det format egner sig ikke til behandling her i rapporten. Derfor er data trukket ud og vist i tabel form, pr. projekt , der indeholder : Attribut navn, navn på problem der giver teknisk gæld, antal gange problemet er repræsenteret, samlet udbedrings omkostninger i minutter. Data er udtrukket vha. nedenstående SQL, i eksemplet her for projekt PUMJsfPortalUtil. select c.name,r.name, count(*), sum(technical_debt) as debt from ISSUES i, RULES r, CHARACTERISTICS c where i.root_component_id = (select id FROM projects where KEE like 'PUMJSFPortalUtil') and i.status = 'OPEN' and i.rule_id = r.id and (select cc.parent_id from CHARACTERISTICS cc where r.DEFAULT_CHARACTERISTIC_ID = cc.id) = c.id Group by c.name,r.name order by debt desc - 31 - 7 Evaluering af KROModel Reader: Predrag Vukelic Reviewer: Mogens Bram, Flemming Clausen, Predrag Vukelic Moderator/Scribe:Carsten Christensen Dato: 18/3 2015 7.1 Intro til projektet. Java projekt til brug for øvrige portletter i subsystem KRO (kredit sags håndtering), for at samle funktionalitet til kald af services, så portletterne kunne holdes som rene præsentations projekter. Formålet har været at øge genbrugeligheden af forretnings logik Projektet består af en række model klasser, som udgør en del af informations modellen. En række service klasser, der indeholder indkapslingen af kald til webservices på backend systemet inden for et afgrænset område. Samt en række Mapper klasser, der mapper webservice response til informations model objekter. Alle service klasserne er skåret over den samme list, og har samme struktur. Det samme gælder for mapper klasserne og model klasserne. Projektet indeholdt et lille antal unittest, samt integrations test. Alle baseret på JUnit. Test klasserne blev ikke vurderet. 7.2 Manuelt review Under gennemgangen af source koden var det derfor naturligt at kigge på hver klump af klasser for sig, og vurdere alle model klasserne under et, etc. Det gav os mulighed for i KROModel, at evaluere en stor mængde kode på forholdsvis kort tid, ved at koncentrere os om et par klasser af hver type, og lave stikprøve review af de øvrige. 7.2.1 Testability. Model: Høj testbarhed. I store træk rene java beans klasser med get/set metoder. Ikke komplekse klasser, single responsability var overholdt. Lidt statiske men ikke mutable variabler. Teknisk gæld: Lav, for alle klasser. Gav ikke anledning til bemærkninger Services: Dependency injection af ServiceOperationFactory, for at øge testability, så det er enkelt at lave mockning af servicekaldet. Overholder generelt single responseability, men nogle service klasser er orchestration klasser, hvilket naturligt giver klasser med mange afhængigheder. Teknisk gæld: Lav - 32 - Mapper: Mapper metoderne var lavet statiske hvilket kan besværliggøre testen. Teknisk gæld : Middel Samlet teknisk gæld vedr. testability, Lav. 7.2.2 Reliability: Model: Validering af data integritet benyttes ikke – ren set uden at validere input. Meget lav/ingen test coverage af klasserne. Teknisk gæld : Lav Services: Benytter null, i stedet for tomme array i enkelte tilfælde. Meget lav/ingen test coverage af klasserne. Teknisk gæld : Lav Mapper: Meget lav/ingen test coverage af klasserne. Teknisk gæld: Lav Samlet Teknsik gæld: Lav evt. Middel afhængig af vægtning af unit test coverage. En del var dog dækket af integrations testen, som af udviklerne på projektet blev anset for mere anvendelig i dette tilfælde. 7.2.3 Changeability: Model : Strenge er trukket ud som konstanter. Klassernes karakter gav lidt at de var ret godt modelleret Teknisk gæld: Lav Services: Ingen kommentarer vedr. changeability Teknisk gæld: Lav Mapper: Teknisk gæld: Lav Samlet teknisk gæld: Lav. 7.2.4 Efficiency: Samet teknisk gæld: Lav. Der var generelt ingen kommentarer vedr. efficiency. - 33 - 7.2.5 Security: Model: Der er toStrig metoder på alle modelklasse, til brug i debug/log som printede alle variabler i klassen. Kunne måske være et problem, ved at logge for meget. Teknisk gæld: Lav Service: Ingen kommentarer vedr. sikkerhed Teknisk gæld: Lav Mapper: Igen kommentarer vedr. sikkerhed Teknisk gæld: Lav Samlet teknisk gæld: Lav. Den overordnede sikkerhed til platformen hvor koden afvikles varetages på et højere niveau. 7.2.6 Maintainability: Model: Navngivning, mange forkortelser. Forkortelser var indlysende for udviklere på området, men svært læselige for andre. Teknisk gæld: Lav Service: Brug af cheked exceptions som der ikke kan reageres på alligevel. Benyt i stedet fail fast princippet. Benytter enkelte steder Arrays med java objecter i stedet for lister. Der benyttes hardcodede strenge for servicenavne i stedet for brug af konstanter Spørgsmål omkring instantiering af Logger, bør overvejes om det skal være lazy initalization. Teknisk gæld: Middel Mapper: Lidt komplekse metoder som med fordel kan splittes, men ofte er grunden at der mappes mange felter. Der blev benytte arv fra en overordnet ModelObjectMapper klasse, men formålet med nedarvningen var primært at få adgang til utility metoder der var generelle for mange klasser. Det kunne med fordel laves som en utility klasse der indeholdt generelle mapper metoder, eks. Mapning af ”Ja”/”Nej” til boolean værdi. Teknisk gæld: Middel Samlet teknisk gæld: Middel - 34 - 7.2.7 Portability: Samlet teknisk gæld: Lav, generelt ingen kommentarer vedr. portability 7.2.8 Reuseability Samlet teknisk gæld Lav. Projektet var netop oprette med reusability for øje. Afgrænsede klasser og metoder 7.2.9 Konklusion Kvalitets attribut Teknisk gæld Testability Lav Reliability Lav/Middel Changeability Lav Efficiency Lav Security Lav Maintainability Middel Portaility Lav Reuseability Lav Et velstruktureret projekt. Primære problemer i Service klasserne hvor også langt den meste logik var placeret. Mapper og model klasser var ret enkle i opbygningen. Især mapper klasserne kunne have haft fordel af bedre unit test coverage. Samlede tekniske gæld vurderet til at være mindre end 10%, hvorfor projektet fik scoren A 7.3 SQALE evaluering med SonarQube Efterfølgende blev SQALE evaluering af samme projekt gennemgået 7.3.1 Data fra evalueringen: Linier kilde kode 7640 Udviklings omkostninger i timer 3820 timer Teknisk gæld 205 timer = 29 dage Teknisk gæld i procent 5,4 % SQALE score A Filer 117 Metoder 525 Accessors 635 Statements 3256 Complexity 1338 - 35 - Complexity/Funtion 2,5 Complexity/Class 11,1 Fordeling af teknisk gæld Figur 12: Teknisk gæld for KROModel Detaljer vedr. enkelte kvalitets attributter, se appendiks D, Teknisk gæld i KROModel, for specifikke målinger. 7.3.2 Testability: Største post var ’Methods should not be to complex’ på ca. 4 timer, et problem som den manuelle test til en hvis grad også havde afdækket, og efterfølgende behandling af de af værktøjet udpegede problemområder, viste at review gruppen var enige i bedømmelserne. 7.3.3 Reliability: Den mest markante enkelt post var den manglende unittest coverage, som alene var sat til ca. 17 dage, jf. appendiks D. Unittest coverage var behandlet under den manuelle evaluering. Der var lavet integrations tests som dækkede en større del af koden, men disse var ikke medtaget i SQALE evalueringen. Der var ikke enighed i gruppen om hvor stor en test coverage der var ønskeligt, og det er mere et spørgsmål om konfiguration og kalibrering at finde det ønskede niveau, så uenigheden på det punkt behandles ikke yderligere. Målingerne af den manglende unit test var i sig selv korrekt. Den anden store post var ’Fields in a "Serializable" class should either be transient or serializable’. Ved nærmere undersøgelse viste det sig at skyldes at nogle model klasser var serializable, men indeholdt andre model klasser som ikke var markeret serializable. Problemet var ikke afdækket af det manuelle review, men review gruppen var enige i problemet. 7.3.4 Changeability: Største post var ’duplicated blocks’ som udgjorde 1 dag og 6 timer. Det var en gæld som det manuelle review ikke havde fanget, men efter følgende behandling verificerede problemet. 7.3.5 Efficiency: Syncronized StringBuffer blev benyttet i stedet for StringBuilder. Det manuelle review havde ikke afdækket problemet men gruppen var i øvrigt enige. - 36 - 7.3.6 Maintainability: Største post var ’public methods should throw at most one checked exception’, som udgjorde 5 dage 2 timer. Måden at behandle exceptions på var også kommenteret under den manuelle evaluering, hvor det dog var udtrykt anderledes, som at bruge en fail fast strategi, i stedet for at lade exceptions boble op. En anden betydende post var brugen af empty arrays i stedet for null, som udgjorde 4 timer og 30 min. Det manuelle review havde ikke fanget de samme problemer, men gruppen var i øvrigt enig i problemet. Øvrige attributter var uden betydning for det generelle billede. 7.3.7 Fil distribuering efter SQALE Score Ialt 117 filer A : 96 B:9 C:6 D:6 Alle D og C mærkede filer var af typen ’Service’ og den tekniske gæld der flyttede filerne ned på D niveau, var behandlingen af exception, som også var påpeget under det manuelle review, samt den manglende test coverage. 7.4 Konklusion på automatiseret SQALE review contra manuelt review. Der var en høj sammenhæng mellem de problemer der blev fundet i det manuelle review og det automatiserede. De problemer det manuelle review kunne finde som det automatiserede havde vanskeligt ved var især design betinget gæld. Eksempelvis hvor der var brugt arv, hvor det mere var et ønske om let adgang til funktionalitet frem for egentlig begrundet i klasse arv. Og spørgsmål om lazy instantiation contra constructor instantiation af enkelte variabler. Det automatiserede review var bedre til at finde dupliceret kode, ligesom fejl i erklæringen af serializable klasser ikke blev afdækket af det manuelle review. Der blev ikke fundet teknisk gæld af det automatiserede review som review gruppen var uenig i, bort set fra test coverage, som der ikke var enighed i gruppen om hvordan skulle håndteres. Dette kan dog i høj grad betragtes som et konfigurations spørgsmål. Der blev ikke under reviewt foreslået nye regler som Sonar-Qube skulle benytte til at afdække gæld som ikke allerede blev afdækket. - 37 - 8 Evaluering af PUMJSFPortalUtil Projekt: PUMJsfPortalUtil Reader: Flemming Unnerup Reviewer: Mogens Bram, Flemming Unnerup Moderator/Scribe: Carsten Christensen Dato: 24 & 26/3 2015 8.1 Intro til projektet Projektet er framework kode til brug i alle jsf portlets. Projektet består af 3 moduler PUMJsfPortletUtilAPI og PUMJsfPortletUtilImpl, som er traditionel interface og implementering. Samt et PUMJSFPortletUtilFwkAPI, som er interface der kun er beregnet udstillet til nogle begrænsede klienter, i.e. andet framework kode. Projektets karakter af framework kode gør at alle klasser har et ret højt kompleksitets niveau, og afhængigheder til 3. parts kode. Projektet består af utility klasser, servlet filtre, phase listners etc. som alle er ret hårdt bundne til den underliggende container. 8.2 Manuelt review Reviewet er foretaget en klasse af gangen, og der er noteret de væsentlige fund. Constant.java Changeability: Duplikeret kode i api/imp/Fwk, mangler oprydning og konsolidering. Mangler javadoc ConstantsFwk -> rename Constants, skal den overhovedet være her. Der er ikke noget over jsf-fwk. JSFPortletUtilFactory.java Changeability: Duplikeret i api/impl JSFPortletUtilImpl, JSFPortletUtil: Testability: Stor binding til især FacesContext, som vanskeligt lader sig teste. Dybe kald i 5 niveauer, så det vil være et stort arbejde at lave mock objekter for at teste, ses f.eks., i metoden getManagedBean(String mangedBeanName) og den tilhørende private metode resolveExpression(String expression) public Object getManagedBean(String managedBeanName) { String expression = "#{" + managedBeanName + "}"; return resolveExpression(expression); } - 38 - private Object resolveExpression(String expression) { Object value = null; if ((expression.indexOf("#{") != -1) && (expression.indexOf("#{") < expression.indexOf('}'))) { value = getFacesContext().getApplication().getExpressionFactory() .createValueExpression(getFacesContext().getELContext(), expression, Object.class).getValue(getFacesContext().getELContext()); } else { value = expression; } return value; } Maintainability: Logning fylder meget og hindre læsbarheden, METHOD_ENTRY/EXIT kan evt. flyttes ud i LOG api’et. getProperty() – dårligt navngiviet metode, ud fra hvad den faktisk gør. resetFlowScopeCacheForPortlet – tom metode bør fjernes resetRenderScopeCacheFor - samme resetPortletPageScope for portlet - samme Changeability: Alle de deprecatede metoder bør wrappe, de nye implementeringer i det omfang de ikke kan slettes, i stedet for at have implementeringen liggende to steder. Deprecatede metoder skal på et tidspunkt fjernes. Omkostningen i klassen her er lille, men stor omkostning fordi metoden benyttes mange steder. Methodname, er hardcoded ved logning, hvilket giver problemer ved refaktorering. Kan afhjælpes af et andet log api. Reliability: resolveExpression() – Object value = null, bedre ikke at initializere med null, så compileren vil fejle hvis variable er unasigned. MessageUtilImpl.java, MessageUtil.java Maintainability: Indeholder Javadoc til en ikke eksisterende metode. Kan blot slettes, omkostning herved er minimal. Warn log ved severity. Log level er for højt eller skal helt fjernes. Minimal omkostning. Konstant navne for ’MP’ og ’DA’ i stedet for magic strings, gør koden mere læsbar, og øger samtidig changeability, ved refactorering. clearMessage() navngivning af variabler, er dårligt valgte. Reliability: addMessage(), godtager null som argument, men bør fejle med illigalargument, argument validering. Vil samtidig øge testbarheden. Testability: complex metode, tester for meddelelse == null, og det vil den altid være på det tidspunkt. Giver dårlig læsbarhed, og er unødvendig. hasBundleKey() bør breake frem for at styre på boolean , giver kompleks logik. clearMessage(), compleksitet, opsplit evt. i to private metoder. getMessageFromBackend(), benytter service facade, som findes via statisk metode kald der ikke kan mockes. - 39 - NavigationUtil.java,NavigationUtilImpl.java Maintainability: Javadoc i impl. Klassen, bør kun ligge i API, kan blot slettes. getPageTitle(), lokal variabel tildeles værdi for derefter blot at blive overskrevet, skal bare returnere værdi getPageTitle(), skal ikke være statisk, har ikke den store betydning her, og kan blot ændres. Metoden er privat og kan blot ændres. Forringer læsbarheden af koden med dette statiske metode kald. checkAuthorization() navngivning sammenholdt med konsekvensen i metoden er ikke tydelig. Mange kald til f.eks JSRPortletUtilFactory. getInstance(), flyt util objecter op som instance variabler i klassen for at øge læsbarheden Testability: Har mange afhængigheder der ikke fremgår af API. Der benyttes factory klasser til at tilvejebringe instanser, hvilket er positivt for testbarheden. AbstractFiter.java Maintainability: Klassen bør være abstract – hvilket navnet også antyder. Logger bør være subClass’s logger, og ikke AbstractFilter’s, da det ellers ikke vil fremgå af logning hvilket klasse der reelt logger. Fjern java doc på impl klasse, bør kun ligge på API. Logning fylder meget, if (isDebugEnabled()), kan mange steder fjernes, skal ellers omkranses af { } renderErrorPage() - udkommenteret kode – bør fjernes. Changeability: Strings trækkes ud som konstanter, f.eks., ”errorBean”, da det går igen mange steder og vanskelig gør ændringer. Testability: renderErrorPage(), kompleks, opsplit i flere private metoder, kontrol flow er ikke læsbart. Hård bundet til GetMethod og HttpClient, som er skjulte afhængigheder, gør det svært at teste uden at lave faktiske service kald til http server. FatalFilter.java Maintainability: Kompleks/lang metoder der kan splittes op. Kontrol flowet er svært læseligt, split metoden op. doFilter(ActionRequest) - debug log fylder meget , kan skrives simplere, gør koden svært læselig. try/catch blok inde i en anden catch blok, bør lægges ud i egen metode, for at øge læsbarheden. cleanUpPortletAttribute() debug logning fylder meget og kan måske trækkes ud I egen metode, svært læsbar. Testability: handleChainError() kompleks control flow – return stament i if sætning if(instance of ..) {return}, - 40 - kan med fordel skrives om ved brug af not operator. isRetry(), kompleks kontrol flow, med mange returns Changeability: getRetryURL() Benytter specifik HashMap, hvor der med fordel kunne kodes mod Map interface dofilter(RenderRequest) - Duplikeret kode request.getAttribute(…).equals() InitializeFilter.java Maintainability: clearPortletSessionAttributes(), private metode benyttes aldrig. CustomExceptionHandler.java Maintainability: handle() – lang metode, kan med fordel splittes op i flere private metoder. 8.2.1 Summering pr. kvalitets attribut Testability: Generelt for klasserne, AbstractFilter, FatalFilter, InitializeFilter, PreventPopulateModelFilter, ServiceFacadeFilter, RenderResponsePhaseListener,Scope, FacesGenericPortlet og NavigationUtilImpl gjaldt at de har skjulte afhængigheder gennem adgang til diverse caches som SessionCache og ThreadCache. Disse cache objekter skaffes via statiske metode kald til CachingFactory, der vanskeligt lader sig mocke, og uden mulighed for at injekte afhængigheder. Objekter der skaffes gennem disse caches var bla. HttpServletRequest og en mængde forskellige attributter der læses og skrives, for der igennem at styre flowet i andre klasser. Eksempel fra FacesGenricPortlet LOGGER.debug(methodName, "Http Session timeout interval : " + ((HttpServletRequest)ThreadCache.getInstance().getRequest()).get Session().getMaxInactiveInterval()); Eksempel fra InitializeFilter if(CachingFactory.getThreadCacheInstance().getAttribute( Constants.PORTLET_IS_IN_INIT_KEY) != null) { Flere steder med hård binding til især FacesContext, med dybe kald, som gør det vanskeligt at konstruere mock objekter. Baseret på gennemgangen med enkelte komplekse metoder og ovenstående generelle betragtning om klasserne, blev testability vurderet til at være lav. Teknisk gæld: Middel Reliability: Meget lav dækning af unittest er den primære årsag til den lave score. Unittest er samtidig forholdsvis vanskelige at lave pga. skjulte bindingerne til - 41 - containeren. Det er forholdsvis komplekse klasser der skal mockes ud, f.eks., FacesContext, PortletRequest og PortletResponse. Teknisk gæld: Middel Changeability: En del deprecatede metoder og komplekse metoder. De deprecatede metoder kunne med fordel wrappe de nye implementeringer, i det omfang de ikke allerede helt kunne fjernes. En del duplikeret kode og enkelte klasser var duplikeret i de 3 moduler, hvilket gav unødig vedligehold. Javadoc var ligeledes duplikeret i både API og implementerings klasser, flere steder, og bør kun skulle vedligeholdes i API'et Der ud over var der ikke noget i koden der antyder at changeability skulle være lav. Den lave score er givet fordi evt. ændringer har stor indflydelse i andre applikationer, som har en stor refactorerings opgave. Teknisk gæld: Middel Efficiency: Ingen bemærkninger Teknisk gæld: Lav Security: Ingen bemærkninger Teknisk gæld: Lav Maintainability: Log fyldte generelt meget i koden og gjorde det ind imellem vanskeligt at læse kode. Flere tomme metoder der kunne slettes. Og enkelte metoder med kontrol logik der var vanskelig at læse. Flere steder var navngivning af variabler mangelfulde, og metodenavne misvisende. Abstract navngivet klasse var ikke abstract. Teknisk gæld: Middel Portability: Ingen bemærkninger Teknisk gæld: Lav Reuseability: Projektet er oprettet med henblik på reuseability, og forventes benyttet i en lang række projekter, og der blev ikke noteret problemer relateret til reuseability. Teknisk gæld: Lav - 42 - 8.2.2 Konklusion Kvalitets attribut Teknisk gæld Testability Middel Reliability Middel Changeability Middel Efficiency Lav Security Lav Maintainability Middel Portaility Lav Reuseability Lav Samlede tekniske gæld vurderet til at være mere end 10%, men mindre end 20%, hvor flere kvalitets attributter blev vurderet til at have en middel teknisk gæld, hvorfor projektet blev bedømt til en samlet score B 8.3 SQALE evaluering med SonarQube Efterfølgende blev SQALE evaluering af samme projekt gennemgået 8.3.1 Data fra evalueringen: Linier kilde kode 4801 Udviklings omkostninger i timer 2400,5 timer Teknisk gæld 16 dage = 112 timer Teknisk gæld i procent 7,2 % SQALE score A Filer 42 Metoder 269 Accessors 28 Statements 1392 Complexity 660 Complexity/Funtion 2,5 Complexity/Class 15,3 Fordeling af teknisk gæld - 43 - Figur 13: Teknisk gæld for PUMJsfPortalUtil Detaljer vedr. enkelte kvalitets attributter. Se Appendix E, Teknisk gæld i PUMJsfPortalUtil 8.3.2 Testability: Al teknisk gæld i forbindelse med testability, skyldes metode kompleksitet, fordelt på klasserne FlowScopeELResolver.java 11min CustomExceptionHandler.java 11min RenderScopeELResolver.java 11min PortalPageScopeELResolver.java 11min FacesGenericPortlet.java 11min AbstractFilter.java 11min FatalFilter.java 11min Der var fra gruppen ikke uenighed i den fundne tekniske gæld. Til gengæld var det gruppens opfattelse at testability var noget lavere, ud fra den betragtning at koden havde mange skjulte afhængigheder, der ikke fremgik af API'et og at disse afhængigheder tilmed var svære at mocke ud. Så her var stor uoverensstemmelse med det manuelle review og det automatiske. De skjulte afhængigheder der hentes via factory objekter, ville i sig selv ikke være så stort et problem, hvis disse factory klasser gjorde det muligt at mocke de faktiske implementeringer. Det kan derfor argumenteres for at den tekniske gæld derfor rettelig tilhører factory klasserne, og ikke dette projekt. 8.3.3 Reliability: Den mest markante enkelt post er den manglende unittest coverage, som alene var sat til 8½ dag. Unittest coverage var behandlet under det manuelle evaluering. På dette punkt var der ikke enighed mellem det manuelle review og det automatiske. Det var review gruppens opfattelse at grundet den lave testability, at det ville tage længere tid at lave unittest. Det kan dog argumenteres for at hvis testbarheden øges, ved at indfri den tekniske gæld vedr. testability, så ville unittests blive lettere at lave. Den anden store post var ’Generic exception should newer be thrown’, som udgør 12 timer. Gruppen var ikke enig i at det i de fundne tilfælde udgjorde en teknisk gæld. Det blev der imod foreslået at SonarQube reglen bliver ændret så dette ikke betragtes som teknisk gæld, såfremt en generic exception wrapper en anden exception. Øvrige poster var ubetydelige, men gruppen var i øvrigt enige i de fund. - 44 - 8.3.4 Changeability: Største post var ’duplicated blocks’ som udgjorde 2 dag og 4 timer. Nærmere undersøgelse viste at det var en gæld som det manuelle review ikke havde fanget i samme omfang, men efter følgende behandling verificerede problemet. Den duplikerede kode der blev fanget af det manuelle review, i Constant.java klassen, blev tilgengæld ikke opdaget af det automatiske review. Der blev kørt med ’Cross project duplication detection’ så opdeling i moduler forklarer ikke hvorfor værktøjet ikke fangede problemet. Ligeledes blev de duplikerede factory klasser ikke opdaget af SonarQube. Der er brug for at kigge nærmere på dette i tilpasningen af SonarQube. 8.3.5 Maintainability Største post, på 4 timer, var TODO tags, der ikke var håndteret. De stammede fra autogenereret kode, og kunne blot fjernes. De øvrige poster var ubetydelige, og gruppen var i øvrigt enige i de fund gjort af værktøjet. Der var dog stor uenighed mellem det automatiske review og det manuelle, hvor det manuelle review fandt koden langt mindre maintainable, især grundet svær læsbarhed af koden, pga. den intensive logning. Enkelte mere design relatered problemer som navnigving der dårligt matchede metodens faktiske udkomme. 8.3.6 Fil distribuering efter SQALE Score Ialt 42 filer A : 36 B:6 C:0 D:0 8.4 Konklusion på automatiseret SQALE review contra manuelt review. Afhængighederne til containeren er vanskelige at mappe ud, hvorfor reviewere mener at estimatet på at lave unittest coverage på 8½ dag, er lidt optimistisk. Gruppen estimerede generelt at teknisk gæld var større end værktøjet. Især testability skorede gruppen noget anderledes en værktøjet. Der var ikke enighed mellem gruppen og værktøjet om den gæld der blev fundet vedr. maintainability hvor gruppen ønskede kode der lå tættere på cleanCode for at øge læsbarheden. De fund der blev lavet under det manuelle review som var af mere design mæssig karakter, som f.eks. valg af navngivnig, kunne værktøjet ikke afdække. Gruppen var uenig i SonarQube reglen vedr. throw RunTimeException, som gruppen ikke anså for et problem når RunTimeException wrappede en anden exception. Overvej derfor at fjerne regel for throw RuntimeException, hvis man wrapper en anden Exception. Generelt var en stor del af den gæld review gruppen fandt, i relaterede projekter, som skulle refaktoreres pga. den gæld der var i dette projekt. Det kunne værktøjet naturligvis ikke afdække, eftersom værktøjet ikke har kendskab til de øvrige projekter. Værktøjet ville også regne teknisk gæld, som følge af at - 45 - deprecate metoder i dette projekt, som tilhørende de projekter der benytter den deprecatede kode, hvilket ikke var gruppens udgangspunkt i det manuelle review. - 46 - 9 Evaluering af SAGOpgaveListeJsfPortlet Projekt: PUMJsfPortalUtil Reader: Søren Lønbæk Christensen Reviewer: Mogens Bram, Flemming Clausen Moderator/Scribe: Carsten Christensen Dato: 10/4 2015 9.1 Intro til projektet Projektet er en portlet til brug i Bankdats's medarbejder portal, som er et administrativt værktøj til bank medarbejdere til betjening af kunder. Medarbejder portalen er opbygget af flere end 300 portletter, lignende SAGOpgaveListeJsfPortlet. SAGOpgaveListeJsfPortlet benyttes til håndtering af opgaver i forbindelse med låne sager etc. Portletter som denne i medarbejder portalen, er primært et præsentations lag. Al data ligger på Bankdatas Host platform, som tilgås via webservice kald, der er indkapslet af en facade. Den generelle opbygning af JSF portletter er defineret på baggrund af Bankdata standarder. 9.2 Manuelt review Reviewet er foretaget en klasse af gangen, og der er noteret de væsentlige fund, flere klasser var uden kommentarer i reviewet og er ikke vist her. HentOpgaverService.java Reliability: Undgå fejl med nulpointer ved sammenligninger ved at sætte konstant delene på venstre side. HentOpsaetningListeService.java Testability: Høj kompleksitet for populateAnsvarlist med flere returns i metoden LengtMin3Validator.java Maintainability: Navngivning af Validator registrering kunne med fordel benytte Camel Case notation, i lighed med klassenavn. AccordianBacking.java: Testability Law of Demeter, dyb afhængighed - 47 - til ExternalContext for at få requestParametre. Kunne med fordel flyttes til framework utility klasse, hvilket vil gøre det letter at lave testen for denne klasse vha. mocks Eks. FacesContext.geCurrentInstance().getExternalContext.getRequestParameterMa p() Benytter FacesContex addMessage() metoder – bør benytte wrappede metoder fra framework koden. Gør det vanskeligere at teste, da FacesContext er sværrer at mocke ud, og har potentielt et vedligeholdelses problem. Maintainability: ”this” keyword brugt overflødigt flere steder hvilket sænker læsbarheden. Typecast af Object value til Date, gøres mange steder i koden. Kan med fordel gøres et sted for at øge læsbarheden. TODO linie skal på et tispunkt udføres Formatering af koden, blanke linier mangler mellem metode. Kompleksitet i opgave.setCheckBehandling(opgave.getBehandling() != null), kan med fordel skrives om. Har også affødt at udvikleren har været nød til at skrive en kommentar for selv at kunne læse det efterfølgende. Changeability SetBehandling(), indeholder duplikeret kode, til håndtering af beskeder. Kan med fordel skilles ud i selvstændig metode. Security: Benyt log framework i stedet for System.out. ListeBacking.java: Testability Law of Demeter, dyb afhængighed til ExternalContext via FacesContext som i AccordianBacking. Går igen i flere metoder i klassen. Changeability: Duplikeret metode accordianAction(), som vidner om copy/paste fra foregående klasse der ikke er blevet slettet. Security: Benyt log framework i stedet for System.out. AnsvarListeData.java: Reliability: Sikre den private variabel ”Map ansvarlige”, mod at kunne indeholde null. Vil både gøre koden lettere læselig i flere kontrolstrukturer og sikre mod null pointer fejl. - 48 - DelOpgaverData.java: Maintainability: Todo linie skal på et tidspunkt udføres. OpgavelData.java: Maintainability: Slut bruger tekster skal hentes fra property filer af hensyn til sprog. OpgavelisteState.java: Maintainability: Udkommenteret kode skal fjernes Changeability: Indeholder duplikeret kode i resetPagination(), som med fordel kan refaktoreres ud i selvstændig metode. 24 linier kode er reelt samme 8 linier gentaget 3 gange, med blot en enkelt parameter til forskel. 9.2.1 Summering pr. kvalitets attribut Testability: Enkelte metoder med unødig høj kompleksitet – men det var virkelig i den lave ende. Dybe afhængigheder enkelte steder gennem FacesContext, som gjorde det vanskeligt at teste. Teknisk gæld: Lav Reliability: Meget lav dækning af unittest, kun to klasser var testet. Enkelte steder hvor man kunne sikre mod null pointer ved at vende udtryk, og ved at beskytte private variabler mod set metoder med null. Teknisk gæld: Lav Changeability: 2 steder med duplikeret kode, som med fordel kunne trækkes ud i selvstændige metoder, hvilket ville være ganske enkelt. Teknisk gæld: Lav Efficiency: Ingen bemærkninger Teknisk gæld: Lav - 49 - Security: System.out blev benyttet til som logning enkelte steder. Teknisk gæld: Lav Maintainability: Indeholdt TODO's som repræsentere en form for teknisk gæld, der blev ikke estimeret på hvor stor den tekniske gæld der lå bag. Enkelte steder hvor formatering af koden ikke var i henhold til gængse formaterings standard, enkelt at rette ved tooling. Udkommenteret kode der burde fjernes, enkelt at rette Typecast af variabel der blev benyttet ofte kunne med fordel samles et sted, enkelt at rette. Teknisk gæld: Lav Portability: Ingen bemærkninger Teknisk gæld: Lav Reuseability: Ingen bemærkninger Teknisk gæld: Lav 9.2.2 Konklusion Kvalitets attribut Teknisk gæld Testability Lav Reliability Lav Changeability Lav Efficiency Lav Security Lav Maintainability Lav Portaility Lav Reuseability Lav Samlet teknisk gæld vurderet til mindre end 10%, og hvorfor projektet blev bedømt til en samlet score A 9.3 SQALE evaluering med SonarQube Efterfølgende blev SQALE evaluering af samme projekt gennemgået - 50 - 9.3.1 Data fra evalueringen: Linier kilde kode 1332 Udviklings omkostninger i timer 666 timer Teknisk gæld 3 dage 3 timer = 24 timer Teknisk gæld i procent 3,7 % SQALE score A Filer 18 Metoder 79 Accessors 101 Statements 563 Complexity 176 Complexity/Funtion 2,2 Complexity/Class 9,8 Fordeling af teknisk gæld Figur 14: Teknisk gæld for SAGOpgaveListeJsfPortlet Detaljer vedr. enkelte kvalitets attributter. Se Appendix F, Teknisk gæld i SAGOpgaveListJSFPortlet 9.3.2 Testability: Det automatiske review fandt ingen teknisk gæld vedrørende Testability. 9.3.3 Reliability: Den mest markante enkelt post er den manglende unittest coverage, som alene udgjorde 17 timer. Næst største post var 20 min til sikring mod null pointer sammenligning ved at have streng konstanter på venstre side ved sammenligninger. Samme gæld som det manuelle review også fandt Der var ikke uenighed i de fund det automatiske review gjorde. - 51 - 9.3.4 Changeability: Eneste fund var duplikeret kode, hvor samme metode var i to klasser, samme metode som det manuelle review fandt. Det automatiske review opdagede ikke de fund af duplikeret kode fra det manuelle review der var mindre kodeblokke, som med fordel kunne skilles ud i selvstændige metoder. 9.3.5 Maintainability Største post var 4 TODO tags, som SonarQube estimere til 20 min pr. styk, da de repræsenterer en teknisk gæld, men som ikke er nærmere defineret. Det vil være en svær opgave at kalibrere den teknisk gæld fra et TODO tag, da det kan være alt fra en mindre rettelse når engang et andre afhængigheder falder på plads, til et helt redesign. Mere interessant var 2. største post, fundet af 'unused parameters' i flere metoder. Ved nærmere analyse viste det sig at være en form for falsk positiv. Ganske vist blev parametren ikke benyttet. Men parameteren var nødvendig da metoderne blev kaldt som validator metoder fra et jsf view, som krævede denne metode signatur. Øvrige punkter var review gruppen enige i, omend ikke alle var fundet under det manuelle review, f.eks. deklarering af thrown runtime exception, som ikke skal erklæres. Portability: Ingen teknisk gæld, i overensstemmelse med det manuelle review. Reuseability: Ingen teknisk gæld, i overensstemmelse med det manuelle review. 9.3.6 Fil distribuering efter SQALE Score Ialt 18 filer A : 18 B:0 C:0 D:0 9.4 Konklusion på automatiseret SQALE review contra manuelt review. Alt i alt meget lidt teknisk gæld i projektet, uanset om det ses af det manuelle review eller det automatiske. Der var en høj sammenhæng mellem de fund det manuelle review gjorde og fund af det automatiske review, og frem for alt var der enighed i de fund det automatiske review gjorde. Det automatiske review viser sig god til at finde ting, som kode formatering, udkommenteret kode, parametre der ikke benyttes, skønt disse i dette tilfælde faktisk var nødvendige. Det automatiske review har vist sig svag ved de mere design orienterede problemer, her specielt strukturering af koden så den blev mere læse venlig. - 52 - Mest bemærkelses værdigt her var duplikeret kode der med fordel kunne skilles ud i selvstændige metoder. I tilfældet her var det 3 blokke ens kode gentaget efter hinanden, se appendiks K. Det var ganske enkelt for det manuelle review at fange, og burde også kunne opdages af automatiske reviews. - 53 - 10 Sammenlign manuel og værktøjsbaseret evaluering 10.1 Konklusion på SQALE SonarQube har vanskeligt ved at detektere gæld som er design relateret, f.eks. syntes der at være flere steder hvor problemer med testability ikke findes. Det ville dog i en vis grad opdages hvis unittest faktisk blev lavet – hvilket detekteres i reliability indekset. Men der er ingen garanti for at de er lavet mest optimale, og den indkapsling der sker ved f.eks., statiske factory klasser, er lidt vanskeligere at mocke, og lader sig kun gøre ved byte code manipulation – det detectere SonarQube ikke. 10.2 Konklusion på processen Især den analyserede portlet havde meget lidt teknisk gæld, og en mulighed var at portletten ikke var repræsentativ for JSF portletter på Bankdata. En årsag hertil kunne skyldes at arkitekter er blevet bedt om selv at stille med projekter, og der er ikke nogen der har ønsket at udstille det værste de har i skuffen. For at verificere om portletten var repræsentativ, udvalgte jeg efterfølgende tre portletter til stikprøve kontrol. Der blev udelukkende kørt automatisk review, da det er en meget overkommelig process, og der har generelt været enighed i den fundne gæld fra de automatiske review. Gælden i disse stikprøve kontrol projekter blev ikke efterfølgende gennemgået, de tjente udelukkende det formål at sandsynliggøre at det oprindelige portlet projekt var repræsentativt. De tre projekter viste en teknisk gæld på 3,4%, 4,7% og 4,5% - altså i ca. samme størrelses orden som SAGOpgavelisteJsfPortlet. Det antages derfor at SAGOpgavelisteJsfPortlet projektet er repræsentativt for JSF portlets på Bankdata. Data fra de automatiske review af de tre kontrol projekter fremgår af appendiks G, SQALE data for kontrol projekter Det har været lidt svært at sammenligne det manuelle review som er meget beskrivende og ikke baseret på faktiske tidsestimater, med det automatiske review som forsøger at sætte tid på, og score på den baggrund. Formålet med projektet var dog ikke at kalibrere tidsestimaterne, men at vurdere om det automatiske review kan benyttes til styring af den tekniske gæld. Det var derfor væsentligt at reviewerne, som alle var erfarne arkitekter, ikke var bundne af tjeklister, men at de fandt de udfordringer de mente var mest presserende for koden, for efterfølgende vurdere reviewernes tillid til værktøjet. Processen med de manuelle review og efterfølgende verificering af det automatiske review har virket godt og givet en fælles forståelse for teknisk gæld, og værktøjets muligheder for at vurdere denne. Processen har dermed - 54 - været nyttig til at forberede review gruppen til en vurdering af SQALE som kvalitets sikrings model, til styring af teknisk gæld. - 55 - 11 Udøveres vurdering af SonarQube / SQALE 11.1 Fokus gruppe diskussion Medlemmerne i fokus gruppen er udvalgt fra en gruppe af arkitekter og projektledere der deltager i strategi arbejdet omkring kodekvalitet på den decentrale platform i Bankdata, specielt med fokus på continuous delivery. 3 af arkitekterne har deltaget i reviewet af de 3 udvalgte projekter, og har været arkitekter i de udvalgte projekter. Ud over deltagelse i review af projekterne, havde alle deltagerne fået en demonstration af SonarQube og SQALE inden mødet. De 3 rapporter for projekterne, se kapitel 7, 8 & 9, var fremsendt inden mødet, lige som også følgende 3 spørgsmål gruppen skulle forholde sig til, var sendt til de enkelte deltagere inden. - er teknisk gæld et begreb som kan benyttes i styringen af kvaliteten. Vil gruppen anbefale at mængden af teknisk gæld systematisk afdækkes i alle/udvalgte projekter. - Vil SonarQube og SQALE kunne benyttes til rapportering af den tekniske gæld, er der overensstemmelse med den tekniske gæld fundet af manuelle og automatiske review. - kan automatiske review, vha. SonarQube og SQALE, erstatte manuelle review. Hvis ikke kan automatiske review supplere manuelle review, evt. for udvalgte kvalitets attributter, i et sådan omfang at det vil anbefales at projekterne altid gennemgår automatisk review inden manuelle review. Alternativt kan SonarQube og SQALE benyttes som guide for det manuelle review. Gruppen bestod af 1 projektleder og 5 arkitekter. Mødereferatet, se appendiks J, Referat fra fokusgruppe diskussion om teknisk gæld og SQALE, blev efterfølgende godkendt af deltagerne. 11.2 Resultat Der blev taget udgangspunkt i de 3 spørgsmål, som var sendt rundt inden mødet. De var dog vanskelige at adskille i diskussionen, så der var tendens til at svare på alle 3 spørgsmål samtidig. Diskussionen er gengivet i appendiks J, Referat fra fokusgruppe diskussion om teknisk gæld og SQALE Følgende konklusioner kan fremdrages for hver enkelt spørgsmål. - Er teknisk gæld et begreb som kan benyttes i styringen af kvaliteten. Vil gruppen anbefale at mængden af teknisk gæld systematisk afdækkes i alle/udvalgte projekter. - 56 - Gruppen fandt at det gav god mening systematisk at afdække den tekniske gæld i alle projekter løbende. Og det at følge trenden i hvor projektet bevæger sig hen, i.e., akkumuleres der gæld over tid, eller håndteres gælden så den nedbringes når der er mulighed for det, vil være vigtigt. Der blev udtrykt behov for at begrebet skulle forankres bredere i organisationen, men enkelte steder var begrebet allerede i et vist omfang i brug, og metaforen var let at forstå og forklare. Begrebet teknisk gæld som det blev brugt i dag var bredere en blot den del værktøjet målte, f.eks udtrykt som ”Syntes vi bruger begrebet allerede nu. Men benyttes lidt bredere, hvor det tal der rapporteres af værktøjet kun er en del af det ” - Vil SonarQube og SQALE kunne benyttes til rapportering af den tekniske gæld, er der overensstemmelse med den tekniske gæld fundet af manuelle og automatiske review. Generel enighed i at det er et stærk værktøj til at afdække den tekniske gæld og ikke mindst at rapportere på den. Bla. Ved at følge udviklingen over tid. Værktøjet rapporterede interessante kvalitets attributter, men kalibreringen manglede. Man skulle gerne kunne stole på tallet ”i store træsko længder”. Men kalibrering kan komme på plads hen af vejen. Men der var også enighed i at den tekniske gæld, rapporteret af værktøjet, ikke var hele sandheden, men kun en del af den samlede tekniske gæld. ”Den gæld værktøjet her viser er en ud af tre ting der skal med når der rapporteres. Manglende funktionalitet, desin gæld og teknisk gæld.” - med den betydning at design gæld, relaterede sig til mere strukturelle ændringer. Målingerne har stadig relevans ”Selvom det ikke fanger de design relaterede problemer, fanger det stadig væk en stor del af den gæld projekterne vil akkumulere.” Det betyder også at værktøjet ikke er super velegnet til at rapportere længere op i systemet, udtrykt som ”afdelings ledere, team ledere og hvem der ellers rapoprteres til, kan ikke forholde sig det (time tallet for den teknisk gæld), det må være den samlede teknisk gæld der skal rapporteres.” Og andet steds ”hvis ledere efterspørger, hvad der er af teknisk gæld, så vil jeg bruge værktøjet + min viden om projektet til at rapportere det.” Dog var der en forventning om at de projekter hvor værktøjet viste meget gæld i et vist omfang også var de projekter hvor der var design orienterede problemer ”Selv om der ikke kan måles de mere design relaterede problemer, vil det formentlig i et vist omfang følges med den tekniske gæld vi kan måle. Så værktøjet vil give en indikator for hvor der ligger andre problemer gemt.” - 57 - - Kan automatiske review, vha. SonarQube og SQALE, erstatte manuelle review. Hvis ikke kan automatiske review supplere manuelle review, evt. for udvalgte kvalitets attributter, i et sådan omfang at det vil anbefales at projekterne altid gennemgår automatisk review inden manuelle review. Alternativt kan SonarQube og SQALE benyttes som guide for det manuelle review. Der var generel enighed om at det gav rigtig god mening at benytte værktøjet som supplement til det manuelle review, både til at finde de mere trivielle ting, som de manuelle review kunne koncentrere sig mere om det strukturelle, et sted udtrykt som ”et godt værktøj til at finde de mere kedelige ting, eksempelvis, nogle klasser var serializable medens andre i arve hierakiet ikke var. Giver tid til at det manuelle review kan fokusere på de mere design orienterede ting” Men også som hjælp til at udpege de projekter hvor der var brug for manuelle review, udtykt som ”Værktøjet kan være en hjælp til at finde de rigtige projekter at reviewe, og evt. se hvilke områder/udviklere det er nødvendig at være lidt tættere på for at vi udvikler os i den rigtige og samme retning” - 58 - 12 Konklusion Gennemgang, med manuelle og automatiske review af de 3 projekter viser at der er god sammenhæng mellem den teknisk gæld fundet ved de manuelle review og de automatiske review. Især for de kvalitets attributter knyttet til SQALE modellens tidligste livscyklus. Der blev ikke afdækket gæld sidst i livscyklusen (portability og reuseability), hverken i de manuelle eller automatiske review. Gennemgangen viste dog også at teknisk gæld af mere strukturel karakter, relateret til design, ikke lod sig afdække af automatiske review, eksempelvis hvor et arve hierarki mellem objekter ville øge readability og dermed maintainability. Den tekniske gæld der blev rapporteret af værktøjet kunne dermed ikke stå alene og var ikke dækkende for den samlede mængde teknisk gæld i projekterne. Trods det, at ikke hele den tekniske gæld blev rapporteret af SonarQube, fandt gruppen af arkitekter og projektledere stadig at SQALE modellen var nyttig til at rapportere på komponenternes kvalitet. Rapporterne om komponenternes kvalitet ville dog være bedre egnet til at rapportere i den kodenære del af organisationen, så som udviklere og arktiekter og systemansvarlige. Rapporteringen var mindre velegnet i de øvre ledelses lag som afdelingsleder, område direktører etc. Her ville værktøjets kvalitets attribut målinger dog stadig med fordel kunne indgå som en del af rapporteringen, til styring af kvaliteten. Gruppen lagde hermed mere vægt på det analytiske view i SQALE modellen og mindre på det eksterne view, og den samlede SQALE score. Fokus gruppen anbefalede at SQALE modelen blev benyttet systematisk på alle komponenter på den decentrale platform, til at følge og styre den tekniske gæld i komponenterne. - 59 - 13 Fremtidig arbejde. Opgaven her har udelukkende haft fokus på Java udvikling. SQALE modellen er sprog neutral, og da en stor mængde kode stadig udvikles og vedligeholdes i Cobol, vil det være interessant at afdække modellens egenskaber i forbindelse med Cobol udvikling. Ud over forskellene i sprogene, kan der være stor forskel på kulturen blandt Cobol og Java udviklere. Men behovet for løbende at vurdere kvaliteten og håndtere den tekniske gæld vil være den samme. Det vil derfor være interessant at undersøge om samme positive resultater kan opnås her. En anden opgave, der skal arbejdes videre med, er kalibrering af metoden. Det var bevidst fravalgt i denne undersøgelse, men det var et ønske i fokus gruppen at den estimerede tid fra projektet blev vurderet mod det faktiske tidsforbrug til at afvikle gælden, og at SQALE modellen efterfølgende blev kalibreret. I et af projekterne, SAGOpgaveListeJsfPortlet, viste SonarQube sig at have problemer med at afsløre duplikeret kode, se appendiks K. Der skal arbejdes videre med at finde en metode så den type af gæld lader sig afsløre vha. SonarQube og rapporteres som teknisk gæld. Jeg har afprøvet PMD's Copy/Paste detector [PMD CPD] på samme kode, som finder problemet i kilde koden. CPD skal bruge som input hvor fint følende algoritmen skal være, for ikke at finde for mange 'falske positive', hvor man reelt ikke vil kalde det duplikeret kode. På SAGOpgaveListeJsfPorjektet blev benyttet en minimumTokenCount på 30, hvilket gav et fornuftigt resultat. Men der skal arbejdes videre med at justere denne værdi, og få det omsat til en regel i SonarQube. - 60 - 14 Referencer [A. Aurum et al.] A. Aurum, H. Petersson and C. Wohlin, ”State-of-the-Art: Software Inspections after 25 Years” [D. B. Hansen, 2014] Dennis Bohnstedt Hansen, 2014, ”Using source code Maintainability measures, for risk evaluation in in-sourcing”, ”http://cs.au.dk/fileadmin/site_files/cs/Masters_and_diplomas/Thesis_Dennis_B ohnstedt_Hansen.pdf” [Fenton 1997] Norman E. Fenton – ”Software Metrics: a Rigorous & Practical Approach, 2nd edition revised printing”, ISBN 0-534-95425-1, Int. Thomson Publishing, 1997 [Haughey, 2008] Haughey, D., 2008. An Introduction to Project Management. Project Smart. [J. H. Hegeman] J. H. Hegeman, 2011, ”On the Quality of Quality Models”, ”http://fmt.cs.utwente.nl/education/master/90/” [Jacoco] http://www.eclemma.org/jacoco/ [Letouzey, 2010], Jean-Louis Letouzey, Thierry Coq, 2010, ”The « SQALE » Analysis Model. An analysis model compliant with the representation condition for assessing the Quality of Software Source Code” [Letouzey, 2012], Jean-Louis Letouzey, 2012, ”Testability is the mother of ability”, ”http://www.sqale.org/blog/testability-is-the-mother-of-ability” [Letouzey, SQALE V1.0] Jean-Louis Letouzey, 2012, ”The SQALE Method Definition Document” version 1.0 [M. Fagan] M. E. Fagan, “Design and Code Inspections to Reduce Errors in Program Develop ment,” IBMSysfmsJ., Vol. 15, No. 3, 1976, pp. 182-211 [M. Fowler] Martin Fowler, Kent Beck (Contributor), John Brant (Contributor), William Opdyke, don Roberts. ”Refactoring: Improving the Design of Existing Code” [M. Fowler, Technical Debt Quadrant], Martin Fowler, http://martinfowler.com/ bliki/TechnicalDebtQuadrant.html [M. Bland, testing-culture], Mike Bland, http://martinfowler.com/articles/ testing-culture.html [M. Hevery] http://misko.hevery.com/attachments/Guide-Writing%20Testable %20Code.pdf [McCabe] McCabe (December 1976). "A Complexity Measure". IEEE - 61 - Transactions on Software Engineering: 308–320. [PMD CPD] PMD Copy/Paste Detector, http://pmd.sourceforge.net/pmd4.3.0/cpd.html [R. Krueger] Richard A. Krueger, Mary Anne Casey. Conducting Focus Group Interviews.” ”Designing and [R. Martin, The Clean Coder] Robert Cecil Martin, ”The Clean Coder”, ISBN13: 978-0137081073 [R. Martin, 2009] ”A Mess is not a Technical debt”, https://sites.google.com/ site/unclebobconsultingllc/a-mess-is-not-a-technical-debt [T. Gilb] Software Quality Professional - March 2000, ”Planning to Get the Most Out of Inspection” [W. Cunningham], Ward Cunningham, OOPSLA'92, Experience Report, ”The WyCash Portfolio Management System.” [W. Cunningham, 2009] Ward Cunningham, ”Ward Explains Debt Metaphor”, http://c2.com/cgi/wiki?WardExplainsDebtMetaphor - 62 - Appendiks A. Manuel review, checkliste Testability: – har klasen single responsibility, Komplekse klasser – har metoden single responsibility, Komplekse metoder - er udtryk sammensat og komplekse, så udfaldet bliver for stort til at være praktisk testbart, Komplekse udtryk - benyttes statiske metodekald, der ikke lader sig mocke så koden ikke er testbar - benyttes public non final variabler - erklæres de faktiske afhængigheder, eller benytte dybe '.' lister, eks. aa.bb.cc.dd(), input parametre benyttes ikke direkte. Law of Demeter, API erklærer ikke de faktiske afhængigheder, Reliability: - hvad / hvor meget testes - benyttes mange null pointer sammenligninger, Undgå Null pointer – Tomme arrays i stedet for null. - kan null pointer undgås ved at vende streng sammenligninger, så konstant udtryk er på venstre side, i.e., ”tekst”.equals(variabel); - valideres input for grænseværdier Changeability: - er kode duplikeret andet sted i metoden, klassen, andre klasser. - hvis magic strings, benyttes, er de så trukket ud som konstanter, eller enums, for at kunne ændres et sted. - benyttes positions bestemte arrays/strenge. - findes deprecatede metoder, er det på tide at rydde dem op. - 63 - Efficiency: - ved syncronize, tjek for korrekt brug af syncronize - bygges strenge ved + operator, vær især opmærksom i loops. Security: - benyttes System.out til logning, så log ikke kan styres - arrays defineret static final skal altid være private Maintainability: - er koden formateret efter gængs standard - oprydning, udkommenteret kode skal fjernes - variabler, private methods og imports der ikke benyttes, skal fjernes - dybe kontrolstrukturer er svære at læse - er javadoc standard overholdt - Todo staments, repræsentere teknisk gæld Portability: - benyttes implementerings specifikke klasser, frem for API'er (sun.java, etc) Reuseability: - benyttes Hardcoded opførelse/tekster, parameteriseret, i f.eks., property filer. - 64 - som med fordel kan være B. SQALE Quality attribute træ, med sub-attributter Characteristic Subcharacteristic Reusability Modularity Reusability Transportability Reusability Reuseability Compliance Portability Language related portability Portability Time zone related portability Portability Hardware related portability Portability Software Portability Compiler related portability Portability OS related portability Maintainability Understandability Maintainability Readability Security API abuse Security Errors Security Security features Security Input validation and representation Efficiency Memory use Efficiency Network user Efficiency Processor use Changeability Architecture Changeability Logic Changeability Data Reliability Fault tolerance Reliability Architecture - 65 - Characteristic Subcharacteristic Reliability Resource Reliability Synchronization Reliability Statement Reliability Logic Reliability Exception handling Reliability Instruction Reliability Reliability Compliance Reliability Unit test coverage Reliability Data Testability Integration level Testability Testability Compliance Testability Unit Testing - 66 - C. SonarQube reglersæt Udtrukket af SonarQube vha. følgende SQL select c.name, r.name, r.DEFAULT_REMEDIATION_FUNCTION, r.DEFAULT_REMEDIATION_COEFF, r.DEFAULT_REMEDIATION_OFFSET from RULES r, CHARACTERISTICS c where (r.plugin_name = 'squid' or r.plugin_name = 'common-java') and r.status = 'READY' and r.language = 'java' and (select cc.parent_id from CHARACTERISTICS cc where r.DEFAULT_CHARACTERISTIC_ID = cc.ID and cc.PARENT_ID = c.ID) Kvalitets attribut Regel Udbedr. Omkost. funktion Udbedr. Udbedr. omkost. omkost. koeff. offset Changeability Duplicated blocks LINEAR 1h Changeability Class variable fields should CONSTANT not have public accessibility _ISSUE 10min Changeability Avoid cycle between java CONSTANT packages _ISSUE 1d Changeability Magic numbers should not be CONSTANT used _ISSUE 5min Changeability Deprecated code should be CONSTANT removed eventually _ISSUE 10min Changeability Classes should not be CONSTANT coupled to too many other _ISSUE classes (Single Responsibility Principle) 2h Changeability Constants should not defined in interfaces be CONSTANT _ISSUE 10min Changeability The default unnamed CONSTANT package should not be used _ISSUE 10min Changeability IP addresses should not be CONSTANT hardcoded _ISSUE 30min Changeability Declarations should use Java CONSTANT collection interfaces such as _ISSUE "List" rather than specific implementation classes such 10min - 67 - as "LinkedList" Changeability Control flow statements "if", CONSTANT "for", "while", "switch" and _ISSUE "try" should not be nested too deeply 10min Changeability "switch" statements should CONSTANT not have too many "case" _ISSUE clauses 30min Changeability Abstract classes without CONSTANT fields should be converted to _ISSUE interfaces 10min Changeability "Serializable" classes should CONSTANT have a version id _ISSUE 5min Efficiency "deleteOnExit" should not be CONSTANT used _ISSUE 30min Efficiency Loop invariants should not CONSTANT be calculated inside the loop _ISSUE 3min Efficiency Synchronized classes Vector, CONSTANT Hashtable, Stack and _ISSUE StringBuffer should not be used 20min Efficiency Case insensitive string CONSTANT comparisons should be made _ISSUE without intermediate upper or lower casing 5min Efficiency Primitive wrappers should CONSTANT not be instantiated only to _ISSUE perform a "toString" conversion 5min Efficiency Public constants should be CONSTANT declared "static final" rather _ISSUE than merely "final" 2min Efficiency Strings should not be CONSTANT concatenated using '+' in a _ISSUE loop 10min - 68 - Efficiency "NullPointerException" should not be caught Efficiency "Serializable" inner classes CONSTANT of "Serializable" classes _ISSUE should be static 15min Efficiency Parsing should be used to CONSTANT convert "Strings" to _ISSUE primitives 5min Efficiency Primitives should not be CONSTANT boxed just for "String" _ISSUE conversion 5min Efficiency Objects should not be created CONSTANT only to "getClass" _ISSUE 5min Efficiency Boxing and unboxing should CONSTANT not be immediately reversed _ISSUE 5min Efficiency "finalize" should fields to "null" 5min Efficiency "ConcurrentLinkedQueue.siz CONSTANT e()" should not be used _ISSUE not CONSTANT _ISSUE 5min set CONSTANT _ISSUE Maintainability Insufficient comment density LINEAR 15min 3min Maintainability Classes should not be too LINEAR_OF 1min complex FSET 10min Maintainability Sections of code should not CONSTANT be "commented out" _ISSUE 5min Maintainability Files should not be empty CONSTANT _ISSUE 5min be CONSTANT _ISSUE 1min Maintainability Source code should indented consistently Maintainability Labels should not be used CONSTANT _ISSUE 30min Maintainability An open curly brace should CONSTANT be located at the end of a line _ISSUE 1min Maintainability An open curly brace should CONSTANT be located at the beginning of _ISSUE 1min - 69 - a line Maintainability Long suffix "L" should be CONSTANT upper case _ISSUE 2min Maintainability Inheritance tree of classes CONSTANT should not be too deep _ISSUE 4h Maintainability Deprecated elements should CONSTANT have both the annotation and _ISSUE the Javadoc tag 5min Maintainability Modifiers should be declared CONSTANT in the correct order _ISSUE 2min Maintainability Throws declarations should CONSTANT not be redundant _ISSUE 5min Maintainability Close curly brace and the CONSTANT next "else", "catch" and _ISSUE "finally" keywords should be on two different lines 1min Maintainability Close curly brace and the CONSTANT next "else", "catch" and _ISSUE "finally" keywords should be located on the same line 1min Maintainability A close curly brace should be CONSTANT located at the beginning of a _ISSUE line 1min Maintainability Method names comply with a convention should CONSTANT naming _ISSUE 5min Maintainability Class names should comply CONSTANT with a naming convention _ISSUE 5min Maintainability Lines of code should not be CONSTANT too long _ISSUE 1min Maintainability Files should not have too CONSTANT many lines _ISSUE 1h Maintainability Tabulation characters should CONSTANT not be used _ISSUE 2min - 70 - Maintainability Files should contain an CONSTANT empty new line at the end _ISSUE 1min Maintainability Interface names comply with a convention should CONSTANT naming _ISSUE 10min Maintainability Constant names comply with a convention should CONSTANT naming _ISSUE 2min Maintainability Field names should comply CONSTANT with a naming convention _ISSUE 2min Maintainability Local variable and method CONSTANT parameter names should _ISSUE comply with a naming convention 2min Maintainability Abstract class names should CONSTANT comply with a naming _ISSUE convention 10min Maintainability Type parameter names CONSTANT should comply with a naming _ISSUE convention 10min Maintainability Package names comply with a convention 10min should CONSTANT naming _ISSUE Maintainability Control structures should CONSTANT always use curly braces _ISSUE 2min Maintainability Statements should be on CONSTANT separate lines _ISSUE 1min Maintainability Unused labels should be CONSTANT removed _ISSUE 2min Maintainability Collapsible "if" statements CONSTANT should be merged _ISSUE 5min Maintainability Unused private fields should CONSTANT be removed _ISSUE 5min Maintainability Utility classes should not CONSTANT have public constructors _ISSUE 30min - 71 - Maintainability Literal boolean values should CONSTANT not be used in condition _ISSUE expressions 2min Maintainability Return of boolean CONSTANT expressions should not be _ISSUE wrapped into an "if-thenelse" statement 2min Maintainability "TODO" handled be CONSTANT _ISSUE 20min Maintainability Try-catch blocks should not CONSTANT be nested _ISSUE 20min Maintainability Methods should not contain CONSTANT too many return statements _ISSUE 20min Maintainability "if" statement conditions CONSTANT should not unconditionally _ISSUE evaluate to "true" or to "false" 2min Maintainability Enumeration should not be CONSTANT implemented _ISSUE 30min Maintainability "switch case" clauses should CONSTANT not have too many lines _ISSUE 5min Maintainability String.valueOf() should not CONSTANT be appended to a String _ISSUE 5min Maintainability Collection.isEmpty() should CONSTANT be used to test for emptiness _ISSUE 2min Maintainability Public methods should throw CONSTANT at most one checked _ISSUE exception 1h Maintainability "@Override" annotation CONSTANT should be used on any _ISSUE method overriding (since Java 5) or implementing (since Java 6) another one 5min Maintainability Checked Exception should CONSTANT not be thrown _ISSUE 1h tags should - 72 - Maintainability Exceptions should not be CONSTANT thrown in finally blocks _ISSUE 30min Maintainability Empty arrays and collections CONSTANT should be returned instead of _ISSUE null 30min Maintainability Only static class initializers CONSTANT should be used _ISSUE 30min Maintainability Unused method parameters CONSTANT should be removed _ISSUE 5min Maintainability Overriding methods should CONSTANT do more than simply call the _ISSUE same method in the super class 5min Maintainability Lambdas and anonymous CONSTANT classes should not have too _ISSUE many lines 20min Maintainability Exception types should not CONSTANT be tested using "instanceof" _ISSUE in catch blocks 10min Maintainability Array designators "[]" should CONSTANT be located after the type in _ISSUE method signatures 5min Maintainability Array designators "[]" should CONSTANT be on the type, not the _ISSUE variable 5min Maintainability Nested code blocks should CONSTANT not be used _ISSUE 10min Maintainability The members of an interface CONSTANT declaration or class should _ISSUE appear in a pre-defined order 5min Maintainability "switch" statements should CONSTANT not contain non-case labels _ISSUE 10min Maintainability Packages javadoc info.java' 20min should have a CONSTANT file 'package- _ISSUE - 73 - Maintainability "switch" statements should CONSTANT have at least 3 "case" clauses _ISSUE 5min Maintainability The @SuppressWarnings CONSTANT annotation should not be _ISSUE used 10min Maintainability "NOPMD" suppression CONSTANT comments should not be used _ISSUE 10min Maintainability Loggers should be "private CONSTANT static final" and should share _ISSUE a naming convention 5min Maintainability "CHECKSTYLE:OFF" CONSTANT suppression comments _ISSUE should not be used 5min Maintainability Loops should not contain LINEAR more than a single "break" or "continue" statement 20min Maintainability Methods should not have too CONSTANT many lines _ISSUE 20min Maintainability Unused local variables CONSTANT should be removed _ISSUE 5min Maintainability Local Variables should not be CONSTANT declared and then _ISSUE immediately returned or thrown 2min Maintainability Collections.emptyList(), CONSTANT emptyMap() and emptySet() _ISSUE should be used instead of Collections.EMPTY_LIST, EMPTY_MAP and EMPTY_SET 2min Maintainability Package declaration should CONSTANT match source file directory _ISSUE 5min Maintainability Lamdbas containing only one CONSTANT statement should not nest this _ISSUE statement in a block 5min - 74 - Maintainability Anonymous inner classes CONSTANT containing only one method _ISSUE should become lambdas 5min Maintainability @FunctionalInterface CONSTANT annotation should be used to _ISSUE flag Single Abstract Method interfaces 2min Maintainability Parentheses should be CONSTANT removed from a single _ISSUE lambda input parameter when its type is inferred 2min Maintainability Replace method possible with CONSTANT when _ISSUE 2min Maintainability An abstract class should have CONSTANT both abstract and concrete _ISSUE methods 5min Maintainability A field should not duplicate CONSTANT the name of its containing _ISSUE class 10min Maintainability Annotation repetitions should CONSTANT not be wrapped _ISSUE 2min Maintainability The ternary operator should CONSTANT not be used _ISSUE 5min Maintainability Redundant casts should not CONSTANT be used _ISSUE 5min Maintainability Fields in non-serializable CONSTANT classes should not be _ISSUE "transient" 2min Maintainability Classes should not be empty CONSTANT _ISSUE 5min Maintainability Classes extending CONSTANT java.lang.Thread should _ISSUE override the "run" method 5min Maintainability "final" classes should not CONSTANT 5min lambdas references - 75 - have "protected" members _ISSUE Maintainability Classes named like CONSTANT "Exception" should extend _ISSUE "Exception" or a subclass 5min Maintainability Class names should shadow interfaces superclasses not CONSTANT or _ISSUE 5min Maintainability Ints and longs should not be CONSTANT shifted by more than their _ISSUE number of bits-1 5min Maintainability Unused type parameters CONSTANT should be removed _ISSUE 5min Maintainability Redundant modifiers should CONSTANT not be used _ISSUE 2min Maintainability Inner class calls to super CONSTANT class methods should be _ISSUE unambiguous 5min Maintainability Classes with only "static" CONSTANT methods should not be _ISSUE instantiated 2min Maintainability "Lock" objects should not be CONSTANT "synchronized" _ISSUE 15min Maintainability Comments should not be CONSTANT located at the end of lines of _ISSUE code 1min Maintainability Public types, methods and CONSTANT fields (API) should be _ISSUE documented with Javadoc 30min Maintainability Unused private should be removed 5min method CONSTANT _ISSUE Maintainability Unused protected methods CONSTANT should be removed _ISSUE 10min Maintainability Useless imports should be CONSTANT removed _ISSUE 10min - 76 - Maintainability Useless parentheses around CONSTANT expressions should be _ISSUE removed to prevent any misunderstanding 1min Portability Avoid use of deprecated CONSTANT methods _ISSUE 15min Portability Future keywords should not CONSTANT be used as names _ISSUE 5min Portability Classes from "sun.*" CONSTANT packages should not be used _ISSUE 1h Reliability Failed unit tests Reliability Insufficient branch coverage LINEAR by unit tests 10min Reliability Insufficient line coverage by LINEAR unit tests 3min Reliability Assignments should not be CONSTANT made from within sub- _ISSUE expressions 5min Reliability Empty statements should be CONSTANT removed _ISSUE 2min Reliability Local variables should not CONSTANT shadow class fields _ISSUE 5min Reliability The Object.finalize() method CONSTANT should not be called _ISSUE 20min Reliability super.finalize() should called at the end Object.finalize() implementations 5min Reliability The Object.finalize() method CONSTANT should not be overriden _ISSUE 20min Reliability Java parser failure 30min Reliability Nested blocks of code should CONSTANT not be left empty _ISSUE LINEAR be CONSTANT of _ISSUE CONSTANT _ISSUE - 77 - 1h 5min Reliability Generic exceptions should CONSTANT never be thrown _ISSUE 20min Reliability Strings literals should be CONSTANT placed on the left side when _ISSUE checking for equality 10min Reliability "FIXME" tags should be CONSTANT handled _ISSUE 20min Reliability "return" statements should CONSTANT not occur in "finally" blocks _ISSUE 30min Reliability Throwable.printStackTrace(.. CONSTANT .) should never be called _ISSUE 10min Reliability Exception classes should be CONSTANT immutable _ISSUE 15min Reliability Exception handlers should CONSTANT preserve the original _ISSUE exception 10min Reliability "Object.finalize()" should CONSTANT remain protected (versus _ISSUE public) when overriding 10min Reliability Object.finalize() should not CONSTANT be overloaded (by adding _ISSUE method parameters) 10min Reliability Throwable and Error should CONSTANT not be caught _ISSUE 20min Reliability Classes that override "clone" CONSTANT should be "Cloneable" and _ISSUE call "super.clone()" 20min Reliability Methods should not be empty CONSTANT _ISSUE 5min Reliability String literals should not be LINEAR_OF 2min duplicated FSET 2min Reliability "java.lang.Error" should not CONSTANT be extended _ISSUE 10min Reliability Methods should 10min named "equals" CONSTANT override _ISSUE - 78 - Object.equals(Object) Reliability "equals(Object obj)" and CONSTANT "hashCode()" should be _ISSUE overridden in pairs 15min Reliability "equals(Object obj)" should CONSTANT be overridden along with the _ISSUE "compareTo(T obj)" method 15min Reliability Execution of the Garbage CONSTANT Collector should be triggered _ISSUE only by the JVM 30min Reliability Thread.run() and CONSTANT Runnable.run() should not be _ISSUE called directly 20min Reliability Methods should not be CONSTANT named "hashcode" or "equal" _ISSUE 10min Reliability Non-constructor methods CONSTANT should not have the same _ISSUE name as the enclosing class 5min Reliability Method parameters, caught CONSTANT exceptions and foreach _ISSUE variables should not be reassigned 5min Reliability Floating point numbers CONSTANT should not be tested for _ISSUE equality 5min Reliability Switch cases should end with CONSTANT an unconditional "break" _ISSUE statement 10min Reliability The Array.equals(Object obj) CONSTANT method should not be used _ISSUE 5min Reliability Octal values should not be CONSTANT used _ISSUE 5min Reliability "StringBuilder" and CONSTANT "StringBuffer" should not be _ISSUE instantiated with a character 5min - 79 - Reliability "object == null" should be CONSTANT used instead of _ISSUE "object.equals(null)" 5min Reliability Generic wildcard types CONSTANT should not be used in return _ISSUE parameters 20min Reliability Variables should not be self- CONSTANT assigned _ISSUE 3min Reliability "NullPointerException" CONSTANT should not be explicitly _ISSUE thrown 10min Reliability Short-circuit logic should be CONSTANT used to prevent null pointer _ISSUE dereferences in conditionals 2min Reliability Objects should be compared CONSTANT with "equals()" _ISSUE 2min Reliability Constructors should only call CONSTANT non-overridable methods _ISSUE 10min Reliability Fields and methods should CONSTANT not have conflicting names _ISSUE 10min Reliability Deprecated classes and CONSTANT interfaces should not be _ISSUE extended/implemented 30min Reliability Identical expressions should CONSTANT not be used on both sides of a _ISSUE binary operator 2min Reliability "Object.wait(...)" should CONSTANT never be called on objects _ISSUE that implement "java.util.concurrent.locks.C ondition" 20min Reliability Objects should not be created CONSTANT to be dropped immediately _ISSUE without being used 5min Reliability "Iterator.hasNext()" 20min should CONSTANT - 80 - not call "Iterator.next()" _ISSUE Reliability "instanceof" operators that CONSTANT always return "true" or _ISSUE "false" should be removed 5min Reliability Synchronisation should not CONSTANT be based on Strings or boxed _ISSUE primitives 15min Reliability Conditions in related "if/else CONSTANT if" statements should not _ISSUE have the same condition 10min Reliability Two branches in the same CONSTANT conditional structure should _ISSUE not have exactly the same implementation 10min Reliability Classes should not compared by name 5min Reliability Classes and methods that rely CONSTANT on the default system _ISSUE encoding should not be used 15min Reliability Fields in a "Serializable" CONSTANT class should either be _ISSUE transient or serializable 30min Reliability "for" loop incrementers CONSTANT should modify the variable _ISSUE being tested in the loop's stop condition 20min Reliability Member variable visibility CONSTANT should be specified _ISSUE 5min Reliability The non-serializable super CONSTANT class of a "Serializable" class _ISSUE must have a no-argument constructor 30min Reliability Custom serialization method CONSTANT signatures should meet _ISSUE requirements 5min - 81 - be CONSTANT _ISSUE Reliability Comparators "Serializable" should Reliability "Serializable" inner classes CONSTANT of non-serializable classes _ISSUE should be "static" 15min Reliability "main" should not "throw" CONSTANT anything _ISSUE 15min Reliability Reflection should not be used CONSTANT to check non-runtime _ISSUE annotations 15min Reliability Invalid "Date" values should CONSTANT not be used _ISSUE 5min Reliability "BigDecimal(double)" should not be used 5min Reliability Collections should not be CONSTANT passed as arguments to their _ISSUE own methods 15min Reliability "hashCode" and "toString" CONSTANT should not be called on array _ISSUE instances 5min Reliability Non-serializable classes CONSTANT should not be written _ISSUE 15min Reliability "ScheduledThreadPoolExecu CONSTANT tor" should not have 0 core _ISSUE threads 20min Reliability Values should not uselessly incremented 5min Reliability "Double.longBitsToDouble" CONSTANT should not be used for "int" _ISSUE 15min Reliability "runFinalizersOnExit" should not be called 20min Reliability Dissimilar primitive CONSTANT wrappers should not be used _ISSUE with the ternary operator without explicit casting - 82 - be CONSTANT _ISSUE CONSTANT _ISSUE be CONSTANT _ISSUE CONSTANT _ISSUE 5min 5min Reliability "Cloneables" implement "clone" should CONSTANT _ISSUE 30min Reliability Subclasses that add fields CONSTANT should override "equals" _ISSUE 30min Reliability "equals" methods should be CONSTANT symmetric and work for _ISSUE subclasses 5min Reliability Math should not performed on floats be CONSTANT _ISSUE 15min Reliability "compareTo" should return "Integer.MIN_VALUE" not CONSTANT _ISSUE 5min Reliability Inappropriate "Collection" CONSTANT calls should not be made _ISSUE 15min Reliability Short-circuit logic should be CONSTANT used in boolean contexts _ISSUE 5min Reliability Math operands should be cast CONSTANT before assignment _ISSUE 5min Reliability Modulus results should not CONSTANT be checked for direct equality _ISSUE 5min Reliability "compareTo" results should CONSTANT not be checked for specific _ISSUE values 5min Reliability Return values should not be CONSTANT ignored when function calls _ISSUE don't have any side effects 10min Reliability ".equals()" should not be CONSTANT used to test the values of _ISSUE "Atomic" classes 5min Reliability "toString()" and "clone()" CONSTANT methods should not return _ISSUE null 5min Reliability Servlets should never have CONSTANT mutable instance fields _ISSUE 30min - 83 - Reliability Non-public methods should CONSTANT not be "@Transactional" _ISSUE 20min Reliability "ResultSet.isLast()" not be used should CONSTANT _ISSUE 10min Reliability IllegalMonitorStateException CONSTANT should never be caught _ISSUE 20min Reliability Methods "wait(...)", CONSTANT "notify()" and "notifyAll()" _ISSUE should never be called on Thread instances 30min Reliability A "for" loop update clause CONSTANT should move the counter in _ISSUE the right direction 5min Reliability Loop conditions should be CONSTANT true at least once _ISSUE 10min Reliability "Iterator.next()" methods CONSTANT should throw _ISSUE "NoSuchElementException" 5min Reliability "wait(...)", "notify()" and CONSTANT "notifyAll()" methods should _ISSUE only be called when a lock is obviously held on an object 20min Reliability "Object.wait(...)" and CONSTANT "Condition.await(...)" should _ISSUE always be called inside a "while" loop 20min Reliability Printf-style format strings CONSTANT should not lead to _ISSUE unexpected behavior at runtime 10min Reliability "wait(...)" should be used CONSTANT instead of "Thread.sleep(...)" _ISSUE when a lock is held 5min Reliability Interfaces should not have CONSTANT "public static" mutable fields _ISSUE 30min - 84 - Reliability Silly bit operations should CONSTANT not be performed _ISSUE 5min Reliability "Threads" should not be used CONSTANT where "Runnables" are _ISSUE expected 15min Reliability Non-serializable objects CONSTANT should not be stored in _ISSUE "HttpSessions" 20min Reliability Lazy initialization of "static" CONSTANT fields should be _ISSUE "synchronized" 30min Reliability Blocks synchronized on CONSTANT fields should not contain _ISSUE assignments of new objects to those fields 15min Reliability "notifyAll" should be used 2min Reliability Null should not be returned CONSTANT from a "Boolean" method _ISSUE 20min Reliability Increment (++) and CONSTANT decrement (--) operators _ISSUE should not be mixed with other operators in an expression 5min Reliability Relational operators should CONSTANT be used in "for" loop _ISSUE termination conditions 2min Reliability Strings should be compared CONSTANT using "equals()" _ISSUE 5min Reliability "switch" statements should CONSTANT end with a "default" clause _ISSUE 5min Reusability Public methods should not CONSTANT contain selector arguments _ISSUE 15min - 85 - CONSTANT _ISSUE Security "NOSONAR" marker should CONSTANT not be used to switch-off _ISSUE issues 1min Security Standard ouputs should not CONSTANT be used directly to log _ISSUE anything 10min Security Exit methods should not be CONSTANT called _ISSUE 30min Security "public static" fields should CONSTANT always be constant _ISSUE 20min Security Copyright and license CONSTANT headers should be defined _ISSUE 5min Security "static final" arrays should be CONSTANT "private" _ISSUE 15min Security Credentials should not be CONSTANT hard-coded _ISSUE 30min Security SHA-1 and Message-Digest CONSTANT hash algorithms should not _ISSUE be used 30min Security Values passed to commands should sanitized OS CONSTANT be _ISSUE 30min Security Values passed to commands should sanitized SQL CONSTANT be _ISSUE 20min Security Values passed to LDAP CONSTANT queries should be sanitized _ISSUE 30min Security HTTP referers should not be CONSTANT relied on _ISSUE 20min Security Cookies should be "secure" 5min Security Pseudorandom number CONSTANT generators (PRNGs) should _ISSUE not be used in secure contexts - 86 - CONSTANT _ISSUE 10min Security "HttpServletRequest.getRequ CONSTANT estedSessionId()" should not _ISSUE be used 10min Security Only standard cryptographic CONSTANT algorithms should be used _ISSUE 1d Security "javax.crypto.NullCipher" CONSTANT should not be used for _ISSUE anything other than testing 15min Security Cryptographic RSA CONSTANT algorithms should always _ISSUE incorporate OAEP (Optimal Asymmetric Encryption Padding) 20min Security DES (Data Encryption CONSTANT Standard) and DESede _ISSUE (3DES) should not be used 20min Testability Skipped unit tests Testability Methods should not be too LINEAR_OF 1min complex FSET 10min Testability Methods should not have too CONSTANT many parameters _ISSUE 20min Testability Expressions should not be LINEAR_OF 1min too complex FSET 5min LINEAR - 87 - 10min D. Teknisk gæld i KROModel Kvalitets Attribut Problem Antal Tid i min. Reliability Insufficient branch coverage by unit tests 60 7260 Maintainability Public methods should throw at most one 37 checked exception 2220 Changeability Duplicated blocks 13 780 Reliability Fields in a "Serializable" class should either be 16 transient or serializable 480 Maintainability Empty arrays and collections should be returned 9 instead of null 270 Testability Methods should not be too complex 23 253 Changeability Declarations should use Java collection 18 interfaces such as "List" rather than specific implementation classes such as "LinkedList" 180 Maintainability "TODO" tags should be handled Maintainability Utility classes constructors Changeability should not have 7 140 public 4 120 Class variable fields should not have public 7 accessibility 70 Maintainability "@Override" annotation should be used on any 11 method overriding (since Java 5) or implementing (since Java 6) another one 55 Maintainability Useless imports should be removed 5 50 Maintainability Unused private fields should be removed 10 50 Reliability Strings literals should be placed on the left side 5 when checking for equality 50 Changeability Deprecated code should be removed eventually 4 40 Efficiency Synchronized classes Vector, Hashtable, Stack 2 and StringBuffer should not be used 40 Maintainability Sections of code should not be "commented 6 30 - 88 - out" Reliability String literals should not be duplicated 6 24 Maintainability Local Variables should not be declared and then 10 immediately returned or thrown 20 Maintainability Collection.isEmpty() should be used to test for 10 emptiness 20 Security "public static" fields should always be constant 1 20 Changeability Control flow statements "if", "for", "while", 2 "switch" and "try" should not be nested too deeply 20 Testability Methods should not have too many parameters 1 20 Maintainability The members of an interface declaration or 3 class should appear in a pre-defined order 15 Maintainability Deprecated elements should have both the 3 annotation and the Javadoc tag 15 Security "static final" arrays should be "private" 1 15 Testability Expressions should not be too complex 2 12 2 10 Maintainability A field should not duplicate the name of its 1 containing class 10 Maintainability Constant names should comply with a naming 4 convention 8 Maintainability Unused local variables should be removed 1 5 Reliability Local variables should not shadow class fields 1 5 Reliability "BigDecimal(double)" should not be used 1 5 Maintainability Useless parentheses around expressions should 5 be removed to prevent any misunderstanding 5 Maintainability Unused private method should be removed 5 Maintainability Collapsible "if" statements should be merged - 89 - 1 E. Teknisk gæld i PUMJsfPortalUtil Kvalitets Attribut Problem Antal Tid i min. Reliability Insufficient branch coverage by unit tests 26 3640 Changeability Duplicated blocks 11 1080 Reliability Generic exceptions should never be thrown 37 740 Maintainability "TODO" tags should be handled 12 240 Reliability 9 180 31 155 Maintainability "@Override" annotation should be used on 28 any method overriding (since Java 5) or implementing (since Java 6) another one 140 Changeability Deprecated eventually 120 Testability Methods should not be too complex 7 77 Reliability String literals should not be duplicated 19 76 Reliability Exception handlers original exception the 7 70 Efficiency Synchronized classes Vector, Hashtable, Stack 3 and StringBuffer should not be used 60 Reliability Methods should not be empty 6 30 Changeability Constants should not be defined in interfaces 3 30 Maintainability Deprecated elements should have both the 6 annotation and the Javadoc tag 30 Changeability 30 Throwable and Error should not be caught Maintainability Throws declarations should not be redundant code should should be removed 12 preserve Control flow statements "if", "for", "while", 3 "switch" and "try" should not be nested too deeply Maintainability Unused method removed parameters be 5 25 Maintainability Sections of code should not be "commented 5 out" 25 Maintainability The members of an interface declaration or 5 class should appear in a pre-defined order 25 Maintainability Useless imports should be removed 20 - 90 - should 2 Changeability Declarations should use Java collection 2 interfaces such as "List" rather than specific implementation classes such as "LinkedList" 20 Maintainability Exception types should not be tested using 1 "instanceof" in catch blocks 10 Reliability 10 Strings literals should be placed on the left 1 side when checking for equality Maintainability Collection.isEmpty() should be used to test for 4 emptiness 8 Maintainability Redundant casts should not be used 1 5 Method parameters, caught exceptions and 1 foreach variables should not be reassigned 5 Reliability Maintainability Collapsible "if" statements should be merged 1 5 Maintainability String.valueOf() should not be appended to a 1 String 5 Maintainability Array designators "[]" should be on the type, 1 not the variable 5 Maintainability Unused private method should be removed 1 5 Maintainability Modifiers should be declared in the correct 2 order 4 Maintainability Local Variables should not be declared and 2 then immediately returned or thrown 4 Maintainability Return of boolean expressions should not be 2 wrapped into an "if-then-else" statement 4 Maintainability Useless parentheses around expressions 3 should be removed to prevent any misunderstanding 3 Maintainability Constant names should comply with a naming 1 convention 2 - 91 - F. Teknisk gæld i SAGOpgaveListJSFPortlet Kvalitets Attribut Problem Antal Tid i min. Reliability Insufficient branch coverage by unit tests 11 1070 Changeability Duplicated blocks 2 120 Maintainability "TODO" tags should be handled 4 80 Maintainability Unused method parameters should be removed 8 40 Maintainability Sections of code should not be "commented out" 7 35 Maintainability Utility classes should not have public constructors 1 30 Maintainability Modifiers should be declared in the correct order 14 28 Maintainability "@Override" used on any (since Java (since Java 5 25 2 20 Maintainability Throws declarations should not be redundant 2 10 Reliability Methods should not be empty 1 5 Reliability Local variables should not shadow class fields 1 5 Reliability String literals should not be duplicated 1 4 1 1 Reliability annotation should be method overriding 5) or implementing 6) another one Strings literals should be placed on the left side when checking for equality Maintainability Useless parentheses around expressions should be removed to prevent any misunderstanding - 92 - G. SQALE data for kontrol projekter SAGViderestillingDetailJsfPortlet Linier kilde kode, 934 Udviklings omkostninger i timer, 467 timer Teknisk gæld i procent, 4,7 % Figur 15: Teknisk gæld for SagViderestillingDetailJsfPortlet SAGViderestillingSogJsfPortlet Linier kilde kode, 629 Udviklings omkostninger i timer, 315 timer Teknisk gæld i procent, 3,4 % Figur 16: Teknisk gæld for SagViderestillingSogJsfPortlet YEBOverforselPortlet Linier kilde kode, 5840 Udviklings omkostninger i timer, 2920 timer Teknisk gæld i procent, 4,5 % Figur 17: Teknisk gæld for YEBOverforselPortlet - 93 - - 94 - H. Sonar-project.properties eksempel sonar.projectKey=PUMJsfPortletUtilImpl sonar.projectName=PUMJsfPortletUtilImpl sonar.projectVersion=1.0 sonar.cpd.cross_project=true sonar.sources=./source sonar.tests=./test sonar.java.binaries=../PUMJsfPortletUtilImpl/target/classes,../PU MJsfPortletUtilImpl/target/test/classes sonar.java.libraries=C:/usr/local/bankdata/lib/*.jar,C:/Udvikler/p ortletressources/jsfjars/*.jar,C:/jarview/YBU/Build/portletplatfor m_71/lib/*.jar sonar.junit.reportsPath=./target/junit/xml sonar.sourceEncoding=UTF-8 sonar.issuesReport.html.location = ./report sonar.modules=PUMJsfPortletUtilImpl,PUMJsfPortletUtilAPI,PUMJs fPortletUtilFwkAPI PUMJsfPortletUtilAPI.sonar.projectBaseDir=../PUMJsfPortletUtilAP I PUMJsfPortletUtilFwkAPI.sonar.projectBaseDir=../PUMJsfPortletUt ilFwkAPI PUMJsfPortletUtilImpl.sonar.projectBaseDir=../PUMJsfPortletUtilI mpl - 95 - I. jacoco_build.xml eksempel <project xmlns:jacoco="antlib:org.jacoco.ant" name="Example Ant Build with JaCoCo" default="rebuild"> <property name="src.dir" location="./source" /> <property name="apisrc.dir" location="../PUMJsfPortletUtilAPI/src" /> <property name="fwkapisrc.dir" location="../PUMJsfPortletUtilFwkAPI/source" /> <property name="test.dir" location="./test" /> <property name="result.dir" location="./target" /> <property name="result.junit.xml.dir" location="${result.dir}/junit/xml" /> <property name="result.classes.dir" location="${result.dir}/classes" /> <property name="result.test.classes.dir" location="$ {result.dir}/test/classes" /> <property name="result.report.dir" location="${result.dir}/site/jacoco" /> <property name="result.exec.file" location="${result.dir}/jacoco.exec" /> <path id="master-classpath"> <fileset dir="C:/Users/bducch/.gradle/caches/modules-2/files-2.1"> <include name="**/*.jar" /> </fileset> <fileset dir="C:\Udvikler\rational\rad901\SDPShared\plugins\org.junit_4.10.0.v4_10_0 _v20120426-0900"> <include name="*.jar" /> </fileset> <fileset dir="C:\jarview\YBU\Eksterne"> <include name="mockito\mockito-all-1.9.5.jar" /> <include name="Apache\log4j-1.2.16.jar" /> </fileset> <fileset dir="C:\usr\WebSphere\AppServer"> <include name="lib\j2ee.jar" /> <include name="plugins\com.ibm.ws.runtime.jar" /> </fileset> <pathelement path="${build.dir}" /> </path> <!-- Step 1: Import JaCoCo Ant tasks --> <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml"> <classpath path="../../../lib/jacocoant.jar" /> </taskdef> <target name="clean"> <delete dir="${result.dir}" /> </target> <target name="compile"> <mkdir dir="${result.classes.dir}" /> <javac srcdir="${apisrc.dir}" destdir="${result.classes.dir}" debug="true" includeantruntime="false"> <classpath refid="master-classpath" /> </javac> - 96 - <javac srcdir="${fwkapisrc.dir}" destdir="${result.classes.dir}" debug="true" includeantruntime="false"> <classpath refid="master-classpath" /> </javac> <javac srcdir="${src.dir}" destdir="${result.classes.dir}" debug="true" includeantruntime="false"> <classpath refid="master-classpath" /> </javac> </target> <target name="compile-test"> <mkdir dir="${result.test.classes.dir}" /> <javac srcdir="${test.dir}" destdir="${result.test.classes.dir}" debug="true" includeantruntime="false"> <classpath refid="master-classpath" /> <classpath location="${result.classes.dir}" /> </javac> </target> <target name="test" depends="compile,compile-test"> <mkdir dir="${result.junit.xml.dir}" /> <!-- Step 2: Wrap test execution with the JaCoCo coverage task --> <jacoco:coverage destfile="${result.exec.file}" xmlns:jacoco="antlib:org.jacoco.ant"> <junit fork="yes" forkmode="once"> <classpath location="${result.classes.dir}" /> <classpath location="${result.test.classes.dir}" /> <classpath refid="master-classpath" /> <formatter type="xml" /> <batchtest fork="yes" todir="${result.junit.xml.dir}"> <fileset dir="${test.dir}"> <include name="**/*Test.java" /> </fileset> </batchtest> </junit> </jacoco:coverage> </target> <target name="rebuild" depends="clean,compile,test" /> </project> - 97 - J. Referat fra fokusgruppe diskussion om teknisk gæld og SQALE Følgende er de væsentlige statements fra fokus gruppe diskussionen. Opsat i kronologisk rækkefølge. Anders: Er et godt værktøj til at finde de mere kedelige ting, eksempelvis, nogle klasser var serializable medens andre i arve hierarkiet ikke var. Giver tid til at det manuelle review kan fokusere på de mere design orienterede ting. Alle: En diskussion om hvorvidt man skulle kunne markere kode som ”ok, jeg ved godt her er problemer, lad være at fortælle mig det igen, det er et bevidst valg” (eks. NOPMD) Argumentet mod var at det ville så ikke vise det reele billede af din kodekvalitet, men kun kvaliteten af den kode du lige havde udvalgt. Argumentet for var et ønske om at ting der var taget stilling til ikke skulle vises som gæld. Der blev dog opnået en vis enighed om at det var en fordel at vise status som den var, og målet ikke var at have 0 gæld, men at være bevidst om hvor den var. Det måtte blot ikke være en kvalitets gate, der gør at det ikke kan bygges. Mogens: Der skal adskillelse mellem rapportering og kvalitets gate. Første spørgsmål, Er teknisk gæld et begreb vi kan benytte ..., blev fremhævet for igen at trække diskussion ind på sporet. Kasper: et godt værktøj hvis vi kan stole på den teknisk gæld set i store træsko længder. Godt for udvikleren til at rapportere til ledelsen om at vi er nød til at afsætte tid til ind imellem at nedbringe den tekniske gæld. Så når en opgave kommer ind der lige skal løses inden næste mandag, og projektet i forvejen har akkumuleret 100 dage i teknisk gæld, vil det være et godt værktøj i argumentation for at det er mere fornuftigt at få nedbragt den tekniske gæld der allerede er oparbejdet frem for at lave mere ved en ny hurtig løsning. - 98 - Mogens: Svært ved at forholde sig til gælden i timer, men kan godt forholde sig til mængden i % Anders: Enig i at det er et stærkt værktøj til at afdække gælden. Kalibreringen kan komme på plads hen af vejen, men hvis man ser bort fra at der står timer, og blot kalder det enheder, giver det allerede et fantastisk overblik. Stærkt at have tallet, selv om de timer værktøjet angiver måske ikke lige stemmer. Kan være lidt et problem at de design relaterede ting ikke opdages og tælles med. Det er tit her de store hurdler ligger. Kim: Rigtig stærk til at fange de små problemer i det daglige, som man tænker ”det skal jeg lige huske til næste iteration”. Selvom det ikke fanger de design relaterede problemer, fanger det stadig væk en stor del af den gæld projekterne vil akkumulere. Morten: Vil være stærkt at have til at give et overblik over hvor meget gæld vi går og sparer op. Morten: Den gæld værktøjet her viser er en ud af tre ting der skal med når der rapporteres. Manglende funktionalitet, design gæld og teknisk gæld. Funktionalitet skulle dog gerne være afdækket af funktions tests. Kasper: Er meget relevant for udviklere, og alle parametrene (kvalitets attributterne) er meget relevante for den erfarne udvikler. Men afdelings ledere, team ledere og hvem der ellers rapporteres til, kan ikke forholde sig det (time tallet for den teknisk gæld), det må være den samlede teknisk gæld der skal rapporteres. Anders: (supplere) Det er den tekniske gæld fra værktøjet, plus noget mere (design relateret) Mogens: En anden stor gevinst er trends, som rapporteres af værktøjet – bliver det værre eller bedre. Det er værktøjet stærk til. Leder til en diskussion af hvor ofte der skal rapporteres. - 99 - Anders: Ikke redskabet til projektledere, men mere til system ejere som har ansvaret for koden/applikationen. Der vil jeg elske sådan et værktøj. Kasper: Men teknisk gæld er stadig et mål der er interessant at måle de enkelte ledere på. Anders: Men hvis ledere efterspørger, hvad der er af teknisk gæld, så vil jeg bruge værktøjet + min viden om projektet til at rapportere det. Men det fundamentale kan en maskine lige så godt tage sig af at måle. Flemming: Vil være en stor hjælp til forvaltning, systemerne har det med at sande til. Analogi til performance – hvor man først reagere 'når det er slemt nok'. Værktøjet her kan også hjælpe med at overvåge systemet at det ikke degenerere for meget, og at der bliver hanket op in i mellem. Projektet kan selvfølgelig bruge det i udviklingen for at styre hvor meget teknisk gæld man ønsker, men for forvaltningen er det interessant at se hvad er niveauet for det kode man overtager forvaltningen af. Man kan bede om at systemet har en vis intern kvalitet inden man overtager systemet fra projektet. De der sidder i driften har så også en ide om hvor de skal sætte ind (for at nedbringe gælden) – det er helt umuligt i dag. Kim: også interessant at analysere projekterne på tværs af et område, og holde øje med trends for at se om der er steder der skal sættes ind med uddannelse etc. Kasper: Kan også bruges som hjælp til TAK, som har ansvaret for at lave stikprøve kontrol, for at se hvordan kvaliteten er. Værktøjet kan være en hjælp til at finde de rigtige projekter at reviewe, og evt. se hvilke områder/udviklere det er nødvendig at være lidt tættere på for at vi udvikler os i den rigtige og samme retning. Morten: Godt værktøj for løsnings arkitekten over for projektlederen. Der er pres fra alle sider, og projektlederne interessere sig typisk kun for hvad der er på skærmen, ser det ud til at virke og er den funktionalitet der er aftalt der. Har ikke interesse for hvad der er nede bagved. - 100 - Kim: Især et stort problem hvor der er mange konsulenter inde – de bliver målt lidt mere på at levere funktionalitet, og har derfor kun fokus på det. Anders: Også rart for andre udviklere at have værktøjet, til at minde en om, når dagligdagen kræver en hurtig løsning, at man ved lejlighed skal have ryddet op igen. Kim: Enig, værktøjet kan holde styr på det man selv i dag går og lige skal huske at sætte tid af i næste itteration til at få rettet til. Anders: Og jeg slipper for selv at skrive sedlen/post it noten på at jeg skal huske det. Morten: Selv om der ikke kan måles de mere design relaterede problemer, vil det formentlig i et vist omfang følges med den tekniske gæld vi kan måle. Så værktøjet vil give en indikator for hvor der ligger andre problemer gemt. En kort snak om hvorvidt man selv kan lægge ind at her er der et udestående. Værktøjet måler i dag på TODO's – men det er jo ret bredt. Og svært at sætte samme værdi for TODO's. Lidt snak om mulighed for at angive i TODO hvor stor gæld man forvente. Konklusion på at gruppen mener grundlæggende at det er en god ide systematisk at afdække teknisk gæld i projekterne. Kim: Men der er behov for at forankre begrebet i organisationen – hvad mener vi med teknisk gæld. Anders: Syntes vi bruger begrebet allerede nu. Men benyttes lidt bredere, hvor det tal der rapporteres af værktøjet kun er en del af det (som stateflere gange) Mogens: Gruppere den tekniske gæld i noget design relateret, noget programmering (som værktøjet her fanger), og noget test. - 101 - Anders: og noget performance. Morten: Nødvendigt med samme værktøj hele vejen igennem, så vi ikke benytter PMD i eclipse, afrapportere via SonarQube på CI serveren etc. (Hvilket SonarQube også har mulighed for via eclipse plugins) Kasper: Ønskeligt om værktøjet kunne kobles sammen med log rapporteringen over hvor mange fejl er der så i koden. Konklusion på erstat/supplere manuelle: Det letter de manuelle og supplerer dem så man kan benytte de manuelle review til de mere interessante ting, og der nå ned i den design relaterede gæld. Benyttes som tool Kim: Giver mulighed for at skifte fokus i de manuelle review. Anders: Kan også være rart i de manuelle review at der er en maskine der siger hvad der er rigtig og forkert så man slipper for den diskussion. - 102 - K. Duplikeret kode i OpgavelisteState BladringType bladring = new BladringType(); bladring.setAction(1); bladring.setFirstKey(""); bladring.setHasNext(false); bladring.setHasPrev(false); bladring.setLastKey(""); this.tabPagination.put(TODAY, bladring); this.tabPage.put(TODAY, 1); bladring = new BladringType(); bladring.setAction(1); bladring.setFirstKey(""); bladring.setHasNext(false); bladring.setHasPrev(false); bladring.setLastKey(""); this.tabPagination.put(FUTURE, bladring); this.tabPage.put(FUTURE, 1); bladring = new BladringType(); bladring.setAction(1); bladring.setFirstKey(""); bladring.setHasNext(false); bladring.setHasPrev(false); bladring.setLastKey(""); this.tabPagination.put(ALL, bladring); this.tabPage.put(ALL, 1); - 103 -
© Copyright 2024