Vurdering af SQALE som kvalitets evalueringsmodel

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 -