Save ourselves with unit testing :)

67
Workshop for developers: save ourselves with unit testing :) Stefano Ottaviani XPUG Marche & DevMarche

description

 

Transcript of Save ourselves with unit testing :)

Page 1: Save ourselves with unit testing :)

Workshop for developers: save ourselves with unit testing :)

Stefano Ottaviani

XPUG Marche & DevMarche

Page 2: Save ourselves with unit testing :)

About MeContacts

Stefano Ottaviani

[email protected]

@ste8

Arcevia (AN) - Italy

Communities

DevMarche

XPUG Marche

DotNetMarche

UgiDotNet

DDD / CQRS

Work

Sales Force Automation

Warehouse logistic

Mobile

MonoTouch

Page 3: Save ourselves with unit testing :)

About You Who usually write tests?

Who knows about tests?

Tests? What??

Page 4: Save ourselves with unit testing :)

Our Mission

Spread testing practices among

developers

as a basic skill of professional developers

Page 5: Save ourselves with unit testing :)

A first major mistake people make is thinking that the testing team is responsible

for assuring quality.

Brian Marick

Page 6: Save ourselves with unit testing :)

Why software testing?And why automate it?

Page 7: Save ourselves with unit testing :)

1. Bug detection

reduce bugs in production code

Page 8: Save ourselves with unit testing :)

Is it "only" that?

Page 9: Save ourselves with unit testing :)

Exercise:Let’s introduce unit testing!

String Calculator Kataby Roy Osherove

Page 10: Save ourselves with unit testing :)

Unit test definition

by Roy Osherovehttp://artofunittesting.com/definition-of-a-unit-test/

Page 11: Save ourselves with unit testing :)

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.

Unit test definitionby Roy Osherove

Page 12: Save ourselves with unit testing :)

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).

Unit of work definition (1/2)

by Roy Osherove

Page 13: Save ourselves with unit testing :)

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.

Unit of work definition (2/2)

by Roy Osherove

Page 14: Save ourselves with unit testing :)

A good unit test is: (1/2) by Roy Osherove

Able to be fully automated Has full control over all the pieces running (use mocks or stubs to achieve this isolation when needed)

Can be run in any order if part of many other tests

Runs in memory (no DB or File access, for example)

Runs fast

Page 15: Save ourselves with unit testing :)

A good unit test is: (2/2) by Roy Osherove

Consistently returns the same result (you always run the same test, so no random numbers or DateTime.Now, for example. Save those for integration or range tests)

Tests a single logical concept in the system Readable Maintainable Trustworthy (when you see its result, you don’t need to debug the code just to be sure

Page 16: Save ourselves with unit testing :)

Some benefits…

Page 17: Save ourselves with unit testing :)

2. Faster development without debugging

no F5, login, go to the form, input data, …

Page 18: Save ourselves with unit testing :)

3. Regression test-suite

add features without breaking the old ones

Page 19: Save ourselves with unit testing :)

4. Instant, visual feedback

automated tests can be run as frequently as required

Page 20: Save ourselves with unit testing :)

5. Refactoring

improve the design without breaking ithttp://xpugmarche.blogspot.it/2009/04/2-meeting-sessione-di-refactoring.html

Page 21: Save ourselves with unit testing :)

White boxvs

Black box

testing

Page 22: Save ourselves with unit testing :)

White box testing Tester knows about internals and exploit that knowledge

Based on code analysis Statement coverage Branch coverage Condition coverage Basis path coverage => Cyclomatic complexity

Page 23: Save ourselves with unit testing :)

Black box testing Tester does not know anything about the test object internal

Focuses on functional requirements

Based on input domain analysis Equivalence partitioning

Boundary value analysis

Page 24: Save ourselves with unit testing :)

Equivalence partitioning (1/2)

A method having 4 integer input parameters with a 16-bit representation has an input domain of 264 different values => 264 different test cases

Equivalence partitioning is a black box testing method that divides the input domain of a program into classes of data from which test cases can be derived.

If an input condition specifies a range, one valid and two invalid equivalence classes are defined (invalid1 [--valid--] invalid2)

Page 25: Save ourselves with unit testing :)

Equivalence partitioning (2/2)

If an input condition requires a specific value, one valid (==) and two invalid (<, >) classes are defined.

If an input condition specifies a member of a set, one valid and one invalid equivalence class are defined.

If an input condition is boolean, one valid and one invalid class are defined

Page 26: Save ourselves with unit testing :)

Boundary value analysis (1/2)

Boundary value analysis is a test case design technique that complements equivalence partitioning.

In fact, a greater number of errors occurs at the boundaries of the input domain rather than in the "center".

The reason is that developers often concentrate on ordinary values and ignore "marginal" values.

Page 27: Save ourselves with unit testing :)

Boundary value analysis (2/2)

If an input condition specifies a range bounded by values a and b, test cases should be designed with values a and b as well as just above and just below a and b.

If an input condition specifies a number of values, test cases should be developed that exercise the minimum and maximum numbers. Values just above and below minimum and maximum are also tested.

If internal data structures have prescribed boundaries, be certain to design a test case to exercise the data structure at its boundary.

Page 28: Save ourselves with unit testing :)

6. Less "thinking" about boundary conditions

collections’ indexes, date ranges, …

Page 29: Save ourselves with unit testing :)

Exercise:Boundary Conditions

Reservations list

Page 30: Save ourselves with unit testing :)

Code coverage

Should I test 100% of my code?

Page 31: Save ourselves with unit testing :)

Naming conventions and structure

Page 32: Save ourselves with unit testing :)

Roy Osherove Way

Method: UnitOfWork_ScenarioUnderTest_ExpectedBehavior

public void Sum_simpleValues_Calculated ()

public void Sum_NegativeNumberAs1stParam_ExceptionThrown()

public void IsLoginOK_UserDoesNotExist_ReturnsFalse ()

http://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html

http://osherove.com/blog/2012/5/15/test-naming-conventions-with-unit-of-work.html

The Art of Unit Testing (book)

Page 33: Save ourselves with unit testing :)

AAA – Arrange, Act, Assert

Page 34: Save ourselves with unit testing :)

Nested class per methodhttp://haacked.com/archive/2012/01/01/structuring-unit-tests.aspx

Class Test Fixture

Page 35: Save ourselves with unit testing :)

Exercise:Let’s introduce

integration testing!

Events Webservice

Page 36: Save ourselves with unit testing :)

Exercise:mocks and stubs

Price Calculator

Page 37: Save ourselves with unit testing :)

Mocks: record and verify expectations

Stubs: do not verify expectations

Mocks aren’t StubsBy Martin Fowler

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

Page 38: Save ourselves with unit testing :)

Database integration strategies

Use of in-memory db such as Sqlite => NO GOOD!

Use of Transactions => less problemshttp://osherove.com/blog/2013/3/28/using-systemtransactionstransactionscope-to-rollback-databas.html

Libraries such as NDbUnit

Recap: http://lostechies.com/jimmybogard/2012/10/18/isolating-database-data-in-integration-tests/

Page 39: Save ourselves with unit testing :)

Some other benefits…

Page 40: Save ourselves with unit testing :)

7. No need to wait development of other components

(database tables, web services …)

thanks to Dependency Injection

Page 41: Save ourselves with unit testing :)

8. Better design

modularization, lower coupling,

SRP (Single responsibility principle)

Page 42: Save ourselves with unit testing :)

A possible tests classification

Unit testing

Integration testing

Validation testing: acceptance (end-to-end), alpha, beta, …

System testing: security, stress, recovery, …

Page 43: Save ourselves with unit testing :)

Caveat emptor

Page 44: Save ourselves with unit testing :)

No formal proof of correctness

you can't be sure to catch all errors

Page 45: Save ourselves with unit testing :)

Testing can never completely establish the correctness of arbitrary

computer software

Page 46: Save ourselves with unit testing :)

Testing shows the presence,

not the absence of bugs.

Edsger W. Dijkstra

Page 47: Save ourselves with unit testing :)

Beware of bugs in the above code;

I have only proved it correct, not tried it.

Donald Knuth

Page 48: Save ourselves with unit testing :)

Pitfalls of (bad) testsfragile, slow, do not test actual features

The Magic Tricks of Testing by Sandi Metz

http://bit.ly/ZwV4U3

@nusco said: after 12+ years of TDD, @sandimetz changed the way I conceptualize it

Page 50: Save ourselves with unit testing :)

9. Companion of code reviews

Page 51: Save ourselves with unit testing :)

"Classic" unit tesingvs

Test Firstvs

Test Driven Development - TDD

Page 52: Save ourselves with unit testing :)

Test First Same attitude of bug reproduction: first, put yourself in the "broken" situation

Who wants to write tests after code?

Page 53: Save ourselves with unit testing :)

TDD Test Driven Development

More on design than testing!

[ITA] Piergiuliano Bossi course on Youtube: http://bit.ly/1bPw9D7

Page 54: Save ourselves with unit testing :)

10. No writer block

specially with TDD

Page 55: Save ourselves with unit testing :)

11. Gain a client perspective

on how we should model

Page 56: Save ourselves with unit testing :)

12. Form of sample code and documentation

used by many open source libraries

Page 57: Save ourselves with unit testing :)

13. Continuous Integration

automated build including tests to detect errors as quickly as possible.

Page 58: Save ourselves with unit testing :)

All these brings to…

Page 59: Save ourselves with unit testing :)

14. Confidence…

Page 60: Save ourselves with unit testing :)

15. …fun and satisfaction!

Page 61: Save ourselves with unit testing :)

And tomorrow?Where do I start?

Will the boss permit… ?

Page 62: Save ourselves with unit testing :)

Test on languageswith dynamic typing(e.g. javascript)

Compilers are a kind of test!

Page 63: Save ourselves with unit testing :)

XP and testing

Page 64: Save ourselves with unit testing :)

Benefits Recap (1/2)

1.Bug detection

2.Faster development without debugging

3.Regression test-suite

4.Instant, visual feedback

5.Refactoring

6.Less "thinking" about boundary conditions

7.No need to wait development of other components (database, ...)

Page 65: Save ourselves with unit testing :)

Benefits Recap (2/2)

8.Better design

9.Companion of code reviews

10.No writer block

11.Gain a client perspective

12.Form of sample code and documentation

13.Continuous Integration

14.Confidence

15.Fun and satisfaction

Page 66: Save ourselves with unit testing :)

Some resources (1/2)

[ITA] "Unit Tests VS End to End Tests" (Domenico Musco) https://vimeo.com/33150685

"Magic Tricks of Testing" (Sandi Metz) http://bit.ly/ZwV4U3

@nusco said: after 12+ years of TDD, @sandimetz changed the way I conceptualize it

[ITA] TDD course by Piergiuliano Bossi: http://bit.ly/1bPw9D7

Page 67: Save ourselves with unit testing :)

Some resources (2/2)

The Art of Unit Testing with Examples in .NET, 2nd Edition (Roy Osherove) http://www.slideshare.net/royosherove/talk-2ndlookunittesting-copy

GOOS - Growing Object-Oriented Software Guided by Tests (Steve Freeman and Nat Pryce)

Test Driven Development By Example (Kent Back)