SlideShare a Scribd company logo
1 of 55
Download to read offline
Test-Driven Development
     turn development on its head


                           Aaron Nordyke
                       Sr. Software Engineer
                    Innovations Development
If I were being
completely honest,
there’s been a
consistent pattern in
my projects.
Dirty Code

Zero Unit Tests

Low Test Coverage

Stupid Bugs

Fear Of Breaking Anything
Dirty Code
Dirty Code
function fillXigrisRelative(){
    try {
        var at = _g("relativeTable");
        //var docfrag = document.createDocumentFragment();
                                                                          Big functions
        //INR > 3.0 - PTT > 40 sec
        //INR
        ea = getEvents("sep_inr_ec", SEPSISREPLY);
        for (i = 0; i < ea.length; i++) {
            for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
                event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
                disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
                rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
                xigrisNotify(_g("inrptt_notify"), [disp, rslt, event_dt]);
                if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 3.0) {
                    _g("rel_inrptt_form").ynu[0].checked = true;
                }
            }
        }
        //PTT
        ea = getEvents("sep_ptt_ec", SEPSISREPLY);
        for (i = 0; i < ea.length; i++) {
            for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
                event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
                disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
                rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
                xigrisNotify(_g("inrptt_notify"), [disp, rslt, event_dt]);
                if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 40) {
                    _g("rel_inrptt_form").ynu[0].checked = true;
                }
            }
        }
…
Dirty Code
//Platelet Count
       ea = getEvents("sep_plt_ec", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
                                                                                 …that keep going
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("platelet_notify"), [disp, rslt, event_dt]);
               if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL < 30000) {
                   _g("rel_platelet_form").ynu[0].checked = true;
               }
           }
       }
       //Gastro-intestinal bleed
       ea = getEvents("sep_gi_hem_dx", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX;
           rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP;
           event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL;
           xigrisNotify(_g("gastro_notify"), [disp,rslt,event_dt]);
           //_g("rel_gastro_form").ynu[0].checked = true;
       }
       //Thrombolytic therapy
       ea = getEvents("sep_thrombolytics_adm", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("thrombo_notify"), [disp, rslt, "Dose Given: " + event_dt]);
               _g("rel_thrombo_form").ynu[0].checked = true;
           }
       }
      …
Dirty Code
//Oral anticoagulants or...
       ea = getEvents("sep_oral_anticoag_adm", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("antiglyco_notify"), [disp, rslt, "Dose Given: " + event_dt]);
               _g("rel_antiglyco_form").ynu[0].checked = true;

       }
           }
                                                                                                …and going
       //...glycoprotein
       ea = getEvents("sep_glyco_plt_inh_adm", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("antiglyco_notify"), [disp, rslt, "Dose Given: " + event_dt]);
               _g("rel_antiglyco_form").ynu[0].checked = true;
           }
       }
       //Aspirin or...
       ea = getEvents("sep_aspirin_adm", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("aspirin_notify"), [disp, rslt, "Dose Given: " + event_dt]);
               //TODO - less than 24 hours
               if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 650) {
                   _g("rel_aspirin_form").ynu[0].checked = true;
Dirty Code
}
        }
    }
    //...other platelet inhibitor
    ea = getEvents("sep_plt_adm", SEPSISREPLY);
    for (i = 0; i < ea.length; i++) {
        for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
            event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
            disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
            rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
            xigrisNotify(_g("aspirin_notify"), ["Active Order", disp]);
            _g("rel_aspirin_form").ynu[0].checked = true;
        }
    }
    //Ischemic Stroke
    ea = getEvents("sep_ischemic_stk_dx", SEPSISREPLY);                   …and going
    for (i = 0; i < ea.length; i++) {
        disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX;
        rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP;
        event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL;
        xigrisNotify(_g("stroke_notify"), [disp,rslt,event_dt]);
        //_g("rel_stroke_form").ynu[0].checked = true;
    }
    //Intracranial Arteriovenous Malformation or aneurysm
    ea = getEvents("sep_aneurysm_dx", SEPSISREPLY);
    for (i = 0; i < ea.length; i++) {
        disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX;
        rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP;
        event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL;
        xigrisNotify(_g("aneurysm_notify"), [disp,rslt,event_dt]);
        _g("rel_aneurysm_form").ynu[0].checked = true;
    }
Dirty Code
      //Chronic Severe Hepatic Disease

  //...Hepatic
  ea = getEvents("sep_hepatic_dis_dx", SEPSISREPLY);
  for (i = 0; i < ea.length; i++) {
      disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX;
      rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP;
      event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL;
      xigrisNotify(_g("hepatic_notify"), [disp,rslt,event_dt]);
      _g("rel_hepatic_form").ynu[0].checked = true;
  }
  //...ALT > 100
  ea = getEvents("sep_alt_ec", SEPSISREPLY);
  for (i = 0; i < ea.length; i++) {
      for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
          event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
          disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
          rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
          xigrisNotify(_g("hepatic_notify"), [disp, rslt, event_dt]);
          if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 100) {
              _g("rel_hepatic_form").ynu[0].checked = true;

      }
          }                                                             …and going
  }
  //...AST > 100
  ea = getEvents("sep_ast_ec", SEPSISREPLY);
  for (i = 0; i < ea.length; i++) {
      for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
          event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
          disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
          rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
          xigrisNotify(_g("hepatic_notify"), [disp, rslt, event_dt]);
Dirty Code
if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 100) {
                   _g("rel_hepatic_form").ynu[0].checked = true;
               }
           }
       }
       //...AST
       ea = getEvents("sep_bilirubin_ec", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("hepatic_notify"), [disp, rslt, event_dt]);
               if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 2) {
                   _g("rel_hepatic_form").ynu[0].checked = true;
               }
           }
       }
       //Pregnant or Breastfeeding
       ea = getEvents("sep_pregnant_ec", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
           for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("pregnant_notify"), [disp, rslt, event_dt]);

           }
               _g("rel_pregnant_form").ynu[0].checked = true;                 …and going
       }
       ea = getEvents("sep_breastfeeding_ec", SEPSISREPLY);
       for (i = 0; i < ea.length; i++) {
Dirty Code
for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) {
               event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP;
               disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP;
               rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT;
               xigrisNotify(_g("pregnant_notify"), [disp, rslt, event_dt]);
               _g("rel_pregnant_form").ynu[0].checked = true;
           }
       }
       //check with handler
       xigrisRelativeHandler();

    }
    catch (e) {
        errorHandler(e, "fillXigrisRelative()");
    }
}




                                                                              …and going
Dirty Code
                              Big functions


  A function should do one thing.
  “One thing. Just one thing. You stick to
  that and the rest don't mean sh*t.”
                          Curly, City Slickers
Dirty Code
             High coupling
Dirty Code

Zero Unit Tests
Zero Unit Tests




 Dirty Code is hard to test
Zero Unit Tests

Ease of
Unit Testing




                  Function Size
Zero Unit Tests

Ease of
Unit Testing




                  Coupling
Zero Unit Tests

Ease of
Unit Testing




                  Number of things the
                  function does
Dirty Code

Zero Unit Tests

Low Test Coverage
Low Test Coverage


 I relied on a little helper
   who was never meant
      to have so much
        responsibility.
Low Test Coverage




    Functional Tests
 King of the Black Boxes
Low Test Coverage
                         Functional Testing
                         has its place




     A-Bomb Testing, Nevada Test Site, 1955
Dirty Code

Zero Unit Tests

Low Test Coverage

Stupid Bugs
Stupid Bugs



   “How in the hell
   did I miss that one?”
              - Me, after every defect
Dirty Code

Zero Unit Tests

Low Test Coverage

Stupid Bugs

Fear Of Breaking Anything
Fear of Breaking Anything
Conventional Development




           write code
Conventional Development




            test code
Conventional Development


 What if we reversed it?
           write code
            test code
Conventional Development


 What if we reversed it?
            test code
           write code
              (WTF?)
Test-Driven Development
     turn development on its head
Test-Driven Development




 “Red, Green, Refactor”
Test-Driven Development

                                         1
                                         Write a test that fails
                            Red



 3
 Clean up code



                 Refactor              Green



                                  2
                                  Make the test pass
a (very) trivial example
1. Write a test that fails
  1. Write one unit test
                             addNumber_test.js




  2. Run the test and verify the failure
2. Make the test pass
  1. Write just enough code to make failing test
     pass.                   addNumber_test.js




                   addNumber.js




  2. Run the test and verify the success
3. Clean up code


   If able, clean up Code and Unit Tests




   “Leave the campground cleaner than you found it.”
                             Boy Scouts of America
1. Write a test that fails (Round 2)
  1. Write one unit test
                             addNumber_test.js




  2. Run the test and verify the failure
2. Make the test pass                (Round 2)
  1. Write just enough code to make failing
     test pass.              addNumber_test.js




                addNumber.js




  2. Run the test and verify the success
3. Clean up code                          (Round 2)

   It’s tough to clean code this simple, so
   we’re done.
                             addNumber_test.js




              addNumber.js
Dirty Code

Zero Unit Tests

Low Test Coverage

Stupid Bugs

Fear Of Breaking Anything
Clean Code

Lotsa Unit Tests

High Test Coverage

Stupid Bugs (but a whole lot less of them)

No Fear Of Breaking Anything
Clean Code


  Having to test a little
  code at a time forced
  me to write smaller functions
              with lower coupling
              that did one thing.
Lotsa Unit Tests

 They help me sleep at night
High Test Coverage




The code follows the tests.
It makes sense that test coverage would be high.
High Test Coverage



I no longer have to rely on the functional
testers to tell me my code works. I know
it works.

For my F5 tells me so.
No fear of breaking anything

This one’s my favorite, because it
means I can refactor mercilessly.


Every time I make a code change, I run
the tests. They tell me immediately
and loudly if I broke anything.
No fear of breaking anything



                   Like Patrick Bateman
                   in American Psycho, I
                   laugh maniacally while
                   I carve up bodies of
                   code.
Other Reasons that TDD Rules
   Unit Tests are Documentation
Other Reasons that TDD Rules
   Closes the Feedback Loop

   “The act of writing a unit test is more an act of design
   than of verification. It is also more an act of
   documentation than of verification. The act of writing a
   unit test closes a remarkable number of feedback loops,
   the least of which is the one pertaining to verification
   of function.”
                               Robert “Uncle Bob” Martin
                               Agile Software Development


  ( You know code works after
    30 seconds, not 10 minutes.    )
It can be quite a struggle at first.
Downright painful.
No code until you write your tests!
Not a silver bullet
Questions?

More Related Content

Similar to Test-Driven Development in JavaScript

Inteligencia artificial 4
Inteligencia artificial 4Inteligencia artificial 4
Inteligencia artificial 4Nauber Gois
 
L04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptx
L04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptxL04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptx
L04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptxEliasPetros
 
fixed 3 issues. I am working on remaining.package chegg;public c.pdf
fixed 3 issues. I am working on remaining.package chegg;public c.pdffixed 3 issues. I am working on remaining.package chegg;public c.pdf
fixed 3 issues. I am working on remaining.package chegg;public c.pdfanjanacottonmills
 
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docxsrcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docxwhitneyleman54422
 
Creating windows store java script apps
Creating windows store java script appsCreating windows store java script apps
Creating windows store java script appsEugene Zharkov
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersIan Barber
 
Java.script
Java.scriptJava.script
Java.scriptg Nama
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionIban Martinez
 
WordPressでIoTをはじめよう
WordPressでIoTをはじめようWordPressでIoTをはじめよう
WordPressでIoTをはじめようYuriko IKEDA
 
JVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's TricksJVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's TricksDoug Hawkins
 
YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docx
 YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docx YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docx
YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docxgertrudebellgrove
 
Web Optimization Summit: Coding for Performance
Web Optimization Summit: Coding for PerformanceWeb Optimization Summit: Coding for Performance
Web Optimization Summit: Coding for Performancejohndaviddalton
 
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019Codemotion
 
KODE JS POKENNNNN
KODE JS POKENNNNNKODE JS POKENNNNN
KODE JS POKENNNNNPipo Atem
 
Build a custom (micro)framework with ZF2 Components (as building blocks)
Build a custom (micro)framework with ZF2 Components (as building blocks)Build a custom (micro)framework with ZF2 Components (as building blocks)
Build a custom (micro)framework with ZF2 Components (as building blocks)Corley S.r.l.
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the typeWim Godden
 

Similar to Test-Driven Development in JavaScript (20)

Inteligencia artificial 4
Inteligencia artificial 4Inteligencia artificial 4
Inteligencia artificial 4
 
L04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptx
L04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptxL04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptx
L04 - Control Structuresjhgjhgjhgjhgfjgfjhgfjgf.pptx
 
fixed 3 issues. I am working on remaining.package chegg;public c.pdf
fixed 3 issues. I am working on remaining.package chegg;public c.pdffixed 3 issues. I am working on remaining.package chegg;public c.pdf
fixed 3 issues. I am working on remaining.package chegg;public c.pdf
 
Blocks+gcd入門
Blocks+gcd入門Blocks+gcd入門
Blocks+gcd入門
 
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docxsrcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
 
Creating windows store java script apps
Creating windows store java script appsCreating windows store java script apps
Creating windows store java script apps
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
teste
testeteste
teste
 
Java.script
Java.scriptJava.script
Java.script
 
Html
HtmlHtml
Html
 
Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
WordPressでIoTをはじめよう
WordPressでIoTをはじめようWordPressでIoTをはじめよう
WordPressでIoTをはじめよう
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
JVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's TricksJVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's Tricks
 
YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docx
 YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docx YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docx
YOU SHOULD NOT MODIFY ANYTHING IN THIS FILE .docx
 
Web Optimization Summit: Coding for Performance
Web Optimization Summit: Coding for PerformanceWeb Optimization Summit: Coding for Performance
Web Optimization Summit: Coding for Performance
 
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
Matteo Antony Mistretta - Refactoring into React hooks - Codemotion Rome 2019
 
KODE JS POKENNNNN
KODE JS POKENNNNNKODE JS POKENNNNN
KODE JS POKENNNNN
 
Build a custom (micro)framework with ZF2 Components (as building blocks)
Build a custom (micro)framework with ZF2 Components (as building blocks)Build a custom (micro)framework with ZF2 Components (as building blocks)
Build a custom (micro)framework with ZF2 Components (as building blocks)
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the type
 

Recently uploaded

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 

Recently uploaded (20)

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 

Test-Driven Development in JavaScript

  • 1. Test-Driven Development turn development on its head Aaron Nordyke Sr. Software Engineer Innovations Development
  • 2. If I were being completely honest, there’s been a consistent pattern in my projects.
  • 3. Dirty Code Zero Unit Tests Low Test Coverage Stupid Bugs Fear Of Breaking Anything
  • 5. Dirty Code function fillXigrisRelative(){ try { var at = _g("relativeTable"); //var docfrag = document.createDocumentFragment(); Big functions //INR > 3.0 - PTT > 40 sec //INR ea = getEvents("sep_inr_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("inrptt_notify"), [disp, rslt, event_dt]); if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 3.0) { _g("rel_inrptt_form").ynu[0].checked = true; } } } //PTT ea = getEvents("sep_ptt_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("inrptt_notify"), [disp, rslt, event_dt]); if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 40) { _g("rel_inrptt_form").ynu[0].checked = true; } } } …
  • 6. Dirty Code //Platelet Count ea = getEvents("sep_plt_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; …that keep going rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("platelet_notify"), [disp, rslt, event_dt]); if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL < 30000) { _g("rel_platelet_form").ynu[0].checked = true; } } } //Gastro-intestinal bleed ea = getEvents("sep_gi_hem_dx", SEPSISREPLY); for (i = 0; i < ea.length; i++) { disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX; rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP; event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL; xigrisNotify(_g("gastro_notify"), [disp,rslt,event_dt]); //_g("rel_gastro_form").ynu[0].checked = true; } //Thrombolytic therapy ea = getEvents("sep_thrombolytics_adm", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("thrombo_notify"), [disp, rslt, "Dose Given: " + event_dt]); _g("rel_thrombo_form").ynu[0].checked = true; } } …
  • 7. Dirty Code //Oral anticoagulants or... ea = getEvents("sep_oral_anticoag_adm", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("antiglyco_notify"), [disp, rslt, "Dose Given: " + event_dt]); _g("rel_antiglyco_form").ynu[0].checked = true; } } …and going //...glycoprotein ea = getEvents("sep_glyco_plt_inh_adm", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("antiglyco_notify"), [disp, rslt, "Dose Given: " + event_dt]); _g("rel_antiglyco_form").ynu[0].checked = true; } } //Aspirin or... ea = getEvents("sep_aspirin_adm", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("aspirin_notify"), [disp, rslt, "Dose Given: " + event_dt]); //TODO - less than 24 hours if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 650) { _g("rel_aspirin_form").ynu[0].checked = true;
  • 8. Dirty Code } } } //...other platelet inhibitor ea = getEvents("sep_plt_adm", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("aspirin_notify"), ["Active Order", disp]); _g("rel_aspirin_form").ynu[0].checked = true; } } //Ischemic Stroke ea = getEvents("sep_ischemic_stk_dx", SEPSISREPLY); …and going for (i = 0; i < ea.length; i++) { disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX; rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP; event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL; xigrisNotify(_g("stroke_notify"), [disp,rslt,event_dt]); //_g("rel_stroke_form").ynu[0].checked = true; } //Intracranial Arteriovenous Malformation or aneurysm ea = getEvents("sep_aneurysm_dx", SEPSISREPLY); for (i = 0; i < ea.length; i++) { disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX; rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP; event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL; xigrisNotify(_g("aneurysm_notify"), [disp,rslt,event_dt]); _g("rel_aneurysm_form").ynu[0].checked = true; }
  • 9. Dirty Code //Chronic Severe Hepatic Disease //...Hepatic ea = getEvents("sep_hepatic_dis_dx", SEPSISREPLY); for (i = 0; i < ea.length; i++) { disp = SEPSISREPLY.VALUES[ea[i]].VALEVENTFTX; rslt = SEPSISREPLY.VALUES[ea[i]].VALEVENTNOMDISP; event_dt = SEPSISREPLY.VALUES[ea[i]].VALEVENTMPVAL; xigrisNotify(_g("hepatic_notify"), [disp,rslt,event_dt]); _g("rel_hepatic_form").ynu[0].checked = true; } //...ALT > 100 ea = getEvents("sep_alt_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("hepatic_notify"), [disp, rslt, event_dt]); if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 100) { _g("rel_hepatic_form").ynu[0].checked = true; } } …and going } //...AST > 100 ea = getEvents("sep_ast_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("hepatic_notify"), [disp, rslt, event_dt]);
  • 10. Dirty Code if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 100) { _g("rel_hepatic_form").ynu[0].checked = true; } } } //...AST ea = getEvents("sep_bilirubin_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("hepatic_notify"), [disp, rslt, event_dt]); if (SEPSISREPLY.VALUES[ea[i]].EVENTS[j].RSLTVAL > 2) { _g("rel_hepatic_form").ynu[0].checked = true; } } } //Pregnant or Breastfeeding ea = getEvents("sep_pregnant_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("pregnant_notify"), [disp, rslt, event_dt]); } _g("rel_pregnant_form").ynu[0].checked = true; …and going } ea = getEvents("sep_breastfeeding_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) {
  • 11. Dirty Code for (j = 0; j < SEPSISREPLY.VALUES[ea[i]].EVENTS.length; j++) { event_dt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENTDTDISP; disp = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_DISP; rslt = SEPSISREPLY.VALUES[ea[i]].EVENTS[j].EVENT_RESULT; xigrisNotify(_g("pregnant_notify"), [disp, rslt, event_dt]); _g("rel_pregnant_form").ynu[0].checked = true; } } //check with handler xigrisRelativeHandler(); } catch (e) { errorHandler(e, "fillXigrisRelative()"); } } …and going
  • 12. Dirty Code Big functions A function should do one thing. “One thing. Just one thing. You stick to that and the rest don't mean sh*t.” Curly, City Slickers
  • 13. Dirty Code High coupling
  • 15. Zero Unit Tests Dirty Code is hard to test
  • 16. Zero Unit Tests Ease of Unit Testing Function Size
  • 17. Zero Unit Tests Ease of Unit Testing Coupling
  • 18. Zero Unit Tests Ease of Unit Testing Number of things the function does
  • 19. Dirty Code Zero Unit Tests Low Test Coverage
  • 20. Low Test Coverage I relied on a little helper who was never meant to have so much responsibility.
  • 21. Low Test Coverage Functional Tests King of the Black Boxes
  • 22. Low Test Coverage Functional Testing has its place A-Bomb Testing, Nevada Test Site, 1955
  • 23. Dirty Code Zero Unit Tests Low Test Coverage Stupid Bugs
  • 24. Stupid Bugs “How in the hell did I miss that one?” - Me, after every defect
  • 25. Dirty Code Zero Unit Tests Low Test Coverage Stupid Bugs Fear Of Breaking Anything
  • 26. Fear of Breaking Anything
  • 29. Conventional Development What if we reversed it? write code test code
  • 30. Conventional Development What if we reversed it? test code write code (WTF?)
  • 31. Test-Driven Development turn development on its head
  • 32. Test-Driven Development “Red, Green, Refactor”
  • 33. Test-Driven Development 1 Write a test that fails Red 3 Clean up code Refactor Green 2 Make the test pass
  • 34. a (very) trivial example
  • 35. 1. Write a test that fails 1. Write one unit test addNumber_test.js 2. Run the test and verify the failure
  • 36. 2. Make the test pass 1. Write just enough code to make failing test pass. addNumber_test.js addNumber.js 2. Run the test and verify the success
  • 37. 3. Clean up code If able, clean up Code and Unit Tests “Leave the campground cleaner than you found it.” Boy Scouts of America
  • 38. 1. Write a test that fails (Round 2) 1. Write one unit test addNumber_test.js 2. Run the test and verify the failure
  • 39. 2. Make the test pass (Round 2) 1. Write just enough code to make failing test pass. addNumber_test.js addNumber.js 2. Run the test and verify the success
  • 40. 3. Clean up code (Round 2) It’s tough to clean code this simple, so we’re done. addNumber_test.js addNumber.js
  • 41. Dirty Code Zero Unit Tests Low Test Coverage Stupid Bugs Fear Of Breaking Anything
  • 42. Clean Code Lotsa Unit Tests High Test Coverage Stupid Bugs (but a whole lot less of them) No Fear Of Breaking Anything
  • 43. Clean Code Having to test a little code at a time forced me to write smaller functions with lower coupling that did one thing.
  • 44. Lotsa Unit Tests They help me sleep at night
  • 45. High Test Coverage The code follows the tests. It makes sense that test coverage would be high.
  • 46. High Test Coverage I no longer have to rely on the functional testers to tell me my code works. I know it works. For my F5 tells me so.
  • 47. No fear of breaking anything This one’s my favorite, because it means I can refactor mercilessly. Every time I make a code change, I run the tests. They tell me immediately and loudly if I broke anything.
  • 48. No fear of breaking anything Like Patrick Bateman in American Psycho, I laugh maniacally while I carve up bodies of code.
  • 49. Other Reasons that TDD Rules Unit Tests are Documentation
  • 50. Other Reasons that TDD Rules Closes the Feedback Loop “The act of writing a unit test is more an act of design than of verification. It is also more an act of documentation than of verification. The act of writing a unit test closes a remarkable number of feedback loops, the least of which is the one pertaining to verification of function.” Robert “Uncle Bob” Martin Agile Software Development ( You know code works after 30 seconds, not 10 minutes. )
  • 51. It can be quite a struggle at first. Downright painful.
  • 52. No code until you write your tests!
  • 53.
  • 54. Not a silver bullet