Measurable code quality

Measurable code quality

Held at the enterJS in Cologne, Germany at Tuesday, 1. July 2014.
The talk was in german.

56b1575ab3b392b92c19bbcf39e808f1?s=128

Andy Grunwald

July 01, 2014
Tweet

Transcript

  1. Codequalität messen EnterJS, 01. Juli 2014

  2. Andy Grunwald • Software Engineer bei @trivago
 • Open Source


    • @andygrunwald
 • @PHPUGDus
 • andygrunwald
  3. Code | qualität | messen

  4. None
  5. –Helmut Balzert „Unter Softwarequalität versteht man die Gesamtheit der Merkmale

    … eines Softwareprodukts, …, festgelegte oder vorausgesetzte Erfordernisse zu erfüllen.“
  6. None
  7. (Software)-Metriken

  8. Frontend Backend

  9. Frontend HTTP Requests Navigation Timing DOM Elemente Browser Repaints …

    Backend
  10. Frontend HTTP Requests Navigation Timing DOM Elemente Browser Repaints …

    Backend Request-Zeit Cache-Miss / -Hits Ressource-Zeit Business-Logik …
  11. Frontend HTTP Requests Navigation Timing DOM Elemente Browser Repaints …

    Backend Request-Zeit Cache-Miss / -Hits Ressource-Zeit Business-Logik … Source Code
  12. Source Code

  13. Source Code Functions count Nested depth Halstead Maintainability index LOC

    Parameter count Cyclomatic Complexity nPath Lint errors CLOC LLOC Your metric here
  14. Source Code Functions count Nested depth Halstead Maintainability index LOC

    Parameter count Cyclomatic Complexity nPath Lint errors CLOC LLOC Your metric here
  15. // Is a given array, string, … // An "empty"

    object has … _.isEmpty = function(obj) { if (obj == null) { return true; } ! if (_.isArray(obj)) { return obj.length === 0; } ! for (var key in obj) { if (_.has(obj, key)) { return false; } } ! return true; }; _.isEmpty(e);
  16. // Is a given array, string, … // An "empty"

    object has … _.isEmpty = function(obj) { if (obj == null) { return true; } ! if (_.isArray(obj)) { return obj.length === 0; } ! for (var key in obj) { if (_.has(obj, key)) { return false; } } ! return true; }; _.isEmpty(e); • LOC: 19
  17. // Is a given array, string, … // An "empty"

    object has … _.isEmpty = function(obj) { if (obj == null) { return true; } ! if (_.isArray(obj)) { return obj.length === 0; } ! for (var key in obj) { if (_.has(obj, key)) { return false; } } ! return true; }; _.isEmpty(e); • LOC: 19
 • CLOC: 2
  18. // Is a given array, string, … // An "empty"

    object has … _.isEmpty = function(obj) { if (obj == null) { return true; } ! if (_.isArray(obj)) { return obj.length === 0; } ! for (var key in obj) { if (_.has(obj, key)) { return false; } } ! return true; }; _.isEmpty(e); • LOC: 19
 • CLOC: 2
 • NCLOC: 17
  19. _.isEmpty(e); • LOC: 19
 • CLOC: 2
 • NCLOC: 17


    • LLOC: 9 // Is a given array, string, … // An "empty" object has … _.isEmpty = function(obj) { if (obj == null) { return true; } ! if (_.isArray(obj)) { return obj.length === 0; } ! for (var key in obj) { if (_.has(obj, key)) { return false; } } ! return true; };
  20. Source Code Functions count Nested depth Halstead Maintainability index LOC

    Parameter count Cyclomatic Complexity nPath Lint errors CLOC LLOC Your metric here
  21. Source Code Functions count Nested depth Halstead Maintainability index LOC

    Parameter count Cyclomatic Complexity nPath Lint errors CLOC LLOC Your metric here
  22. Cyclomatic Complexity / McCabe Anzahl von Entscheidungspunkten innerhalb einer Funktion

    (if, switch, for, while, …)
  23. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  24. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  25. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  26. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  27. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  28. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } } Cyclomatic Complexity: 4
  29. nPath Complexity Anzahl einzigartiger Ausführungspfade innerhalb einer Funktion

  30. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  31. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  32. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  33. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  34. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } }
  35. function nestedFunction(x, y, z) { if (x > 0) {

    if (y > 0) { if (z > 0) { console.log(z); } } } } nPath Complexity: 4
  36. Cyclomatic Complexity === nPath?

  37. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  38. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  39. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  40. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  41. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  42. Cyclomatic Complexity: 4 function nPath(x, y, z) { if (x

    > 0) { console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  43. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  44. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  45. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  46. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  47. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  48. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  49. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  50. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  51. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } }
  52. function nPath(x, y, z) { if (x > 0) {

    console.log(x); } ! if (y > 0) { console.log(y); } ! if (z > 0) { console.log(z); } } nPath Complexity: 8
  53. None
  54. None
  55. escomplex complexity-report plato Esprima yardstick jsmeter

  56. escomplex complexity-report plato Esprima yardstick jsmeter

  57. None
  58. ScanJS JSHint jsprime DoctorJs JSWhiz WALA

  59. None
  60. +

  61. None
  62. Sprach-Features

  63. function foo() { var a = [0, 1, 2, 3,

    4]; for (index = 0; index < a.length; ++index) { console.log(a[index]); } }
  64. function foo() { for (key in [0, 1, 2, 3,

    4]) { console.log(key); } } function foo() { var a = [0, 1, 2, 3, 4]; for (index = 0; index < a.length; ++index) { console.log(a[index]); } }
  65. function foo() { for (key in [0, 1, 2, 3,

    4]) { console.log(key); } } function foo() { [0, 1, 2, 3, 4].forEach(function (i) { console.log(i); }); } function foo() { var a = [0, 1, 2, 3, 4]; for (index = 0; index < a.length; ++index) { console.log(a[index]); } }
  66. JavaScript ist eine dynamische Sprache

  67. var a = 'if(arguments[0] > 0) ' + 'console.log(arguments);'; new

    Function(a)(5);
  68. var a = '(function() {' + 'if(arguments[0] > 0) '

    + 'console.log(arguments);' + '})(6)'; eval(a); var a = 'if(arguments[0] > 0) ' + 'console.log(arguments);'; new Function(a)(5);
  69. Referenzwerte / Schwellenwerte + Kontext

  70. None
  71. None
  72. None
  73. Referenzwerte / Schwellenwerte Niedrig Normal Hoch Sehr hoch Cyclomatic Complexity

    1-4 5-7 8-10 >= 11 nPath / / / >= 200
  74. Java (45 Projekte) Metrik Niedrig Normal Hoch Sehr hoch CYCLO/LOC

    0.16 0.20 0.24 0.36 LOC/Methode 7 10 13 19.5 NOM/Class 4 7 10 15
  75. Java (45 Projekte) Metrik Niedrig Normal Hoch Sehr hoch CYCLO/LOC

    0.16 0.20 0.24 0.36 LOC/Methode 7 10 13 19.5 NOM/Class 4 7 10 15 C++ (37 Projekte) Metrik Niedrig Normal Hoch Sehr hoch CYCLO/LOC 0.20 0.25 0.30 0.45 LOC/Methode 5 10 16 24 NOM/Class 4 9 15 22.5
  76. Metriken

  77. Source Code

  78. Source Code Functions count Nested depth Halstead Maintainability index LOC

    Parameter count Cyclomatic Complexity nPath Lint errors CLOC LLOC Your metric here
  79. None
  80. None
  81. None
  82. Verwendete Bilder • „Ruler“ by Scott Akerman: https://www.flickr.com/ photos/sterlic/4299631538/ •

    „the JavaScript Code“ by Dmitry Baranovskiy: https:// www.flickr.com/photos/dmitry-baranovskiy/2378867408 • „Ignition“ by Zach Dischner: https://www.flickr.com/ photos/zachd1_618/3489625168 • „Tools IMG_0171“ by OZinOH: https://www.flickr.com/ photos/75905404@N00/7126146307
  83. Verwendete Bilder • „Danger & Skull, Legoland“ by bixentro: https://

    www.flickr.com/photos/bixentro/338433029 • „Baby“ by The Noun Project: http://thenounproject.com/ term/baby/47/ • „Man“ by The Noun Project: http://thenounproject.com/ term/man/2/ • „Sasquatch“ by Mike Wirth: http://thenounproject.com/ term/sasquatch/2680/
  84. Verwendete Bilder • „Waking Up In Abbeyford Woods“ by Miles

    Wolstenholme: https://www.flickr.com/photos/ oaktorphotography/14444806464 • „Danke 102/365“ by Dennis Skley: https:// www.flickr.com/photos/dskley/13796815083/ • „Questions“ by Oberazzi: https://www.flickr.com/photos/ oberazzi/318947873/in/photostream/
  85. Zitate und Tabellen • Helmut Balzert: Lehrbuch der Softwaretechnik. Band

    2: Softwaremanagement, Software-Qualitätssicherung, Unternehmensmodellierung, Spektrum Akademischer Verlag, Heidelberg 1998, ISBN 3-8274-0065-1, S. 257 • Michele Lanza, Radu Marinescu: Object-Oriented Metrics in Practice: Using Software Metrics to Characterize, Evaluate, and Improve the Design of Object-Oriented Systems, Springer 2006, ISBN 3540244298