unit testing - the hard parts
Post on 16-Feb-2017
816 Views
Preview:
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
Shaun Abram 72
Recommended reading
Unit Test Best Practices - https://wiki.tlcinternal.com/display/TD/Unit+Test+Best+Practices
Mocks Arent Stubs - http://www.martinfowler.com/articles/mocksArentStubs.html
Questions?
top related