Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Test-Driven Development

Test-Driven Development

Introduction to Test-Driven Development, with examples in JavaScript.

Aaron Nordyke

November 14, 2011
Tweet

More Decks by Aaron Nordyke

Other Decks in Programming

Transcript

  1. function fillXigrisRelative(){ try { var at = _g("relativeTable"); //var docfrag

    = document.createDocumentFragment(); //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 Big functions
  2. //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; 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; } } … …that keep going Dirty Code
  3. //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; } } //...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; …and going Dirty Code
  4. } } } //...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); 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; } …and going Dirty Code
  5. //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; } } } //...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]); …and going Dirty Code
  6. 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; } } ea = getEvents("sep_breastfeeding_ec", SEPSISREPLY); for (i = 0; i < ea.length; i++) { …and going Dirty Code
  7. 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
  8. Dirty Code A function should do one thing. Big functions

    “One thing. Just one thing. You stick to that and the rest don't mean sh*t.” Curly, City Slickers
  9. Low Test Coverage I relied on a little helper who

    was never meant to have so much responsibility.
  10. Stupid Bugs “How in the hell did I miss that

    one?” - Me, after every defect
  11. 1. Write a test that fails 1. Write one unit

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

    to make failing test pass. 2. Run the test and verify the success addNumber_test.js addNumber.js
  13. 3. Clean up code If able, clean up Code and

    Unit Tests “Leave the campground cleaner than you found it.” Boy Scouts of America
  14. 1. Write a test that fails 1. Write one unit

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

    to make failing test pass. 2. Run the test and verify the success addNumber.js addNumber_test.js (Round 2)
  16. 3. Clean up code It’s tough to clean code this

    simple, so we’re done. addNumber.js addNumber_test.js (Round 2)
  17. Stupid Bugs (but a whole lot less of them) High

    Test Coverage Clean Code No Fear Of Breaking Anything Lotsa Unit Tests
  18. Clean Code smaller functions Having to test a little code

    at a time forced me to write with lower coupling that did one thing.
  19. High Test Coverage The code follows the tests. It makes

    sense that test coverage would be high.
  20. 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.
  21. 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.
  22. No fear of breaking anything Like Patrick Bateman in American

    Psycho, I laugh maniacally while I carve up bodies of code.
  23. Other Reasons that TDD Rules “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 Closes the Feedback Loop You know code works after 30 seconds, not 10 minutes. ( )