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

TDD anti patterns - episode 6 - with Ignacio Saporitti and Pablo Díaz

TDD anti patterns - episode 6 - with Ignacio Saporitti and Pablo Díaz

In this talk we are going to introduce two new TDD anti-patterns that came in our experience practicing TDD in different projects: The jumper and The flash.

Ed39ca0d44a6e6cdefc76ac548de5f41?s=128

Marabesi

May 26, 2022
Tweet

More Decks by Marabesi

Other Decks in Programming

Transcript

  1. TDD - EP 6 codurance.com Testing anti-patterns - The One,

    The Peeping Tom, The jumper and The flash
  2. Matheus Marabesi Hello there, you can call me Marabesi, But

    my name is Matheus Marabesi, I work at Codurance as a Software Craftsperson. I enjoy talking about anything related to: testing, patterns and gamification. You can find me at @MatheusMarabesi or https://marabesi.com Codurance Crafting Code
  3. 1. Intro - Recap 2. The One 3. The Peeping

    Tom 4. The Flash 5. The Jumper 6. Wrapping up Crafting code Agenda
  4. 1. Intro - Recap 2. The One 3. The Peeping

    Tom 4. The Flash 5. The Jumper 6. Wrapping up Crafting code Agenda
  5. 1. Recap Episode 1, Episode 2, Episode 3, Episode 4,

    Episode 5 Getting started
  6. The Liar The Giant The Mockery The Inspector Generous Leftovers

    The Local Hero The Nitpicker The Secret Catcher The Dodger The Loudmouth Anti patterns The Greedy Catcher Excessive Setup The Sequencer Hidden Dependency The Enumerator The Stranger The Operating System Evangelist Success Against All Odds The Free Ride The One The Peeping Tom The Slow Poke James Carr - TDD Anti-Patterns
  7. The Liar 4 The Giant 5 The Mockery 1 The

    Inspector 7 Generous Leftovers 5 The Local Hero 7 The Nitpicker 8 The Secret Catcher 7 The Dodger 8 The Loudmouth 8 Anti patterns The Greedy Catcher 7 Excessive Setup 3 The Sequencer 7 Hidden Dependency 2 The Enumerator 8 The Stranger 7 The Operating System Evangelist 8 Success Against All Odds 5 The Free Ride 8 The One 7 The Peeping Tom 7 The Slow Poke 6
  8. Anti patterns - Survey takeaways 1. Survey notes: Javascript, PHP

    and Java were the most used programming languages 2. Survey notes: Practitioners usually informally learn TDD 3. The anti patterns covered were related to test last 4. Subjects we touched around testability: SOLID, Object calisthenics, Non-determinism and the test pyramid 5. Examples are from open source projects and also extraction from real code bases
  9. MOST POPULAR

  10. None
  11. None
  12. MOST POPULAR

  13. 2. Anti-patterns - Episode 6 The One, The Peeping Tom,

    The jumper and The flash Getting started
  14. The Liar The Giant The Mockery The Inspector Generous Leftovers

    The Local Hero The Nitpicker The Secret Catcher The Dodger The Loudmouth Anti patterns The Greedy Catcher Excessive Setup The Sequencer Hidden Dependency The Enumerator The Stranger The Operating System Evangelist Success Against All Odds The Free Ride The One The Peeping Tom The Slow Poke James Carr - TDD Anti-Patterns
  15. The Liar 4 The Giant 5 The Mockery 1 The

    Inspector 7 Generous Leftovers 5 The Local Hero 7 The Nitpicker 8 The Secret Catcher 7 The Dodger 8 The Loudmouth 8 Anti patterns The Greedy Catcher 7 Excessive Setup 3 The Sequencer 7 Hidden Dependency 2 The Enumerator 8 The Stranger 7 The Operating System Evangelist 8 Success Against All Odds 5 The Free Ride 8 The One 7 The Peeping Tom 7 The Slow Poke 6
  16. 2. The One - 🏆 7 Crafting code

  17. 2. The One - 🏆 7 A combination of several

    patterns, particularly TheFreeRide and TheGiant, a unit test that contains only one test method which tests the entire set of functionality an object has. A common indicator is that the test method is often the same as the unit test name, and contains multiple lines of setup and assertions. Crafting code
  18. 2. The One - 🏆 7 A combination of several

    patterns, particularly TheFreeRide and TheGiant, a unit test that contains only one test method which tests the entire set of functionality an object has. A common indicator is that the test method is often the same as the unit test name, and contains multiple lines of setup and assertions. Crafting code
  19. 2. The One - 🏆 7 A combination of several

    patterns, particularly TheFreeRide and TheGiant, a unit test that contains only one test method which tests the entire set of functionality an object has. A common indicator is that the test method is often the same as the unit test name, and contains multiple lines of setup and assertions. Crafting code
  20. The giant A unit test that, although it is validly

    testing the object under test, can span thousands of lines and contain many many test cases. This can be an indicator that the system under tests is a God Object. Crafting code
  21. namespace PhpOffice\PhpWord\Shared; class ConverterTest extends \PHPUnit\Framework\TestCase { public function testUnitConversions()

    { $values = array(); $values[] = 0; // zero value $values[] = rand(1, 100) / 100; // fraction number $values[] = rand(1, 100); // integer foreach ($values as $value) { $result = Converter::cmToTwip($value); $this->assertEquals($value / 2.54 * 1440, $result); $result = Converter::cmToInch($value); $this->assertEquals($value / 2.54, $result); PHPUnit - PHPOffice/Word
  22. namespace PhpOffice\PhpWord\Shared; class ConverterTest extends \PHPUnit\Framework\TestCase { public function testUnitConversions()

    { $values = array(); $values[] = 0; // zero value $values[] = rand(1, 100) / 100; // fraction number $values[] = rand(1, 100); // integer foreach ($values as $value) { $result = Converter::cmToTwip($value); $this->assertEquals($value / 2.54 * 1440, $result); $result = Converter::cmToInch($value); $this->assertEquals($value / 2.54, $result); PHPUnit - PHPOffice/Word
  23. namespace PhpOffice\PhpWord\Shared; class ConverterTest extends \PHPUnit\Framework\TestCase { public function testUnitConversions()

    { $values = array(); $values[] = 0; // zero value $values[] = rand(1, 100) / 100; // fraction number $values[] = rand(1, 100); // integer foreach ($values as $value) { $result = Converter::cmToTwip($value); $this->assertEquals($value / 2.54 * 1440, $result); $result = Converter::cmToInch($value); $this->assertEquals($value / 2.54, $result); PHPUnit - PHPOffice/Word
  24. namespace PhpOffice\PhpWord\Shared; class ConverterTest extends \PHPUnit\Framework\TestCase { public function testUnitConversions()

    { $values = array(); $values[] = 0; // zero value $values[] = rand(1, 100) / 100; // fraction number $values[] = rand(1, 100); // integer foreach ($values as $value) { $result = Converter::cmToTwip($value); $this->assertEquals($value / 2.54 * 1440, $result); $result = Converter::cmToInch($value); $this->assertEquals($value / 2.54, $result); PHPUnit - PHPOffice/Word
  25. namespace PhpOffice\PhpWord\Shared; class ConverterTest extends \PHPUnit\Framework\TestCase { public function testUnitConversions()

    { $values = array(); $values[] = 0; // zero value $values[] = rand(1, 100) / 100; // fraction number $values[] = rand(1, 100); // integer foreach ($values as $value) { $result = Converter::cmToTwip($value); $this->assertEquals($value / 2.54 * 1440, $result); $result = Converter::cmToInch($value); $this->assertEquals($value / 2.54, $result); PHPUnit - PHPOffice/Word
  26. $result = Converter::cmToPixel($value); $this->assertEquals($value / 2.54 * 96, $result); $result

    = Converter::cmToPoint($value); $this->assertEquals($value / 2.54 * 72, $result); $result = Converter::cmToEmu($value); $this->assertEquals(round($value / 2.54 * 96 * 9525), $result); $result = Converter::inchToTwip($value); $this->assertEquals($value * 1440, $result); $result = Converter::inchToCm($value); $this->assertEquals($value * 2.54, $result); $result = Converter::inchToPixel($value); $this->assertEquals($value * 96, $result); PHPUnit - PHPOffice/Word
  27. $result = Converter::cmToPixel($value); $this->assertEquals($value / 2.54 * 96, $result); $result

    = Converter::cmToPoint($value); $this->assertEquals($value / 2.54 * 72, $result); $result = Converter::cmToEmu($value); $this->assertEquals(round($value / 2.54 * 96 * 9525), $result); $result = Converter::inchToTwip($value); $this->assertEquals($value * 1440, $result); $result = Converter::inchToCm($value); $this->assertEquals($value * 2.54, $result); $result = Converter::inchToPixel($value); $this->assertEquals($value * 96, $result); PHPUnit - PHPOffice/Word
  28. $result = Converter::cmToPixel($value); $this->assertEquals($value / 2.54 * 96, $result); $result

    = Converter::cmToPoint($value); $this->assertEquals($value / 2.54 * 72, $result); $result = Converter::cmToEmu($value); $this->assertEquals(round($value / 2.54 * 96 * 9525), $result); $result = Converter::inchToTwip($value); $this->assertEquals($value * 1440, $result); $result = Converter::inchToCm($value); $this->assertEquals($value * 2.54, $result); $result = Converter::inchToPixel($value); $this->assertEquals($value * 96, $result); PHPUnit - PHPOffice/Word
  29. $result = Converter::cmToPixel($value); $this->assertEquals($value / 2.54 * 96, $result); $result

    = Converter::cmToPoint($value); $this->assertEquals($value / 2.54 * 72, $result); $result = Converter::cmToEmu($value); $this->assertEquals(round($value / 2.54 * 96 * 9525), $result); $result = Converter::inchToTwip($value); $this->assertEquals($value * 1440, $result); $result = Converter::inchToCm($value); $this->assertEquals($value * 2.54, $result); $result = Converter::inchToPixel($value); $this->assertEquals($value * 96, $result); PHPUnit - PHPOffice/Word
  30. $result = Converter::cmToPixel($value); $this->assertEquals($value / 2.54 * 96, $result); $result

    = Converter::cmToPoint($value); $this->assertEquals($value / 2.54 * 72, $result); $result = Converter::cmToEmu($value); $this->assertEquals(round($value / 2.54 * 96 * 9525), $result); $result = Converter::inchToTwip($value); $this->assertEquals($value * 1440, $result); $result = Converter::inchToCm($value); $this->assertEquals($value * 2.54, $result); $result = Converter::inchToPixel($value); $this->assertEquals($value * 96, $result); PHPUnit - PHPOffice/Word
  31. $result = Converter::cmToPixel($value); $this->assertEquals($value / 2.54 * 96, $result); $result

    = Converter::cmToPoint($value); $this->assertEquals($value / 2.54 * 72, $result); $result = Converter::cmToEmu($value); $this->assertEquals(round($value / 2.54 * 96 * 9525), $result); $result = Converter::inchToTwip($value); $this->assertEquals($value * 1440, $result); $result = Converter::inchToCm($value); $this->assertEquals($value * 2.54, $result); $result = Converter::inchToPixel($value); $this->assertEquals($value * 96, $result); PHPUnit - PHPOffice/Word
  32. $result = Converter::inchToPoint($value); $this->assertEquals($value * 72, $result); $result = Converter::inchToEmu($value);

    $this->assertEquals(round($value * 96 * 9525), $result); $result = Converter::pixelToTwip($value); $this->assertEquals($value / 96 * 1440, $result); $result = Converter::pixelToCm($value); $this->assertEquals($value / 96 * 2.54, $result); $result = Converter::pixelToPoint($value); $this->assertEquals($value / 96 * 72, $result); $result = Converter::pixelToEmu($value); $this->assertEquals(round($value * 9525), $result); PHPUnit - PHPOffice/Word
  33. $result = Converter::inchToPoint($value); $this->assertEquals($value * 72, $result); $result = Converter::inchToEmu($value);

    $this->assertEquals(round($value * 96 * 9525), $result); $result = Converter::pixelToTwip($value); $this->assertEquals($value / 96 * 1440, $result); $result = Converter::pixelToCm($value); $this->assertEquals($value / 96 * 2.54, $result); $result = Converter::pixelToPoint($value); $this->assertEquals($value / 96 * 72, $result); $result = Converter::pixelToEmu($value); $this->assertEquals(round($value * 9525), $result); PHPUnit - PHPOffice/Word
  34. $result = Converter::inchToPoint($value); $this->assertEquals($value * 72, $result); $result = Converter::inchToEmu($value);

    $this->assertEquals(round($value * 96 * 9525), $result); $result = Converter::pixelToTwip($value); $this->assertEquals($value / 96 * 1440, $result); $result = Converter::pixelToCm($value); $this->assertEquals($value / 96 * 2.54, $result); $result = Converter::pixelToPoint($value); $this->assertEquals($value / 96 * 72, $result); $result = Converter::pixelToEmu($value); $this->assertEquals(round($value * 9525), $result); PHPUnit - PHPOffice/Word
  35. $result = Converter::inchToPoint($value); $this->assertEquals($value * 72, $result); $result = Converter::inchToEmu($value);

    $this->assertEquals(round($value * 96 * 9525), $result); $result = Converter::pixelToTwip($value); $this->assertEquals($value / 96 * 1440, $result); $result = Converter::pixelToCm($value); $this->assertEquals($value / 96 * 2.54, $result); $result = Converter::pixelToPoint($value); $this->assertEquals($value / 96 * 72, $result); $result = Converter::pixelToEmu($value); $this->assertEquals(round($value * 9525), $result); PHPUnit - PHPOffice/Word
  36. $result = Converter::inchToPoint($value); $this->assertEquals($value * 72, $result); $result = Converter::inchToEmu($value);

    $this->assertEquals(round($value * 96 * 9525), $result); $result = Converter::pixelToTwip($value); $this->assertEquals($value / 96 * 1440, $result); $result = Converter::pixelToCm($value); $this->assertEquals($value / 96 * 2.54, $result); $result = Converter::pixelToPoint($value); $this->assertEquals($value / 96 * 72, $result); $result = Converter::pixelToEmu($value); $this->assertEquals(round($value * 9525), $result); PHPUnit - PHPOffice/Word
  37. $result = Converter::inchToPoint($value); $this->assertEquals($value * 72, $result); $result = Converter::inchToEmu($value);

    $this->assertEquals(round($value * 96 * 9525), $result); $result = Converter::pixelToTwip($value); $this->assertEquals($value / 96 * 1440, $result); $result = Converter::pixelToCm($value); $this->assertEquals($value / 96 * 2.54, $result); $result = Converter::pixelToPoint($value); $this->assertEquals($value / 96 * 72, $result); $result = Converter::pixelToEmu($value); $this->assertEquals(round($value * 9525), $result); PHPUnit - PHPOffice/Word
  38. $result = Converter::degreeToAngle($value); $this->assertEquals((int) round($value * 60000), $result); $result =

    Converter::angleToDegree($value); $this->assertEquals(round($value / 60000), $result); } } PHPUnit - PHPOffice/Word
  39. public void testFlightMileage_asKm2() throws Exception { // set up fixture

    // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", Assertion Roulette - xUnit
  40. public void testFlightMileage_asKm2() throws Exception { // set up fixture

    // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", Assertion Roulette - xUnit
  41. public void testFlightMileage_asKm2() throws Exception { // set up fixture

    // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", Assertion Roulette - xUnit
  42. public void testFlightMileage_asKm2() throws Exception { // set up fixture

    // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", Assertion Roulette - xUnit
  43. public void testFlightMileage_asKm2() throws Exception { // set up fixture

    // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", Assertion Roulette - xUnit
  44. try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) {

    assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } Assertion Roulette - xUnit
  45. try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) {

    assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } Assertion Roulette - xUnit
  46. try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) {

    assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } Assertion Roulette - xUnit
  47. try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) {

    assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } Assertion Roulette - xUnit
  48. The Free Ride Rather than write a new test case

    method to test another feature or functionality, a new assertion rides along in an existing test case. Crafting code
  49. public class ToolLocationTest { @Rule public JenkinsRule j = new

    JenkinsRule(); @Test public void toolCompatibility() { Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); JDK[] jdk = j.jenkins.getDescriptorByType(JDK.DescriptorImpl.class).getInstallations(); assertEquals(Arrays.asList(jdk), j.jenkins.getJDKs()); assertEquals(2, jdk.length); // JenkinsRule adds a 'default' JDK assertEquals("default", jdk[1].getName()); // make sure it's really that we're seeing assertEquals("FOOBAR", jdk[0].getHome()); Java - Jenkins
  50. public class ToolLocationTest { @Rule public JenkinsRule j = new

    JenkinsRule(); @Test public void toolCompatibility() { Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); JDK[] jdk = j.jenkins.getDescriptorByType(JDK.DescriptorImpl.class).getInstallations(); assertEquals(Arrays.asList(jdk), j.jenkins.getJDKs()); assertEquals(2, jdk.length); // JenkinsRule adds a 'default' JDK assertEquals("default", jdk[1].getName()); // make sure it's really that we're seeing assertEquals("FOOBAR", jdk[0].getHome()); Java - Jenkins
  51. public class ToolLocationTest { @Rule public JenkinsRule j = new

    JenkinsRule(); @Test public void toolCompatibility() { Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); JDK[] jdk = j.jenkins.getDescriptorByType(JDK.DescriptorImpl.class).getInstallations(); assertEquals(Arrays.asList(jdk), j.jenkins.getJDKs()); assertEquals(2, jdk.length); // JenkinsRule adds a 'default' JDK assertEquals("default", jdk[1].getName()); // make sure it's really that we're seeing assertEquals("FOOBAR", jdk[0].getHome()); Java - Jenkins
  52. public class ToolLocationTest { @Rule public JenkinsRule j = new

    JenkinsRule(); @Test public void toolCompatibility() { Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); JDK[] jdk = j.jenkins.getDescriptorByType(JDK.DescriptorImpl.class).getInstallations(); assertEquals(Arrays.asList(jdk), j.jenkins.getJDKs()); assertEquals(2, jdk.length); // JenkinsRule adds a 'default' JDK assertEquals("default", jdk[1].getName()); // make sure it's really that we're seeing assertEquals("FOOBAR", jdk[0].getHome()); Java - Jenkins
  53. public class ToolLocationTest { @Rule public JenkinsRule j = new

    JenkinsRule(); @Test public void toolCompatibility() { Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); JDK[] jdk = j.jenkins.getDescriptorByType(JDK.DescriptorImpl.class).getInstallations(); assertEquals(Arrays.asList(jdk), j.jenkins.getJDKs()); assertEquals(2, jdk.length); // JenkinsRule adds a 'default' JDK assertEquals("default", jdk[1].getName()); // make sure it's really that we're seeing assertEquals("FOOBAR", jdk[0].getHome()); Java - Jenkins
  54. The automation server

  55. public class ToolLocationTest { @Test @LocalData public void shouldBeCompatibleWithMaven() {

    Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); } @Test @LocalData public void shouldBeCompatibleWithAnt() { Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); } @Test @LocalData Java - Jenkins
  56. public class ToolLocationTest { @Test @LocalData public void shouldBeCompatibleWithMaven() {

    Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); } @Test @LocalData public void shouldBeCompatibleWithAnt() { Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); } @Test @LocalData Java - Jenkins
  57. public class ToolLocationTest { @Test @LocalData public void shouldBeCompatibleWithMaven() {

    Maven.MavenInstallation[] maven = j.jenkins.getDescriptorByType(Maven.DescriptorImpl.class).getInstallations(); assertEquals(1, maven.length); assertEquals("bar", maven[0].getHome()); assertEquals("Maven 1", maven[0].getName()); } @Test @LocalData public void shouldBeCompatibleWithAnt() { Ant.AntInstallation[] ant = j.jenkins.getDescriptorByType(Ant.DescriptorImpl.class).getInstallations(); assertEquals(1, ant.length); assertEquals("foo", ant[0].getHome()); assertEquals("Ant 1", ant[0].getName()); } @Test @LocalData Java - Jenkins
  58. @Test @LocalData public void shouldBeCompatibleWithJdk() { JDK[] jdk = j.jenkins.getDescriptorByType(JDK.DescriptorImpl.class).getInstallations();

    assertEquals(Arrays.asList(jdk), j.jenkins.getJDKs()); assertEquals(2, jdk.length); // JenkinsRule adds a 'default' JDK assertEquals("default", jdk[1].getName()); // make sure it's really that we're seeing assertEquals("FOOBAR", jdk[0].getHome()); assertEquals("FOOBAR", jdk[0].getJavaHome()); assertEquals("1.6", jdk[0].getName()); } } Java - Jenkins
  59. Web automation

  60. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  61. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  62. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  63. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  64. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  65. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  66. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  67. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  68. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  69. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  70. it('Page.Events.RequestFailed', async () => { const { page, server, isChrome

    } = getTestState(); await page.setRequestInterception(true); page.on('request', (request) => { if (request.url().endsWith('css')) request.abort(); else request.continue(); }); const failedRequests = []; page.on('requestfailed', (request) => failedRequests.push(request)); await page.goto(server.PREFIX + '/one-style.html'); expect(failedRequests.length).toBe(1); expect(failedRequests[0].url()).toContain('one-style.css'); expect(failedRequests[0].response()).toBe(null); expect(failedRequests[0].resourceType()).toBe('stylesheet'); if (isChrome) expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED'); else expect(failedRequests[0].failure().errorText).toBe('NS_ERROR_FAILURE'); expect(failedRequests[0].frame()).toBeTruthy(); }); Javascript/Typescript - Puppeteer
  71. 3. The Peeping Tom - 🏆7 Crafting code

  72. 3. The Peeping Tom - 🏆7 A test that, due

    to shared resources, can see the result data of another test, and may cause the test to fail even though the system under test is perfectly valid. This has been seen commonly in fitnesse, where the use of static member variables to hold collections aren’t properly cleaned after test execution, often popping up unexpectedly in other test runs. Also known as TheUninvitedGuests Crafting code
  73. 3. The Peeping Tom - 🏆7 A test that, due

    to shared resources, can see the result data of another test, and may cause the test to fail even though the system under test is perfectly valid. This has been seen commonly in fitnesse, where the use of static member variables to hold collections aren’t properly cleaned after test execution, often popping up unexpectedly in other test runs. Also known as TheUninvitedGuests Crafting code
  74. None
  75. None
  76. public class MySingleton{ private static MySingleton instance; private String property;

    private MySingleton(String property) { this.property = property; } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(System.getProperty("com.example")); } return instance; } public Object getSomething() { return this.property; } } Java - Singleton
  77. public class MySingleton{ private static MySingleton instance; private String property;

    private MySingleton(String property) { this.property = property; } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(System.getProperty("com.example")); } return instance; } public Object getSomething() { return this.property; } } Java - Singleton
  78. public class MySingleton{ private static MySingleton instance; private String property;

    private MySingleton(String property) { this.property = property; } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(System.getProperty("com.example")); } return instance; } public Object getSomething() { return this.property; } } Java - Singleton
  79. public class MySingleton{ private static MySingleton instance; private String property;

    private MySingleton(String property) { this.property = property; } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(System.getProperty("com.example")); } return instance; } public Object getSomething() { return this.property; } } Java - Singleton
  80. public class MySingleton{ private static MySingleton instance; private String property;

    private MySingleton(String property) { this.property = property; } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(System.getProperty("com.example")); } return instance; } public Object getSomething() { return this.property; } } Java - Singleton
  81. public class MySingleton{ private static MySingleton instance; private String property;

    private MySingleton(String property) { this.property = property; } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(System.getProperty("com.example")); } return instance; } public Object getSomething() { return this.property; } } Java - Singleton
  82. public class MySingleton{ private static MySingleton instance; private String property;

    private MySingleton(String property) { this.property = property; } public static synchronized MySingleton getInstance() { if (instance == null) { instance = new MySingleton(System.getProperty("com.example")); } return instance; } public Object getSomething() { return this.property; } } Java - Singleton
  83. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  84. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  85. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  86. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  87. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  88. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  89. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  90. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton ✅
  91. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton
  92. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton ❌
  93. None
  94. class MySingletonTest { @BeforeEach public void resetSingleton() throws SecurityException, NoSuchFieldException,

    IllegalArgumentException, IllegalAccessException { Field instance = MySingleton.class.getDeclaredField("instance"); instance.setAccessible(true); instance.set(null, null); } } Java - Singleton
  95. class MySingletonTest { @BeforeEach public void resetSingleton() throws SecurityException, NoSuchFieldException,

    IllegalArgumentException, IllegalAccessException { Field instance = MySingleton.class.getDeclaredField("instance"); instance.setAccessible(true); instance.set(null, null); } } Java - Singleton
  96. class MySingletonTest { @BeforeEach public void resetSingleton() throws SecurityException, NoSuchFieldException,

    IllegalArgumentException, IllegalAccessException { Field instance = MySingleton.class.getDeclaredField("instance"); instance.setAccessible(true); instance.set(null, null); } } Java - Singleton
  97. class MySingletonTest { @BeforeEach public void resetSingleton() throws SecurityException, NoSuchFieldException,

    IllegalArgumentException, IllegalAccessException { Field instance = MySingleton.class.getDeclaredField("instance"); instance.setAccessible(true); instance.set(null, null); } } Java - Singleton
  98. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton ✅
  99. import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class MySingletonTest { @Test public

    void somethingIsDoneWithAbcIsSetAsASystemProperty(){ System.setProperty("com.example", "abc"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("abc"); } @Test public void somethingElseIsDoneWithXyzIsSetAsASystemProperty(){ System.setProperty("com.example", "xyz"); MySingleton singleton = MySingleton.getInstance(); assertThat(singleton.getSomething()).isEqualTo("xyz"); } } Java - Singleton ✅
  100. None
  101. None
  102. None
  103. None
  104. None
  105. None
  106. None
  107. The Liar 4 The Giant 5 The Mockery 1 The

    Inspector 7 Generous Leftovers 5 The Local Hero 7 The Nitpicker 8 The Secret Catcher 7 The Dodger 8 The Loudmouth 8 Anti patterns The Greedy Catcher 7 Excessive Setup 3 The Sequencer 7 Hidden Dependency 2 The Enumerator 8 The Stranger 7 The Operating System Evangelist 8 Success Against All Odds 5 The Free Ride 8 The One 7 The Peeping Tom 7 The Slow Poke 6
  108. The Liar 4 The Giant 5 The Mockery 1 The

    Inspector 7 Generous Leftovers 5 The Local Hero 7 The Nitpicker 8 The Secret Catcher 7 The Dodger 8 The Loudmouth 8 Anti patterns The Greedy Catcher 7 Excessive Setup 3 The Sequencer 7 Hidden Dependency 2 The Enumerator 8 The Stranger 7 The Operating System Evangelist 8 Success Against All Odds 5 The Free Ride 8 The One 7 The Peeping Tom 7 The Slow Poke 6
  109. • The One • The Peeping Tom What we covered

  110. • The One ◦ Anti patterns can be mixed between

    each other ◦ In open source projects it is usually a mix • The Peeping Tom What we covered
  111. • The One ◦ Anti patterns can be mixed between

    each other ◦ In open source projects it is usually a mix • The Peeping Tom ◦ Once again, avoid global state What we covered
  112. 4. The flash ⚡ Crafting code

  113. 4. The flash ⚡ Developers that gets blocked trying to

    practice TDD, and before splitting up the test in smaller chunks, they are thinking about all the edge cases that the test would cover. This can lead to another anti patterns itself. Crafting code
  114. Test methods should be easy to read, pretty much straight

    line code. If a test method is getting long and complicated, then you need to play "Baby Steps." Kent Beck - TDD by example
  115. Focuses on generalization or performance issues from the start The

    flash
  116. Aggregates It potentially leads to a combination of different anti-patterns,

    like The One The flash
  117. 5. The jumper Crafting code

  118. 5. The jumper The practice of trying to follow the

    test driven development approach, but jumping up to the next steps of the flow before completing the one before. Crafting code
  119. Tdd loop here (and potentially share the xp meetup)

  120. Tdd loop here (and potentially share the xp meetup) Trying

    to make it "perfect" from the start
  121. Tdd loop here (and potentially share the xp meetup) Trying

    to make it "perfect" from the start Get blocked by not knowing what to code
  122. Tdd loop here (and potentially share the xp meetup) -

    Refactor on the red - Changing class name - Fixing styles (any kind of style) - Changing files that are not related to the test Trying to make it "perfect" from the start Get blocked by not knowing what to code
  123. Tdd loop here (and potentially share the xp meetup) -

    Refactor on the red - Changing class name - Fixing styles (any kind of style) - Changing files that are not related to the test Trying to make it "perfect" from the start Get blocked by not knowing what to code
  124. Tdd loop here (and potentially share the xp meetup) Not

    trusting the hard coded ("I know it will pass")
  125. Tdd loop here (and potentially share the xp meetup) Making

    changes that break the tests
  126. 6. Wrapping up We are almost done! Crafting code

  127. • The One • The Peeping Tom • The flash

    • The jumper What we covered
  128. https://www.codurance.com/publications/building-testing-culture https://www.codurance.com/publications/tdd-anti-patterns-chapter-1

  129. https://www.codurance.com/publications/building-testing-culture https://www.codurance.com/publications/building-testing-culture

  130. https://www.codurance.com/events

  131. Matheus Marabesi Hello there, you can call me Marabesi, But

    my name is Matheus Marabesi, I work at Codurance as a Software craftsperson. I enjoy talking about anything related to: testing, patterns and gamification. You can find me at @MatheusMarabesi or https://marabesi.com Codurance Crafting Code