Testing

Esempi pratici con PHPUNIT

Matteo Galacci

Software architect & Back-end Developer

Github:  https://github.com/matiux

Slack GRUSP:  matiux

Email:  m.galacci@gmail.com

Linkedin: Matteo Galacci

https://github.com/matiux/ddd-utente-esempio-v2

Introduzione

  • Perchè li faccio
  • Tipi di test
  • Test driven design
  • Organizzazione codice
  • Builders
  • Gruppi di test
  • Database
  • Mock & Mockery

Perchè faccio i test

Vi racconto la mi esperienza diretta, per le best practices ci sono i libri.

Estremizzo il pragmatismo del testing, strizzando comunque l'occhio alla pulizia e al design.

  • Piccoli team di sviluppo o sviluppo in solitaria
  • Un collega virtuale
  • Self pair programming
  • Sviluppo non continuativo

Tipi di test

Testa come ti pare, ma testa!

Ma se vuoi essere essere figo quando vai alle conferenze...

  • Unit test
  • Integration test
  • End-to-end test

In un approccio pratico, anche uno solo di questi test potrebbe migliorare notevolmente la manutenibilità del software.

TIPI DI TEST

| UNIT TEST

Unit tests are low-level, focusing on a small part of the software system.

TIPI DI TEST

| Integration test

Integration tests determine if independently developed units of software work correctly when they are connected to each other.

TIPI DI TEST

| E2e test

Testing your deployed application via its user interface is the most end-to-end way you could test your application. End-to-end tests give you the biggest confidence when you need to decide if your software is working or not.

Test-Driven Development

Test-Driven Development (TDD) is a technique for building software that guides software development by writing tests. It was developed by Kent Beck in the late 1990's as part of Extreme Programming.

 

In essence you follow three simple steps repeatedly:

 

  • Write a test for the next bit of functionality you want to add.
  • Write the functional code until the test passes.
  • Refactor both new and old code to make it well structured.

Testa come ti pare, ma testa!
Scrivili quando ti pare, ma scrivili!

Organizzazione del codice

  • Il namespace dei test deve essere gestito con la stessa cura del software stesso.
  • Rapporto 1:1 tra le cartelle src/ e tests/
  • Dato il punto sopra, l'architettura esagonale ci fornisce un buono spunto per l'organizzazione del codice
  • Possono essere necessari strumenti e servizi accessori come Builders o Repository in memory

Testa come ti pare, ma testa!
Scrivili quando ti pare, ma scrivili!
Scrivili dove ti pare, ma da qualche parte mettili!

Organizzazione del codice

Test data builder

Test Data Builders are just normal Builders with default values used exclusively in your test suites so that you don’t have to specify irrelevant parameters on specific test cases.

 

Nella programmazione ad oggetti, il Builder è uno dei pattern fondamentali, definiti originariamente dalla Gang of Four. Il design pattern Builder, nella programmazione ad oggetti, separa la costruzione di un oggetto complesso dalla sua rappresentazione cosicché il processo di costruzione stesso possa creare diverse rappresentazioni.

 

I builder ci aiutano a velocizzare la scrittura di test in quanto grazie a loro, non dobbiamo più preoccuparci dei dati sui quali far girare i test.

Gruppi di test

PHPUnit ci da modo di "etichettare" ogni singolo test, categorizzandolo. In questo modo possiamo decidere di lanciare solo test unitari, piuttosto che i testo del modulo "utente"

phpunit --group unit, controllers
phpunit --exclue e2e

Database

I test dovrebbero lavorare su database solo su test end-to-end o al limite sui test di integrazione. Per tutto il resto, c'è la memoria. L'utilizzo di implementazioni in-memory dei repository potrebbe essere un buono spunto

I test devono essere atomici; ogni singola funzione di test deve avere i suoi dati e fare tutto senza dipendere da dati manipolati da altre funzioni. L'opzione process isolation di PHPUnit può essere utile.

Per mantenere l'atomicità, nei testi che utilizzano un database, a ogni test il db andrebbe svuotato. ORM Purger di doctrine potrebbe essere utile. In alternativa rendere i test transazionali. Vedere dama/doctrine-test-bundle 

Mock & Mockery

I mock object sono degli oggetti simulati che riproducono (simulano) il comportamento degli oggetti reali in modo controllato. Un programmatore crea un oggetto mock per testare il comportamento di altri oggetti, reali, ma legati ad un oggetto inaccessibile o non implementato. Allora quest'ultimo verrà sostituito da un mock.​

Mockery è un framework per la gestione di oggetti mock molto flessibile per l'uso in unit test con PHPUnit, PHPSpec o qualsiasi altro framework di test.