Test-Driven Development

Tim Schraepen & Wouter Groeneveld
30/01/2017
https://wgroeneveld.github.io/tdd-course/

Pre-requirements: installaties

PHP

	echo @php "%~dp0phpunit.phar" %* > phpunit.cmd
					
Java
Een editor
VSCode of Sublime of Atom

Introductie

Wouter

Prato, brood bakken, PXL, ...

Tim

Cegeka, LeanCoffee Leuven, PXL, ...

Doel

  • Jullie zelfzeker maken in TDD
  • Zodat jullie dit kunnen overbrengen aan jullie leerlingen
  • Door middel van TDD in jullie lessen te verwikkelen
9:10Laptop setup double check
9:20Unit Testing
10:00Oefening: Basic Unit testing (JS)
11:00Unit Testing en TDD
11:10Oefening: Legacy Code 1 (PHP)
11:30Code Retreat!
12:00Lunch
13:30Soorten testen
14:00Oefening: Integrated TDD (Java)
16:50Wat hebben we geleerd?

TDD Deel 1:
Unit testing

Wat is Unit Testing

  • Test Harnas
        bvb. JUnit, MSTest
  • Assertion Framework
       bvb. Assert.That(expected).IsEqualTo(actual);
  • TDD

Waarom unit testen?

Waarom unit testen?

  • Early Feedback!
  • Denk in code vanuit API standpunt
  • Makkelijk voor pair om te volgen
  • Alle mogelijke paden gedekt
  • Documentatie

Oefening: basic testing in Javascript

makkelijk genoeg voor alle niveau's

Oefening 1: speculaas

Unit testing in JS

jasmine logo


		describe("A suite", function() {
		  it("contains spec with an expectation", function() {
		    expect(true).toBe(true);
		  });
		});
						
Beschrijft gedrag
C# equiv.: Assert.That(true).IsEqualTo(true);

Unit testing in JS

Hoe runnen? runtests.html
how to run JS tests

Eigenschappen van een goede test

  • Ontdek sneller bugs
  • Leesbaar
  • Geautomatiseerd
  • Snel & gefocuset (test 1 ding)
  • Herhaalbaar
  • Volgorde onafhankelijk
  • Losgekoppeld van de implementatie
  • Productie code makkelijker wijzigbaar (aanpasbaarheid en design)

Geautomatiseerd


Travis CI org. + GitHub live demo

Geautomatiseerd: build lifecycle


Living Documentation

NIET Losgekoppeld van implementatie!

Test Driven Development (TDD)

En wat is refactoring?

Structuur veranderen,
zonder inhoud te wijzigen!

Voel jij je veilig genoeg zonder testen?

TDD: "bugfix" edge case

Live Demo in C#

Unit testing in C#

nunit logo


	[TestFixture]
	public class MyTestClass {

		[Test]
		public void SomeMethodShouldReturnTrueIfSomeCondition() {
			var result = SomeMethod();
			Assert.That(result, Is.EqualTo(expected));
		}

	}
						

Unit testing in C#

Gebruik tools van IDE:
how to run CSharp tests

Resharper Documentation

Oefening: Legacy code in PHP

Legacy Code oefening
my code is working, I don't know why?

Unit Testing in PHPUnit

https://phpunit.de/manual/


    public function testStub()
    {
        $mock = $this->createMock(SomeClass::class);
        $mock->method('doSomething')->willReturn('foo');

        $this->assertEquals('foo', $mock->doSomething());
    }
						

Unit Testing in PHP

Hoe runnen?
phpunit [dir]
phpunit dir/testfile.php

PHPUnit 4.3.5 by Sebastian Bergmann.

.......................

Time: 105 ms, Memory: 2.75Mb

OK (23 tests, 25 assertions)
							

 

Code Retreat oefening

Java
JavaScript
C# .NET
PHP

»  Mob Timer

  • Write exactly one new test. It should be the smallest test which seems to point in the direction of a solution
  • Run the test to make sure it fails
  • Make the test from (1) pass by writing the least amount of implementation code you can IN THE TEST METHOD.
  • Refactor to remove duplication or otherwise as required to improve the design. Be strict about the refactorings. Only introduce new abstractions (methods, classes, etc) when they will help to improve the design of the code.
Specifically:
  • ONLY Extract a new method if there is sufficient code duplication in the test methods. When extracting a method, initially extract it to the test class (don't create a new class yet).
  • ONLY create a new class when a clear grouping of methods emerges and when the test class starts to feel crowded or too large.
Repeat the process by writing another test (go back to step #1).

Soorten testen

 

Unit Testing

  • Onafhankelijk van externen (db, webservice, ...)
  • Snel!
  • Véél testen
  • Test Happy Path & Edge Cases
  • "Actieve vijand van de code"

Integration Testing

  • Test geïntegreerd met externen (db, webservice, ...)
  • Test integratie twee verschillende lagen
  • Trager dan unit tests
  • Minder test cases

Integration Testing

Test doubles

Integration Testing

  • Mocks
  • Stubs
  • Spies

Details: zie Mocks aren't stubs by Martin Fowler.

End to End Testing

  • Test hele applicatie!
  • niet alle limieten
  • traag, moeilijker onderhoudbaar
  • Test integratie alle lagen

Voorbeeldje/demo

Eventueel mee volgen in
tdd-course/labs/integrationtest-livedemo

Oefening: Integrated TDD met Java

En nu is het aan jullie!

Om jullie te helpen om sneller te ontwikkelen:
Shortcuts cursus met IntelliJ
ReSharper cheat sheet keymap

Unit Testing in Java

http://junit.org/junit4/javadoc/latest/
http://joel-costigliola.github.io/assertj/


    import static org.assertj.core.api.Assertions.assertThat;

    @Test
    public void methodShouldReturnTrueIfBehaviourCorrect()
    {
    	bool result = method();
        assertThat(result).isTrue();
    }
						

Unit Testing in Java

Hoe runnen? Gebruik tools van IDE:
How to run java tests

Resources

Boeken

Growing Object-Oriented Software Guided by Tests

Boeken

Clean Code

Boeken

Working Effectively With Legacy Code

Wat hebben we geleerd?

Tim en Wouter zijn BAZEN

Test Driven Development zorgt voor:

  • Beter design (loose coupling, single responsibility)
  • Leesbare code
  • Een vangnet voor Legacy code
Test Driven Development is...

  • ...helemaal niet zo scary!
  • ...toegankelijk voor studenten
  • ...zoals we het vandaag gezien hebben overdraagbaar op studenten