Unit Testing

Post on 16-Nov-2014

475 views 2 download

description

 

Transcript of Unit Testing

Unit Testing

Giacomo Petronio – O3 Enterprise

https://github.com/hijackit/swtesting

Intro

Software Testing:

◦ È una buona idea?

◦ Processo costoso

tempo, conoscenza

manutenzione

Vantaggi??

Perché (1) QA

Software Di Qualità!

◦ Correttezza, robustezza, affidabilità, …

◦ Manutenibilità evolutiva, correttiva, riusabilità

1 Bug meno qualità!

N Bug …

Perché (2)

Domanda: perché?

Risposta: per verificare che ‘funziona’.

Problema Programma (soluzione)

Problema risolto?

Funziona??

Troppo generico..

Quand’è che funziona?

Quando saprò se risolve il mio problema?

Si da per scontato che saremo in grado di dire se la nostra soluzione funziona

Quando funziona?

Soddisfa i requisiti

Insieme dei requisiti

Soluzione problema

Programma funziona

1° step: definizione dei requisiti

Contratto che il SW deve rispettare

I test possono essere considerati come un modo per catturare e implementare i requisiti

Requisiti e test

Una cosa sola

1 requisito 1+ test

1 requisito, 0 test == 0 requisiti

Categorie di test

Test di accettazione

(Stress test)

Test funzionali

Test di integrazione

Unit test

Criterio:

Oggetto sotto verifica

Scopo della verifica

Unit test

Scopo: “funziona”?

Oggetto: singola classe

Altre caratteristiche:

◦ Code coverage

Unit test

API Design

Documentazione vivente

Unit test

Refactoring

Code confidence

Regression testing

Definire Unit Test

Non dovrebbe

◦ Comunicare con DBMS/rete/filesystem

◦ Aver bisogno di un ambiente configurato

Dovrebbe essere

◦ Veloce

◦ Ripetibile

◦ Indipendente

Definire Unit Test

Meno pignoli!

◦ Può accedere a DBMS (in-memory dbms)

◦ Può accedere al filesystem

◦ Può accedere alla rete

Velocità Ripetibilità Indipendenza

xUnit

JUnit

CppUnit

NUnit

PHPUnit

PyUnit

Idea di base

La ricetta per un buon test

◦ Fixture (contesto)

◦ Test case

◦ Check

Kent Beck’s testing framework paper http://www.xprogramming.com/testfram.htm

JUnit

MyClassTest

◦ Fixture: @Before method

◦ Test Case: @Test method

◦ Check assert

ESEMPIO…

Best practices

N model classes N test classes

Assert precisi

assertTrue(shape.area != 0); assertTrue(shape.area == 50);

Best practices

White box / Black box

Process proc = new Process(); proc.start(); assertEquals(proc.status, Status.Running);

assertTrue(proc.isRunning());

Best practices

Come testare metodi privati ◦ non testare

◦ reflection

◦ cambiare visibilità

◦ (nested test-class)

Reflection Legacy code?

Non testare Codice nuovo?

Visibilità default

Nuova classe

Best practices

Nome classe

◦ TriangleTest

Package

◦ src/main/java/it/units/inginf/shapes

Triangle.class

Rectangle.class

◦ src/test/java/it/units/inginf/shapes

TriangleTest.class

RectangleTest.class

Best practices

Nome test-case (metodi)

◦ Verbosità è ok

test01(){ … } test02(){ … }

testAreaIsEmpty(){ … } testTriangleIsNotARectangle(){ … }

areaShouldBeEmpty(){ … } areaShouldBeExactly50(){ … } triangleShouldNotBeEqualToARectangle(){ … }

Best practices

Eccezioni

◦ Attributo expected

@Test(expected=IllegalArgumentException.class) invaldAddressShouldNotBeAccepted(){ WebClient client = new WebClient(“WRONG!”); }

@Test invaldAddressShouldNotBeAccepted(){ try{ WebClient client = new WebClient(“WRONG!”); fail(); } catch(IllegalArgumentException e){} }

Tecniche di testing

Classi di equivalenza e valori al confine

◦ Coprire tutti gli input

◦ Minimizzare la ridondanza

0 6 16 65

4€ 0€ 8€ 5€

5 test-case, uno per classe di equivalenza

8 test-case, uno per confine di ciascuna classe

Tecniche di testing

Esplorazione del grafo

◦ Macchine a stato

◦ Transazioni e stato interno

int left = 1; int right = 1; public void incLeft(){ left++; } public void incRight(){ right++; } public String getId(){ return left + “.” + right; }

Tecniche di testing

1:1

2:1

3:1 1:2

1:2

2:1 1:3

T1 T2

Stato iniziale X;Y X;Y

Evento incLeft incRight

Effetto X++ Y++

Stato finale X+1;Y X;Y+1

1° livello: 2 test-case 2° livello: 4 test-case 3° livello: 8 test-case …

T1 T2

Codice testabile

SOLID principles

◦ Single responsibility

◦ Open/Closed

Codice testabile

SOLID principles

◦ Liskov substitution

AClass { client.doGreatThings(); }

Client { … }

SubClient extends Client { … }

Codice testabile

SOLID principles

◦ Interface segregation

IDoOneThing { doOneThingA(); }

IDoManyThings { doThingA(); doThingB(); doThingC(); }

IDoAnotherThing { doOneThingB(); }

Codice testabile

SOLID principles

◦ Dependency inversion

class JapaneseGuy { playWith(PlayStation ps){ ps.play(); } }

class JapaneseGuy { playWith(IConsolle c){ c.play(); } }

Concrete, Abstract

Concrete Abstract

Esempio

MovieLister

+ moviesDirectedBy

<<Interface>> MovieFinder

+ findAll()

MovieFinderImpl <<crea>>

Classe concreta usa classe concreta

http://martinfowler.com/articles/injection.html

Testare una classe

Isolare la classe

◦ Individuare tutte le dipendenze

◦ Prendere il controllo (IoC)

Classe testabile

◦ Poche dipendenze

◦ Dipendenze astratte

Inversion Of Control (IoC)

Dipendenze vengono fornite

Diversi pattern

◦ Dependency Injection (DI)

MovieLister

<<Interface>> MovieFinder

MovieFinderImpl <<crea>>

Assembler <<crea>>

<<inject>>

IoC: Dependency Injection

Constructor injection

◦ Dipendenze esplicite

Setter injection

◦ Dipendenze meno esplicite

◦ Rende testabile classe esistente

Framework…

◦ Guice

◦ Spring

◦ CDI (J2EE 6)

IoC: Service Locator

MovieLister

<<Interface>> MovieFinder

MovieFinderImpl <<crea>>

ServiceLocator Assembler

<<crea>>

<<chiede>>

DI Framework: Guice

Es. servizio di pagamento

https://code.google.com/p/google-guice/wiki/Motivation

RealBillingService

<<Interface>> CreditCardProcessor

PaypalProcessor

<<Interface>> TransactionLog

DBTransactionLog

<<Interface>> BillingService

+ chargeOrder(order, creditCard)

Stub e Mock

Isolare la classe

Se ha dipendenze?

◦ Sostituirle con oggetti controllati

Stub

◦ Non hanno logica interna

◦ Comportamento sempre uguale

◦ Non si effettuano verifiche sugli stub

◦ Es. finta risorsa web

Stub e Mock

Mock

◦ Programmabile

Quando metodo riceve X Restituisci Y

Lancia eccezione

◦ Verifiche sui mock

Numero di chiamate ad un metodo

Parametro passato ad un metodo

Mocking library: Mockito

Mock lifecycle:

◦ Crea mock a partire da interfaccia

◦ Programma comportamento atteso

◦ Utilizzo indiretto (da parte del SUT*)

◦ Verifica dell’utilizzo

SUT = System Under Test, classe sottoposta a verifica

Mockito: esempio

MovieFinder finder = mock(MovieFinder.class) when(finder.findAll()).thenReturn(allMovies); MovieLister lister = new MovieLister(finder); Lister.moviesDirectedBy(“Martin Scorsese”); verify(finder).findAll(); // verifica la chiamata

ESEMPIO…

Mockito: possibilità MovieFinder finder = mock(MovieFinder.class) when(finder.findAll()).___________ .thenReturn(allMovies); .thenReturn(none, all); .thenThrows(new RuntimeException()); .then( callback ); MovieLister lister = mock(MovieLister.class) when(lister.moviesDirectedBy(_____)).then(…); “Martin Scorsese” anyString() any()

Mockito: spies

List list = new ArrayList(); List spy = spy(list); // calls real method! spy.add(“one”); spy.add(“two”); // verify verify(spy).add("one");

Utile per testare codice esistente

Test di risorse web

Esempio con Jetty (OnlineMovieFinder)

OnlineMovieFinder Risorsa web

Tester

Jetty Server

Servlet Stub

ESEMPIO…

Test Driven Development

Test first!

TDD mantra:

◦ RED

◦ GREEN

◦ REFACTOR

Test Driven Development

Ho un metodo calcolaX(a, b)

Ho bisogno di un test che verifica TUTTO!

Dati a, b vorrei ottenere X

Se a < 0, vorrei avere un errore

Se b == 0, vorrei…

1° test

2° test

3° test

Test Driven Development

What is the common, expected case?

What are some possible unusual cases?

How many external dependencies do I have?

What system failures could I reasonably encounter here?

http://www.codinghorror.com/blog/2005/04/good-test-bad-test.html

Costringe ad affrontare domande scomode

Costringe a pensare prima di scrivere

The real value of unit testing is that it forces you to stop and think about testing.