unit testing - the hard parts

Post on 16-Feb-2017

817 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Shaun AbramBlog: shaunabram.comEmail: shaun@abram.comTwitter: @shaunabramLinkedIn: linkedin.com/in/sabram

Unit TestingThe hard parts

October 10th, 2015

Shaun Abram 2

Test Obsessed?

How much do you know…Test coverageDependency InjectionMock vs stubsTesting private or static methodsTest driven development

Shaun Abram 3

What is a unit test?

A piece of code that executes a specific functionality (‘unit’) in the code, andConfirms behavior or result is as expected

Determines if code is ‘fit for use’Does it do what the developer intended?

Before, we manually verified, but not easily repeatable.

Shaun Abram 4

Why unit test?

Economics $but also…

Drive design Create defensive code against bad input

Act as safety buffers for regression bugs

Provide documentationClean codeLess bugs

Shaun Abram 5

What is a unit?

A class? A method? A single path through a method?

The smallest testable part of an application. A single functional use case.

Shaun Abram 6

What makes a good unit test?Provides benefit!Readable, Understandable, Maintainable

Independent run in any order, no DB or File access

Consistent / deterministicRuns fastTests a single logical concept in the system

Shaun Abram 7

Unit testing limitations

Can not prove the absence of bugs

Lot’s of code (x3-5)

Some things difficult to test

Shaun Abram 8

Dependency Injection

9

10

Dependency Injection Useful for testing – inject test doubles Also helps reduce coupling

Shaun Abram 11

Test Doubles

MocksStubs

DummiesSpies

Fakes

Shaun Abram 12

Test Doubles

MocksStubs

DummiesSpies

Fakes

Shaun Abram 13

Test Doubles: Mocks

Mocks: An overloaded term!

uses behavior verificationobjects pre-programmed with expectations

14

15

Mocks use behavior verification Can specify how to respond when called Roll your own?

Shaun Abram 16

Test Doubles

MocksStubs

DummiesSpies

Fakes

Shaun Abram 17

Test Doubles: Stubs

‘stubs out’or provides a simplified version

of the implementation for the purposes of testing

18

19

Stubs can use state or behavior verification Provides a useful approach for test fixture configurability

Shaun Abram 20

Test Doubles

MocksStubs

DummiesSpies

Fakes

Shaun Abram 21

Test Doubles: DummiesA very dumb class! Contains next to nothing - enough to compile

Pass when you don’t expect to be used

22

Use dummies with state or behavior verification Can create as inner class Can replicate with mocks

Shaun Abram 23

Unit Testing – the tricky partsLegacy codePrivates Statics

Shaun Abram 24

General approach to testing legacy code

1) Start with coarse grained testsNo modificationsStrict and rigidDetect regressionsShort term bridges - delete

Shaun Abram 25

General approach to testing legacy code

1) Start with coarse grained tests2) Add finer grained tests Incrementally add more unit start gently refactoring Use TDD – if possibleTest from 1) should protect you

Shaun Abram 26

General approach to testing legacy code

1) Start with coarse grained tests2) Add finer grained tests3) Continuously refactorUse patterns such as Extract Method/ClassMove Method/Fieldtease apart methods (>10 lines smells)

Shaun Abram 27

Unit Testing – the tricky partsLegacy codePrivates Statics

Shaun Abram 28

How do you test private methods?

Indirectly! Best tested via public interface

But sometimes…Legacy code

With limited capability to refactor, or

adding a safety net before refactoring

A public method calls several private methods, each with complex logic

Shaun Abram 29

Testing Private Methods

1. Refactor2. Change the visibility

Bad practicePublic API? Very bad practice! Internal & stepping stone -> lesser evil

Java private -> package; .Net protected or internal?

Document (@VisibleForTesting)

Shaun Abram 30

Testing Private Methods

1. Refactor2. Change the visibility3. Use ReflectionNo code modification, but…4. Other options…

Testing frameworks InternalsVisibleToAttributePrivate Accessors

Shaun Abram 31

Testing static methods

32

33

34

Shaun Abram 35

Testing static methodsDI idealBut sometimes not pragmatic

36

37

Refactor to wrap the static call in an instance methodWhich can then be mocked…

38

39

40

Shaun Abram 41

Testing static methodsRefactor – use DIWrap static call in a instance methodUse a mocking framework?

Shaun Abram 42

Test Driven Development

Shaun Abram 43

Test Driven Development

Shaun Abram 44

Test Driven Development

Shaun Abram 45

Test Driven Development

Shaun Abram 46

Test Driven Development

Shaun Abram 47

Test Driven Development

Red - Green – Refactor: the TDD MantraNo new functionality without a failing test

No refactoring without passing tests

Shaun Abram 48

Test Driven Development Example…

Shaun Abram 49

Test Driven Development Example…

Create a StringCalculator class with an add method which takes a comma separate String of numbers and returns their sum.

Example input Result0

1 1

2 2

1,2 3

1,2,100 103

50

Refactor?

Refactor?

These tests act like the original developer looking over your shoulder and advising you, long after that developer has left…

These tests act like the original developer looking over your shoulder and advising you, long after that developer has left…

Shaun Abram 71

Recommended reading

Growing Object-Oriented Software, Guided by TestsFreeman & Pryce

Test Driven DevelopmentKent Beck

Refactoring: Improving the Design of Existing CodeMartin Fowler, Kent Beck et. al.

Effective Unit TestingLasse Koskela

Questions?

top related