Metryka oprogramowania – miara pewnej własności oprogramowania lub jego specyfikacji. Termin ten nie ma precyzyjnej definicji i może oznaczać właściwie dowolną wartość liczbową charakteryzującą oprogramowanie.
Standard IEEE 1061-1998 określa metrykę jako funkcję odwzorowującą jednostkę oprogramowania w wartość liczbową. Ta wyliczona wartość jest interpretowalna jako stopień spełnienia pewnej własności jakości jednostki oprogramowania. Metryki używają różnych definicji jednostki oprogramowania, opartej zazwyczaj na kodzie źródłowym, rozdzielonym na jeden lub więcej plików. Istnieją też metryki, które nie bazują na kodzie, lecz pozwalają na analizę specyfikacji oprogramowania (np. punkty funkcyjne) lub przebiegu wykonania programu.
Zastosowanie Celem użycia metryk oprogramowania jest otrzymanie dokładnych wartości, które dotyczą wytwarzanych aplikacji. Lord Kelvin, fizyk i matematyk, stwierdził: Jeśli to o czym mówisz potrafisz zmierzyć i wyrazić w liczbach – wiesz coś o tym. Inaczej twa wiedza jest mizernaCyt. za: , inżynier oprogramowania Tom DeMarco uważa zaś, że nie można kontrolować tego, czego się nie da zmierzyć. Metryki pozwalają na obiektywne spojrzenie na oprogramowanie i porównanie ze sobą poszczególnych jego elementów lub różnych produktów. Mierzenie jakości aplikacji oraz wydajności pracy bez danych liczbowych staje się bardzo trudne, a utrzymanie obiektywności jest niemal niemożliwe.
Obliczanie metryk jest istotnym ułatwieniem we wszystkich fazach procesu wytwarzania oprogramowania. W fazie projektowania metodologie takie jak COCOMO za pomocą rozmaitych metryk pozwalają na oszacowanie nakładu pracy potrzebnego do realizacji pomysłu. Na tym etapie metryki są przydatne przede wszystkim dla klientów oraz projektantów. W fazie produkcji dużą rolę odgrywają metryki statyczne, pomagające w utrzymywaniu jakości kodu źródłowego. Korzystają na tym programiści, którzy dzięki metrykom mogą łatwo odnajdywać te miejsca w kodzie, które są potencjalnym źródłem nadmiernej złożoności, a co za tym idzie, powstających błędów. W fazie testów wykorzystywane są zarówno metryki statyczne, jak i dynamiczne, pozwalające na badanie przebiegu wykonania programu. Na tym etapie gromadzone są też dane liczbowe dotyczące wydajności czy niezawodności aplikacji. Wyniki testów są pożytecznym źródłem informacji dla wszystkich osób zaangażowanych w projekt, w tym kierowników, programistów i klientów.
Jakość metryki Istotną kwestią jest ocena samej metryki („meta-metryka”). Aby metryka była użyteczna, powinna być: prosta i możliwa do obliczenia przez komputer przekonująca konsekwentna i obiektywna spójna pod względem użytych jednostek niezależna od języka programowania dająca przydatne informacje.
Linda Westfall wymienia 12 kroków prowadzących do opracowania użytecznych metryk: identyfikacja klientów, ustalenie celów, zadanie pytań, wybór metryk, standaryzacja definicji, wybór funkcji mierzącej, ustalenie metody pomiaru, definicja kryteriów wyboru, definicja mechanizmów raportowania, ustalenie dodatkowych własności, zebranie danych, aspekt ludzki. Charakterystycznym elementem jest paradygmat Cel – Pytanie – Metryka (, – – ), wypromowane przez Victora Basiliego z University of Maryland oraz Laboratorium Inżynierii Oprogramowania Centrum Lotów Kosmicznych imienia Roberta H. Goddarda. Polega ono na ustaleniu trzech kroków: pierwszym jest zdefiniowanie celów projektu, drugim ustalenie pytań, na które trzeba odpowiedzieć w trakcie realizacji, trzecim wykonanie odpowiednich pomiarów, dostosowanych odpowiednio do pierwszych dwóch poziomów. Metryka powinna być ściśle dopasowana do tego, jakie informacje są potrzebne w trakcie procesu tworzenia produktu. Używanie wyłącznie metryk ogólnych może być mylące, a nawet niebezpieczne.
Podział Podstawowy podział metryk oprogramowania związany jest ze sposobem podejścia do jego analizy i testowania. Podobnie jak testy dzielą się na testy strukturalne (testy białej skrzynki) oraz testy funkcjonalne (testy czarnej skrzynki), tak też można podzielić metryki na związane z analizą kodu źródłowego metryki statyczne oraz metryki dynamiczne, wyznaczane w oderwaniu od kodu i badające zachowanie uruchomionego programu. Osobną kategorią są metryki niezwiązane bezpośrednio z implementacją oprogramowania, lecz z jego specyfikacją, wymaganiami klienta, a także z przebiegiem testów.
Inne podejście dzieli metryki ze względu na obiekty i wartości je charakteryzujące, jakie są przez nie mierzone. Można wyróżnić metryki produktów, takie jak metryki rozmiaru (), metryki złożoności () czy metryki jakości (). Innymi metrykami są metryki procesów (), metryki zasobów () czy metryki projektu (). Wyraźny jest tu podział na metryki produktów, dotyczące właściwości samego oprogramowania, oraz metryki procesów, charakteryzujące proces jego wytwarzania.
Metryki mogą mierzyć wartości bezpośrednio (np. liczba linii kodu) lub pośrednio, najpierw obliczając wartości składowe (np. częstość występowania błędów = liczba błędów / całkowity rozmiar produktu), mogą też bazować na subiektywnych prognozach (np. punkty funkcyjne).
Metryki statyczne Metryki statyczne pozwalają na ocenę jakości kodu źródłowego i łączą się ściśle z analizą statyczną, dziedziną inżynierii oprogramowania zajmującą się badaniem struktury kodu źródłowego. Metryki te najbardziej przydatne są dla samych programistów i innych osób bezpośrednio zaangażowanych w proces powstawania oprogramowania. Pozwalają na bieżące śledzenie jakości kodu i zwrócenie uwagi na miejsca, które wymagają uproszczenia bądź szczególnie uważnego testowania.
Metryki rozmiaru Linie kodu thumb|300px|Przykładowy kod w Javie: wszystkich LOC jest 18, bez pustych linii 16, bez komentarzy 9, bez nawiasów 8
Najprostszą metryką rozmiaru oprogramowania jest liczba linii kodu źródłowego, oznaczana jako () lub (). Wielkość ta daje ogólne pojęcie o skali programu, nie jest jednak wystarczająca do bardziej szczegółowych analiz. Wartość jest silnie zależna od użytego języka programowania – ten sam algorytm w języku wysokiego poziomu będzie miał wielokrotnie mniej linii kodu niż w asemblerze.
Istotny jest też sposób zliczania linii kodu – ich liczba może się zdecydowanie zmieniać, zależnie od tego, czy wliczane są puste linie, komentarze czy linie zawierające jedynie nawiasy klamrowe (m.in. w językach C, Java czy PHP) bądź słowa kluczowe begin i end (w Pascalu). Liczba linii z pominięciem wymienionych elementów jest określana jako ().
Alternatywą dla zliczania fizycznych linii kodu jest miara logicznych linii kodu, oznaczana jako (). Miara ta jest zależna od użytego języka programowania, np. w C zliczane są linie zakończone średnikami.
W większych projektach używane są jednostki pochodne takie jak KLOC (kilo-LOC).
Liczba tokenów Podstawową wadą liczby linii kodu jako metryki jest fakt, że nie odróżnia ona w żaden sposób trudnych i łatwych części kodu źródłowego oraz premiuje rozwlekły styl pisania programów. Aby nadać odpowiednie wagi mniej i bardziej skomplikowanym liniom kodu, można zastosować inną metrykę, mierzącą liczbę tokenów – czyli podstawowych jednostek składni języka programowania. Schemat takiej metryki został użyty po raz pierwszy w 1977 przez Maurice’a Howarda Halsteada w jego rodzinie metryk zwanej metrykami Halsteada, a przez niego samego nazwanych Software Science. Halstead rozróżnił dwa typy tokenów, na które można podzielić całość kodu źródłowego (bez komentarzy). Są to operatory (symbole i słowa kluczowe symbolizujące pewną akcję) i operandy (zmienne, stałe itp.). Na ich podstawie można określić podstawowe metryki: – liczba unikatowych operatorów – liczba unikatowych operandów – całkowita liczba wystąpień operatorów – całkowita liczba wystąpień operandów.
Reguły klasyfikowania symboli jako operatorów i operandów są zależne od języka programowania. Na podstawie tych podstawowych wartości można określić kolejne, bardziej złożone: = słownictwo () = długość () = objętość ().
Badania wskazały, że wartości i są liniowo powiązane z liczbą linii kodu, mierzą więc tę samą wielkość. Charakteryzuje je jednak wyższa odporność na małe zmiany w kodzie. Halstead zaproponował też kolejne metryki, dotyczące już nie tylko rozmiaru, ale i złożoności programu, o których jest mowa poniżej.
Inne metryki Szeroko stosowane są jednostki rozmiaru programu większe niż linie kodu. Dla większych aplikacji często stosowanymi metrykami są liczba modułów czy liczba funkcji. Ponieważ obecnie dominującym paradygmatem programowania jest podejście obiektowe, wytworzono wiele metod mierzenia oprogramowania dla niego specyficznych (zob. metryki obiektowe). Podstawowymi metrykami rozmiaru dla projektów obiektowych są np. liczba klas i interfejsów.
Na podstawie linii kodu można wyliczyć wiele metryk pochodnych, takich jak produktywność (KLOC / osobomiesiąc), jakość (błędy / KLOC), koszt (koszt / KLOC) czy ilość dokumentacji (strony dokumentacji / KLOC). Należy pamiętać, że zawsze będą one miały jedynie charakter pomocniczy i niedopuszczalne jest np. ocenianie pracowników wyłącznie na podstawie liczby napisanych linii koduPor. np. .
Podstawowe metryki złożoności Sam rozmiar programu jest informacją przydatną, jednak daje zbyt mało wiedzy na jego temat. Aby scharakteryzować oprogramowanie pod względem jego złożoności, trzeba użyć innych metod. Jeśli użyte są wyrafinowane algorytmy, cenną miarą będzie ich złożoność obliczeniowa. Wartość ta ma kluczowe znaczenie w badaniu wydajności, często daje jednak informacje o małym wycinku kodu źródłowego. Metryki mierzące złożoność opierają się na strukturze kodu źródłowego.
Złożoność cyklomatyczna McCabe’a thumb|200px|Przykład funkcji o niskim CC:8 węzłów, 8 krawędzi,CC = 8 – 8 + 2 = 2
Jedną z najbardziej podstawowych metryk złożoności jest złożoność cyklomatyczna (, ozn. CC lub v(G)), zaproponowana przez Thomasa J. McCabe’a w 1976. Pierwotnie pomyślana była jako metryka dla programów strukturalnych, nadaje się jednak równie dobrze do programów obiektowych, dzięki czemu jest popularna także dzisiaj. Złożoność cyklomatyczna jest liczbą charakteryzującą funkcję lub metodę i odzwierciedlającą jej poziom skomplikowania.
Początkowo złożoność cyklomatyczna miała mierzyć liczbę niezależnych ścieżek przebiegu programu, co bezpośrednio przekłada się na łatwość jego przetestowania. Ponieważ skoki wstecz mogą spowodować nieskończony wzrost takich ścieżek, mierzy się liczbę prostych ścieżek bez uwzględniania cykli.
Złożoność cyklomatyczną dla danej funkcji można policzyć, mając do dyspozycji graf przebiegu programu. Wówczas wyraża się ona wzorem
gdzie oznacza liczbę krawędzi, a liczbę wierzchołków w grafie. Inny wzór podaje prostą zależność CC od liczby węzłów, w których podejmujemy decyzje:
gdzie to liczba węzłów decyzyjnych, w których podejmowana jest decyzja o charakterze binarnym (tak/nie).
Taki wzór pozwala na szybkie wyznaczanie wartości CC – wystarcza tu zliczyć liczbę wystąpień słów kluczowych if, while, for czy case.
Niska wartość CC wskazuje na łatwość zrozumienia danej funkcji czy metody. Wartość powyżej 20 charakteryzuje złożony kod i wiąże się z dużym ryzykiem wystąpienia błędów.
Zaletami metryki CC są m.in. łatwość jej obliczenia i możliwość wskazania elementów aplikacji, które należy przeprojektować. Liczba rozgałęzień przepływu programu nie daje jednak pełnej informacji, ponieważ nie rozróżnia zagnieżdżonych i niezagnieżdżonych pętli oraz prostych instrukcji case, a także nie bierze pod uwagę skomplikowanych warunków w węzłach decyzyjnych. Istnieją modyfikacje definicji CC, które pozwalają zredukować lub wyeliminować te wady.
Złożoność Halsteada Wspomniane wyżej metryki Halsteada dotyczące rozmiaru programu pozwalają na zdefiniowanie bardziej skomplikowanych metryk złożoności. Wyróżnia się wśród nich: