Slide 1

Slide 1 text

foolab.ca | @foolabca Unit Testing by Example php[tek], St. Louis - May 25, 2016

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Anna Filina • Developer • Problem solver • Teacher • Advisor • FooLab + ConFoo 3

Slide 4

Slide 4 text

You Don’t Become an Expert Overnight

Slide 5

Slide 5 text

You Don’t Start With 100% Coverage

Slide 6

Slide 6 text

Testing Without Automation

Slide 7

Slide 7 text

Step 1: Found Bug $item = new CartItem("Overwatch", 30); $item->setQuantity(0.1); $this->assertEquals(1, $item->getQuantity()); 7

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Regression Testing

Slide 10

Slide 10 text

Step 2: Improve Code $item = new CartItem("Overwatch", 30); $item->setQuantity(2); $cart->addItem($item); $this->assertEquals(0, $cart->getShipping()); 10

Slide 11

Slide 11 text

Step 2: Improve Code public function getShipping() { if ($this->subtotal >= 40) { return 0; } else { return 15; } } 11

Slide 12

Slide 12 text

Test Both Cases $item = new CartItem("Overwatch", 30); $item->setQuantity(1); $cart->addItem($item); $this->assertEquals(15, $cart->getShipping()); 12

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Step 3: New 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

Slide 15

Slide 15 text

Step 3: New Code $cart = new Cart(); $taxes = $cart->getApplicableTaxes(); $this->assertInternalType('array', $taxes); $this->assertCount(2, $taxes); $gst = $taxes[0]; $this->assertEquals(0.05, $gst['percent']); 15

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Data From CSV

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Don't Waste Time $total = 5; $this->assertNotNull($total); 20

Slide 21

Slide 21 text

How Many Cases? 21

Slide 22

Slide 22 text

Cyclomatic Complexity 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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. 27

Slide 28

Slide 28 text

Anna Filina • Development. • Fix bugs & performance issues. • Workshops on testing, frameworks & APIs. • Advisor on testing strategy, legacy code. 28

Slide 29

Slide 29 text

@afilina afilina.com joind.in