Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Unit Testing

111 views

Published on

A short presentation slide deck I gave to interns we have this summer of 2019 on (unit) testing in software development. This is not a code-centric slide deck and just looking at the slides loses some context without being there in person, or having discussions, etc.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Unit Testing

  1. 1. Scott Leberknight 6/28/2019 (Unit) Testing
  2. 2. Why Test?
  3. 3. Does your code work? How do you know?
  4. 4. Tests provide some level of confidence your code does what you think it does…
  5. 5. …which is not the same as saying the code is correct from a business perspective
  6. 6. Tests cannot and will not ever catch or prevent all possible problems
  7. 7. You might have a passing test suite but still have logic bugs… e.g. due to poorly defined or understood requirements, poor design, etc.
  8. 8. “In the 737 Max, only one of the flight management computers is active at a time - either the pilot’s computer or the copilot’s computer.And the active computer takes inputs only from the sensors on its own side of the aircraft.” https://spectrum.ieee.org/aerospace/aviation/how-the-boeing-737-max-disaster-looks-to-a-software-developer
  9. 9. “When the two computers disagree, the solution for the humans in the cockpit is 
 to look across the control panel to see
 what the other instruments are saying and then sort it out. In the Boeing system, the flight management computer does not “look 
 across” at the other instruments. It 
 believes only the instruments on its side.” https://spectrum.ieee.org/aerospace/aviation/how-the-boeing-737-max-disaster-looks-to-a-software-developer
  10. 10. “This means that if a particular angle-of- attack sensor goes haywire - which happens all the time in a machine that alternates from one extreme environment to another, vibrating and shaking all the way - the flight management computer just believes it.” https://spectrum.ieee.org/aerospace/aviation/how-the-boeing-737-max-disaster-looks-to-a-software-developer
  11. 11. “The primary cause of this discrepancy was that one piece of ground software supplied by Lockheed Martin produced results in a United States customary unit, contrary to its Software Interface Specification (SIS), while a second system, supplied by NASA, expected those results to be in SI units, in accordance with the SIS. Specifically, software that calculated the total impulse produced by thruster firings produced results in pound-force seconds.The trajectory calculation software then used these results – expected to be in newton seconds – to update the predicted position of the spacecraft.” https://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_failure
  12. 12. The act of testing makes you consider more than just the “happy path”
  13. 13. Many Flavors… “Unit” Integration Performance Functional (QA) Security User interface Other…?Exploratory
  14. 14. Good testing… Automated Repeatable Continuous (“ARC” testing)
  15. 15. Good unit testing… Fast (a few milliseconds?) Isolated (no “real” dependencies) Consider success & failure modes
  16. 16. What is a “unit” test? Not always clearly defined A single class? A single function? Can it touch external resources? (e.g. a database, web service, or file system)
  17. 17. @Test fun `contribution should be sum of salary & Roth deferrals`() { assertThat(payroll.totalContribution) .isEqualTo(payroll.salaryDeferral + payroll.rothDeferral) } A simple unit test
  18. 18. Potential Benefits Find regressions quickly Confidence Better design (*) (*) probably… You can go faster in the long run
  19. 19. Potential Pitfalls False confidence Tests can have bugs too… (*) debatable, but not in my personal experience… You might be slower in short run (*)
  20. 20. What to test? “Business” logic… Persistence logic… User interfaces… “Anything that can possibly break” ???
  21. 21. What to test? Test your code… …not your dependencies
  22. 22. What to test? More generally you should assume libraries, frameworks, operating systems, etc. have been tested and work as advertised… (obviously there are caveats to the above)
  23. 23. How to test? TDD (Test-Driven Development aka “test first”) TAST (test at same time, commit only tested code) Test after (avoid…or deal with the consequences) …on “legacy code” this is your only option
  24. 24. “Legacy Code” “To me, legacy code is simply code without tests” - Michael Feathers, Working Effectively with Legacy Code
  25. 25. “TDD” Test-driven development Usually associated with “test first” Write failing test, write simplest code to make it pass, repeat… “Red-Green-Refactor” cycle
  26. 26. “TDD” Can you be test-driven without test first? I think you can… By letting tests drive the design… And guide towards “testable” code…
  27. 27. Tests & Design What does “testable” code mean? * Loosely coupled, e.g. injecting dependencies * Separation of concerns * Single Responsibility Principle (SRP)
  28. 28. Tests & Design What does “testable” code look like? * Smaller classes in OO languages * Smaller methods/functions (7-10 lines max? 20? 30?) * Injected dependencies, e.g. via constructors or function parameters * More “pure” functions
  29. 29. Tests & Design Why do these things make code testable? * Facilitates “mocking” dependencies, e.g. a credit card processing web service, or persistence to a database * A function that accepts input, has no side effects, and produces a consistent output is much easier to test
  30. 30. Testing Techniques Prefer smaller, targeted tests (less coupling) Mock objects (but don’t overdo it) Perform assertions on return values Verify behavior of mock objects (correct methods called, expected arguments)
  31. 31. Testing Techniques Property-based testing Test “units” and mock dependencies Generative testing Measuring code “covered” by tests
  32. 32. Example test using a mock
  33. 33. @ExtendWith(DropwizardExtensionsSupport.class) class RelationshipResourceTest { private static final RelationshipService SERVICE = mock(RelationshipService.class); private static final ResourceExtension RESOURCES = ResourceExtension.builder() .addResource(new RelationshipResource(SERVICE)) .build(); @AfterEach void tearDown() { reset(SERVICE); } @Test @DisplayName("given a valid event should attempt to save the event") void testRecordEvent() { ConnectionEvent event = newConnectionEvent(A_SERVICE_NAME, Direction.OUTBOUND, "some-identifier"); Response response = RESOURCES.target(“/elucidate/event") .request() .post(Entity.json(event)); assertThat(response.getStatus()).isEqualTo(202); verify(SERVICE).createEvent(eq(event)); } // more tests... }
  34. 34. Testing Async Code No sleeps! Mock the environment “If we go by the book…hours could seem like days…” Wait for conditions (e.g. until a status value is changed)
  35. 35. Unit vs Integration Tests * A unit test of a single HTTP endpoint accepts HTTP requests, but uses mock dependencies, e.g. objects to persist data, or process payments, or send asynchronous messages * An integration test of that single HTTP endpoint accepts HTTP requests, but uses the actual dependencies…
  36. 36. Code Coverage How much is “enough”? Should automated builds fail if below a threshold? 70%? 80%? Can/should you test all exceptional conditions?
  37. 37. Code Coverage By definition, decoupled, “testable” code is easier to achieve higher coverage The goal should not be a number (80%) The goal is ensuring correct behavior, output, etc.
  38. 38. Key Takeaways…
  39. 39. Gain confidence that code is “correct” Automated, repeatable, continuous (ARC) Tests cannot catch all problems Better design through “testable code” Build & change systems faster
  40. 40. (THE END)
  41. 41. Suggested Reading Clean Code, Robert “Uncle Bob” Martin Working Effectively with Legacy Code, Michael Feathers Pragmatic Programmer, Dave Thomas & Andy Hunt (20th anniversary edition in beta at https://pragprog.com/book/tpp20/the-pragmatic-programmer-20th-anniversary-edition)
  42. 42. Suggested Websites JUnit, de-factor Java unit testing framework, https://junit.org/junit5/ Mockito, mocking library, https://site.mockito.org AssertJ, fluent assertion library, https://joel-costigliola.github.io/assertj/ Awaitility, async testing library, https://github.com/awaitility/awaitility Jacoco, code coverage, https://www.jacoco.org/jacoco/
  43. 43. Boeing 737 MAX https://commons.wikimedia.org/wiki/File:WS_YYC_737_MAX_1.jpg https://creativecommons.org/licenses/by-sa/4.0/deed.en No changes made Photos & Images (All other images were purchased from iStock) 66MHz Pentium Chip with FDIV flaw https://en.wikipedia.org/wiki/Pentium_FDIV_bug#/media/ File:KL_Intel_Pentium_A80501.jpg Konstantin Lanzet [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/)] No changes made
  44. 44. Mars Climate Orbiter https://en.wikipedia.org/wiki/Mars_Climate_Orbiter#/media/ File:Mars_Climate_Orbiter_2.jpg Public domain Photos & Images (All other images were purchased from iStock)
  45. 45. My Info sleberknight at fortitudetec.com www.fortitudetec.com @sleberknight scott.leberknight at gmail

×