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

TDD For The Curious

TDD For The Curious

A lot has been said about TDD with the rise of the agile software development movement. However, it’s still confusing for both novice and experienced programmers. In my talk,
I’ll explain what TDD is all about, why we at Wix believe it’s beneficial (and crucial!), and how you can get started applying TDD in your teams and projects.

Amitay Horwitz

December 07, 2016
Tweet

More Decks by Amitay Horwitz

Other Decks in Programming

Transcript

  1. • TDD is not (only) about testing • TDD is

    not a waste of time (in the long run) • TDD != no design Common misconceptions
  2. TDD (Test Driven Development/Design) is a discipline for writing software,

    in which automated tests are written before the production code is written So what IS TDD?
  3. When practicing TDD it is forbidden to write a new

    line of code, unless it’s used to make a failing test pass! So what IS TDD?
  4. The term was coined by Kent Beck, and relates to

    XP methodologies which started in the late 1990s So what IS TDD? https://media.simplecast.com/episode/image/11199/thumb_1441192692-artwork.jpg
  5. • Fewer defects in production • Short feedback loop •

    Easier to get new people working on a project • Tests as documentation / specification ◦ “Truth can only be found in one place: the code.” - Uncle Bob Martin • No fear of changes and refactoring = less code rot • And more... I can blab about...
  6. • Write a failing test that checks a specific part

    of functionality • You must run the test! If the test passes then there’s (probably) something wrong with the test • A test should contain one logical assertion about the system (test one thing only) • Given / when / then mindset Red
  7. • Write the minimal amount of production code to make

    the failing test pass • Don’t try to implement the whole solution up-front - keep within the boundaries of the test • Make sure you don’t break other tests in the process. The rest of the test suite is your “safety net”, which allows you to make changes without fear Green
  8. • Once the test passes, you can cleanup the code

    you wrote • Identify code duplication and extract to methods / classes • Identify common patterns and introduce abstractions • Keep the tests passing in the process • Tests are also code! Refactor the tests as well • Continue to next iteration Refactor
  9. "viewed invoice" should { "have last viewed date" in {

    givenInvoiceWasSavedAndSent(invoice) givenInvoiceWasViewed(invoice, viewedAt = now) dao.getInvoices must contain(anInvoiceWithLastViewedDate(now)) } } What a typical test looks like (Specs²)
  10. • What should / shouldn’t I test? • How do

    I test this thing? • Many confusing terms ◦ Unit tests, integration tests, end-to-end tests, component tests, acceptance tests, mocks, stubs, fakes, spikes, ATDD, BDD, ... But it’s hard to get started
  11. Unit tests exercise individual objects or value types or small

    clusters of objects within in a single process Unit tests http://www.natpryce.com/articles/000772.html
  12. Integration tests verify that implementation on an abstraction that we

    own integrates with some third-party package correctly Integration tests http://www.natpryce.com/articles/000772.html
  13. System tests exercise the entire system end-to-end, driving the system

    through its published remote interfaces and user interface System / end-to-end tests http://www.natpryce.com/articles/000772.html
  14. As demonstrated in “Growing Object Oriented Software, Guided By Test”

    by Steve Freeman and Nat Pryce We like outside-in TDD http://www.growing-object-oriented-software.com/cover.jpg
  15. • Start from a failing end-to-end test ◦ Forces you

    to create the “walking skeleton” • Write code from the call site (wishful thinking) • Evolve your code by spotting the abstractions needed for solving your problems • Promotes YAGNI (You Ain’t Gonna Need It) Outside-in TDD
  16. • Add new functionality / features using TDD as much

    as you can. Untested code tends to be more coupled and harder to test • Try to write integration and end-to-end tests to verify the correctness of your software • When fixing bugs, try to first recreate them in some test • Once you feel confident enough, refactor out the problematic parts. You may never get to a state where everything is tested thoroughly Dealing with legacy code
  17. • For basic testing all you need is def assert(assertion:

    Boolean) = { if (!assertion) throw new AssertionError } • But it’s really helpful to have advanced features ◦ Ability to run only parts of the test suite ◦ Custom composable matchers • Many choices - Specs² (Scala), JUnit (Java), NUnit (C#), Jasmine (JavaScript), Midje (Clojure), ... Use decent tooling
  18. • TDD katas ◦ String calculator, bowling game, poker hands,

    FizzBuzz, prime factors, word wrap, natural sorting... ◦ Anything you want • Side projects ◦ https://github.com/amitayh/lispjs ◦ https://github.com/amitayh/scala-game-of-life ◦ https://github.com/amitayh/mano-machine-emulator ◦ https://github.com/amitayh/amd-compiler • Open source contributions Practice!
  19. • Requires discipline • Requires practice • The whole team

    has to be committed - you can’t do TDD by yourself • After initial investment - allows you to move and react to changes much quickly TDD is an investment
  20. More resources GOOS - Steve Freeman, Nat Pryce Clean Code

    - Robert C. Martin Refactoring - Martin Fowler TDD By Example - Kent Beck
  21. This is where you are going to present your final

    words. This slide is not meant to have a lot of text. Thank You! Any Questions? amitayhorwitz amitayh @amitayh [email protected]