La scrittura di test automatici nello sviluppo software è ormai di fondamentale importanza, in quanto permette di:
1. Individuare e correggere molto prima, già in fase di sviluppo, i bug.
2. Sviluppare e testare più velocemente il codice, riducendo di molto le volte in cui bisogna ricorrere al debugger.
3. Essere molto più confidenti che una modifica fatta ad un "vecchio" pezzo di codice non "rompa" tutto il resto e non funzioni più niente (ovviamente scoprendolo quando ormai si è rilasciato in produzione!).
Questi sono "solo" 3 di una quindicina di benefici che sono riuscito ad elencare, ottenibili utilizzando una pratica durante lo sviluppo del codice: la scrittura di test automatici.
Con questo workshop vogliamo introdurre gli sviluppatori ai test automatici, una pratica purtroppo non ancora conosciuta e utilizzata quanto meriterebbe, che può cambiare radicalmente il modo con cui scriviamo il codice, portandolo verso un approccio più "ingegneristico".
Faremo una panoramica sulle varie tipologie di test e sui benefici che possono portare, approfondendo in particolare i test unitari (unit test) e d'integrazione (integration test).
I test automatici sono un argomento trasversale ai linguaggi di programmazione, perciò potrete seguire il workshop a prescindere da quale linguaggio utilizziate.
2. Tratto da una storia vera…
A QA engineer walks into a bar. Orders a beer.
Orders 0 beers. Orders 99999999999 beers.
Orders a lizard. Orders -1 beers. Orders a
ueicbksjdhd.
First real customer walks in and asks where the
bathroom is. The bar bursts into flames, killing
everyone.
4. About You
•Chi è
• Sviluppatore
• Tester
• Project Manager / Imprenditore / …
• Altro
•Chi scrive già test automatici?
•Chi sa cosa sono i test automatici?
•Chi non sa cosa sono?
5. About Your Company
Come considera la scrittura di test automatici?
•Ignora l’esistenza dell’argomento
•Importanti al pari (o più) dello sviluppo
•Meno dello sviluppo, ma comunque importanti
•Superflui
•Dannosi
9. “A first major mistake
people make is thinking
that the testing team is
responsible for assuring
quality”
–Brian Marick
Developer, Tester e Utenti:
i Developer sono i primi a poter
accorgersi dei problemi e a poterli
correggere
20. Tipi di test
• Unit testing
• Integration testing
• End-to-end testing / UI Testing
• Functional testing
• API testing
• Property Based Testing
• Mutation testing
• Smoke testing
• Acceptance testing
• Performance Testing
• Load testing
• Stress testing
• Security testing
• Usability testing
• Accessibility testing
• …
21. Tipi di test
• Unit testing
• Integration testing
• End-to-end testing / UI Testing
• Functional testing
• API testing
• Property Based Testing
• Mutation testing
• Smoke testing
• Acceptance testing
• Performance Testing
• Load testing
• Stress testing
• Security testing
• Usability testing
• Accessibility testing
• …
22. Metodologie
• TDD (Test Driven Development)
=> Red / Green / Refactor
• BDD (Behavior Driven Development)
=> Given / When / Then
• Test First
• ….
23. Metodologie
• TDD (Test Driven Development)
=> Red / Green / Refactor
• BDD (Behavior Driven Development)
=> Given / When / Then
• Test First
• ….
24.
25. Definizione di Unit Test (1/2)
A unit test is an automated piece of code
that invokes a unit of work in the system and
then checks a single assumption about the
behavior of that unit of work.
http://artofunittesting.com/definition-of-a-unit-test/
26. Definizione di Unit Test (2/2)
A unit of work is a single logical functional
use case in the system that can be invoked
by some public interface (in most cases). A
unit of work can span a single method, a
whole class or multiple classes working
together to achieve one single logical
purpose that can be verified.
http://artofunittesting.com/definition-of-a-unit-test/
27. Un buon Unit Test: (1/2)
1.Able to be fully automated
2.Has full control over all the pieces running
(Use mocks or stubs to achieve this isolation when needed)
3.Can be run in any order if part of many other tests
4.Runs in memory
(no DB or File access, for example)
5.Consistently returns the same result
(You always run the same test, so no random numbers, for
example. Save those for integration or range tests)
28. Un buon Unit Test: (2/2)
6.Runs fast
7.Tests a single logical concept in the system
8.Readable
9.Maintainable
10.Trustworthy
(when you see its result, you don’t need to debug the
code just to be sure)
29. VS
Tester knows about internals and
exploit that knowledge
Based on code analysis
•Statement coverage
•Branch coverage
•Condition coverage
•Basis path coverage
=> Cyclomatic complexity
Tester does not know anything about
the test object internal
Focuses on functional requirements
Based on input domain analysis
- Equivalence partitioning
- Boundary value analysis
30. Integration Test
• Usano una o più dipendenze “reali” del sistema testato
• real System Time (e.g. DateTime.Now),
• real File System
• real Database
• real Web Services
• Non veloci come gli Unit Test
• Non consistenti, possono ritornare valori diversi a
causa delle loro dipendenze (es. dal System Time)
31. Test End-to-End
Ensure that the integrated components of an application function as
expected. The entire application is tested in a real-world scenario such
as communicating with the database, network, hardware and other
applications.
For example, a simplified end-to-end testing of an email application might
involve:
• Logging in to the application
• Accessing the inbox
• Opening and closing the mailbox
• Composing, forwarding or replying to email
• Checking the sent items
• Logging out of the application
36. 1° step
Create a simple String calculator with a method int Add(string numbers)
1. The method can take 0, 1 or 2 numbers, and will return their sum (for an
empty string it will return 0) for example “” or “1” or “1,2”
2. Start with the simplest test case of an empty string and move to 1 and two
numbers
3. Remember to solve things as simply as possible so that you force yourself
to write tests you did not think about
4. Remember to refactor after each passing test
37. 2° step
Allow the Add method to handle
an unknown amount of numbers.
38. 3° step
Allow the Add method to handle new lines between numbers
(instead of commas).
the following input is ok: "1n2,3" (will equal 6)
the following input is NOT ok: "1,n" (not need to prove it - just
clarifying)
39. 4° step
Support different delimiters
1. to change a delimiter, the beginning of the string will contain
a separate line that looks like this: “//[delimiter]
n[numbers…]” for example “//;n1;2” should return 3 where
the default delimiter is ‘;’ .
2. the first line is optional. all existing scenarios should still be
supported
40. 5° step
Calling Add with a negative number will throw an exception
“negatives not allowed” - and the negative that was passed.
If there are multiple negatives, show all of them in the exception
message.