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

Unit Testing by Example

Unit Testing by Example

Everyone tells you that you need to write tests. You tried it, but your tests ended up not very useful and consumed valuable time. What to test? What conditions to write? Through realistic examples, this presentation will take you from var_dump() and ease you into the testing business. All this without losing sight of the tight deadlines. You will come out of this presentation with a renewed interest in writing unit tests.

Anna Filina
PRO

June 08, 2015
Tweet

More Decks by Anna Filina

Other Decks in Programming

Transcript

  1. foolab.ca | @foolabca
    Unit Testing
    by Example
    IPC, Berlin - June 8, 2015

    View Slide

  2. Anna Filina
    • Developer
    • Problem solver
    • Teacher
    • Advisor
    2

    View Slide

  3. Objectives
    • Make testing enjoyable.
    • Make it useful.
    • Reduce pre-release stress.
    3

    View Slide

  4. You don’t become an
    expert overnight

    View Slide

  5. You don’t start with
    100% coverage

    View Slide

  6. Testing Without
    Automation

    View Slide

  7. Step 1: found bug
    $item = new CartItem("Skyrim", 30);
    $item->setQuantity(0.1);
    $this->assertEquals(1, $item->getQuantity());
    7

    View Slide

  8. Step 1: found bug
    $item = new CartItem("Skyrim", 30);
    $item->setQuantity(0.1);
    $this->assertEquals(1, $item->getQuantity());
    public function setQuantity($qty)
    {
    $this->qty = ceil($qty);
    }
    8

    View Slide

  9. Regression Testing

    View Slide

  10. Step 2: improve code
    $item = new CartItem("Skyrim", 30);
    $item->setQuantity(2);
    $cart->addItem($item);
    $this->assertEquals(0, $cart->getShipping());
    $this->assertEquals(60, $cart->getTotal());
    10

    View Slide

  11. Step 2: improve code
    public function getShipping()
    {
    if ($this->getSubtotal() >= 40) {
    return 0;
    }
    else {
    return 15;
    }
    }
    11

    View Slide

  12. Test both cases
    $item = new CartItem("Skyrim", 30);
    $item->setQuantity(1);
    $cart->addItem($item);
    $this->assertEquals(15, $cart->getShipping());
    $this->assertEquals(45, $cart->getTotal());
    12

    View Slide

  13. Step 3: write code
    public function getTotal()
    {
    //...
    $taxes = $this->getApplicableTaxes();
    foreach ($taxes as $tax)
    {
    $total += $subtotal * $tax->getPercent();
    }
    //...
    }
    13

    View Slide

  14. Step 3: write code
    array (size=2)
    0 =>
    array (size=2)
    'name' => string 'GST' (length=3)
    'percent' => float 0.5
    1 =>
    array (size=2)
    'name' => string 'QST' (length=3)
    'percent' => float 0.9975
    14

    View Slide

  15. Step 3: write code
    $cart = new Cart();
    $taxes = $cart->getApplicableTaxes();
    $this->assertInternalType('array', $taxes);
    $this->assertCount(2, $taxes);
    $gst = $taxes[0];
    $this->assertEquals(0.5, $gst->getPercent());
    15

    View Slide

  16. Advantages
    • More tests.
    • Easy to write.
    • Never fall too far.
    16

    View Slide

  17. Data from CSV

    View Slide

  18. Step 4: before (TDD)
    $import = new CatalogImport();
    $products = $import->parseFromCsv('catalog.csv');
    $this->assertInternalType('array', $products);
    $this->assertCount(2, $products);
    $this->assertArrayHasKey('name', $products[0]);
    $this->assertArrayHasKey('price', $products[0]);
    18

    View Slide

  19. Tips
    • How it’s not supposed to work.
    • Plan for exceptions.
    • Focus on realistic scenarios.
    19

    View Slide

  20. Don't waste time
    $total = 5;
    $this->assertNotNull($total);
    20

    View Slide

  21. Recap
    • Testing takes practice
    • Write tests when you see
    a bug
    • Write tests when you
    improve code

    • Write tests as you write
    new code
    • Write tests before you
    write code
    • Test unexpected
    scenarios
    21

    View Slide

  22. Cyclomatic
    Complexity

    View Slide

  23. Execution Paths
    public function getShipping()
    {
    if ($this->subtotal >= 50) {
    return 0;
    }
    return $this->shipping;
    }
    23

    View Slide

  24. Example
    24
    start
    product loop free shipping? gift wrap?
    end

    View Slide

  25. Zero times
    foreach ($products as $product) {
    $total = $product->price * $product->quantity;
    }
    if ($total > 0) {
    echo 'found';
    }
    25

    View Slide

  26. Multiple times
    $total = 0;
    foreach ($products as $product) {
    $total = $product->price * $product->quantity;
    }
    if ($total > 0) {
    echo 'found';
    }
    26

    View Slide

  27. Services
    • Development: PHP, JS, etc.
    • Fix problems: bugs, performance, etc.
    • Workshops: testing, Symfony, AngularJS
    • Advisor: testing strategy, architecture, etc.
    27

    View Slide