15 Aralık 2020 Salı

Cyclomatic Complexity - Esas Amacı Test Sayısını Belirlemektir

Giriş
Cyclomatic Complexity'nin Türkçesi kodun karmaşıklığı olarak ifade edilebilir. CC kod içinde decision Logic'in miktarı (the amount of decision logic in a source code function) hakkında bilgi verir

CC'nin Esas Kullanım Amacı
Açıklaması şöyle
Cyclomatic complexity is a metric invented to find out the number of tests to cover the given code fully.
Yani  %100 birim testi kapsaması için CC değeri kadar test yazmak gerekir.  Ancak CC değeri aynı zamanda kodun basitliğini ölçmek için de kullanılabilir.

CC Değeri
Şu şekilde düşünülebilir.
CYC SCORE LEVEL OF READABILITY
1-10               Maintainable code  
10-20       Difficult to support
20-40       Very difficult to support
>40               Unmaintainable code 
- CC'nin yüksek olması bir kodun kötü olduğunu gösterir. Yani code smell'dir.
- Decision Logic olmayan statement'lar CC'ye dahil değildir.
- CC'nin düşük olması kodun okunabilir olduğu anlamına gelmez! Bunun için bir de Cognitive Complexity değerine bakmak gerekir.

Switch/Case
CC'nin hesaplanmasına 2 ile başlanır. Her switch/case içindeki case için 1 eklenir.

If-Else
Örnek
Elimizde şöyle bir kod olsun. Bu kodun CC değeri 3
List<Applicant> applicants = ...
for (Applicant applicant : applicants) { //Condition 1
  //statement 2
  int salary = 0;
  if (applicant.isJavaDev()) { //condition 2
    //statement 3
    salary = ...;
  } else {
    //statement 4
    salary = ...;
  }
}
Fazla Sayıda If-Else Olması
Replace Conditional Refactoring yazısına bakabilirsiniz.

Buradaki soruda CC değeri 13 olan bir kodun If-Else ifadelerinden kurtulması için öneriler var. Çözüm genellikle if-else bloklarını tek bir döngü içine almak, reflection kullanmak veya if-else konfigürasyon içinse bu bilgiyi bir veri yapısı içine doldurarak arama yapmak şeklinde oluyor. Benzer bir örnek ise burada.

Boolean Logic
If/else if içinde OR/AND varsa her değişken için 1 eklenir.  Açıklaması şöyle
Complex conditions increase complexity eg (condition1 || condition2) add 2 score.
Örneğin elimizde şöyle bir kod olsun
if (A || B || C) {
  ...
}else {
  ...
}
Bu kod için 4 test gerekir. Programlama dilinin short-circuit evaluation yapması test sayısını değiştirmez!
  • 1xx: A is true, don't care about B and C - then path
  • 01x: A is false, B is true, don't care about C - then path
  • 001: A and B are false, C is true - then path
  • 000: A, B, and C are all false - else path

Hiç yorum yok:

Yorum Gönder