$30 off During Our Annual Pro Sale. View Details »

Unit Testing By Example

Unit Testing By Example

Everyone tells you that you need to test. You know the theory, but you don't know where to begin. What to test? What cases to write? Through realistic and pragmatic examples, this presentation will take you away from var_dump and ease you into the testing business until you're ready to do TDD. All this without losing sight of the tight deadlines.

Anna Filina
PRO

August 22, 2015
Tweet

More Decks by Anna Filina

Other Decks in Programming

Transcript

  1. foolab.ca | @foolabca
    Unit Testing
    by Example
    FrOSCon, Sankt Augustin - August 22, 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.05
    1 =>
    array (size=2)
    'name' => string 'QST' (length=3)
    'percent' => float 0.09975
    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.05, $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
    22

    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. Anna Filina
    • Development: PHP, JS, etc.
    • Fix problems: bugs, performance, etc.
    • Workshops: testing, Symfony, AngularJS, API, etc.
    • Advisor: testing strategy, legacy code, etc.
    27

    View Slide

  28. @afilina afilina.com

    View Slide