Good Unit Tests Ask For Quality
Code
Florin Coros
www.rabs.ro
florin.coros@rabs.ro
@florincoros
www.florincoros.wordpress.com
About me
RABS, Co-Founder
@florincoros
Agenda
• Good Unit Tests
• Code Quality
• How we get to code quality
• Demo: writing good UT & improving the code
Defining GOOD Unit Tests
Definition:
A unit test is an automated piece of code that
invokes the method or class being tested and
then checks some assumptions about the
logical behavior of that method or class.
A unit test is almost always written using a unit-
testing framework.
It’s fully automated, trustworthy, readable, and
maintainable.
Properties of GOOD Unit Tests
It is very small
It is automated and repeatable
It can be written easily
It runs quickly
It’s
readable, maintainable, trustwort
hy and fully automated
It should run in isolation
It should test ONE thing
If it fails you should know exactly
where the bug is
Good Unit Tests - easy to write
less than 5 minutes to implement
few lines of code. Less than 10 -15
see from a glimpse what the test checks
Good Unit Tests - Run in Isolation
Isolate the code under test
from the rest of your system,
by creating seams, to be able
to plug fakes (stubs & mocks)
which you can control in
your test
“There is no object-oriented
problem that cannot be
solved by adding a layer of
indirection, except, of
course, too many layers of
indirection.”
Good Unit Test - test ONE thing
Check only ONE thing in
your tests. If the test fails
you know exactly where the
problem is. You do not need
to do step-by-step
debugging
Dependencies and Fakes
An external dependency is an object in your system that
your code under test interacts with, and over which you
have no control. (Common examples are file
systems, threads, memory, time, and so on.)
A stub is a controllable replacement for an existing
dependency (or collaborator) in the system. By using a
stub, you can test your code without dealing with the
dependency directly.
A mock object is a fake object in the system that decides
whether the unit test has passed or failed. It does so by
verifying whether the object under test interacted as
expected with the fake object. There’s usually no more
than one mock per test.
Why Code Quality?
It works. Don’t touch it!
From Good Unit Tests to Code Quality
B
C
f()
g()
h()
h’()
Depend on abstractions not on implementation
details (DIP)
Use IoC for instantiating objects, or Factory
design patterns
Visible dependencies for our classes
Low coupling and high coherence
Extensibility, Reusability (OCP)
Design Patterns
Integration tests:
HIGH COSTS & LOW BENEFITS
From Good Unit Tests to Code Quality
Screen
Keyboard
translate()
write()
read()
Depend on abstractions not on implementation
details (DIP)
Use IoC for instantiating objects, or Factory
design patterns
Visible dependencies for our classes
Low coupling and high coherence
Extensibility, Reusability (OCP)
Design Patterns
Integration tests:
HIGH COSTS & LOW BENEFITS
From Good Unit Tests to Code Quality
IText
Output
IText
Input
translate()
write()
read()
Depend on abstractions not on implementation
details (DIP)
Use IoC for instantiating objects, or Factory
design patterns
Visible dependencies for our classes
Low coupling and high coherence
Extensibility, Reusability (OCP)
Design Patterns
Integration tests:
HIGH COSTS & LOW BENEFITS
From Good Unit Tests to Code Quality
OOD Principles
SOLID
DRY
IoC & DI
LowCoupling
High Coherence
…..…
Design Patterns
Composite
Chain Of Responsibility
Decorator
…….
Can you TEST it?
Good Enough
GOOD Unit Tests
Small
In Isolation
Test ONE Thing
Easy to implement
Reusability
Extensibility
Maintainability
Thank you!

Good Unit Tests Ask For Quality Code

  • 1.
    Good Unit TestsAsk For Quality Code Florin Coros www.rabs.ro florin.coros@rabs.ro @florincoros www.florincoros.wordpress.com
  • 2.
  • 3.
    Agenda • Good UnitTests • Code Quality • How we get to code quality • Demo: writing good UT & improving the code
  • 4.
    Defining GOOD UnitTests Definition: A unit test is an automated piece of code that invokes the method or class being tested and then checks some assumptions about the logical behavior of that method or class. A unit test is almost always written using a unit- testing framework. It’s fully automated, trustworthy, readable, and maintainable.
  • 5.
    Properties of GOODUnit Tests It is very small It is automated and repeatable It can be written easily It runs quickly It’s readable, maintainable, trustwort hy and fully automated It should run in isolation It should test ONE thing If it fails you should know exactly where the bug is
  • 6.
    Good Unit Tests- easy to write less than 5 minutes to implement few lines of code. Less than 10 -15 see from a glimpse what the test checks
  • 7.
    Good Unit Tests- Run in Isolation Isolate the code under test from the rest of your system, by creating seams, to be able to plug fakes (stubs & mocks) which you can control in your test “There is no object-oriented problem that cannot be solved by adding a layer of indirection, except, of course, too many layers of indirection.”
  • 8.
    Good Unit Test- test ONE thing Check only ONE thing in your tests. If the test fails you know exactly where the problem is. You do not need to do step-by-step debugging
  • 9.
    Dependencies and Fakes Anexternal dependency is an object in your system that your code under test interacts with, and over which you have no control. (Common examples are file systems, threads, memory, time, and so on.) A stub is a controllable replacement for an existing dependency (or collaborator) in the system. By using a stub, you can test your code without dealing with the dependency directly. A mock object is a fake object in the system that decides whether the unit test has passed or failed. It does so by verifying whether the object under test interacted as expected with the fake object. There’s usually no more than one mock per test.
  • 10.
  • 11.
  • 12.
    From Good UnitTests to Code Quality B C f() g() h() h’() Depend on abstractions not on implementation details (DIP) Use IoC for instantiating objects, or Factory design patterns Visible dependencies for our classes Low coupling and high coherence Extensibility, Reusability (OCP) Design Patterns Integration tests: HIGH COSTS & LOW BENEFITS
  • 13.
    From Good UnitTests to Code Quality Screen Keyboard translate() write() read() Depend on abstractions not on implementation details (DIP) Use IoC for instantiating objects, or Factory design patterns Visible dependencies for our classes Low coupling and high coherence Extensibility, Reusability (OCP) Design Patterns Integration tests: HIGH COSTS & LOW BENEFITS
  • 14.
    From Good UnitTests to Code Quality IText Output IText Input translate() write() read() Depend on abstractions not on implementation details (DIP) Use IoC for instantiating objects, or Factory design patterns Visible dependencies for our classes Low coupling and high coherence Extensibility, Reusability (OCP) Design Patterns Integration tests: HIGH COSTS & LOW BENEFITS
  • 15.
    From Good UnitTests to Code Quality OOD Principles SOLID DRY IoC & DI LowCoupling High Coherence …..… Design Patterns Composite Chain Of Responsibility Decorator ……. Can you TEST it? Good Enough GOOD Unit Tests Small In Isolation Test ONE Thing Easy to implement Reusability Extensibility Maintainability
  • 16.

Editor's Notes

  • #3 My name is Florin CorosI live in ClujAnd I am under 35I like to go to ROCK concertsI like to travel with my girl-friendI like to play GO. GO is a game that thought me to look a few steps ahead, which turned to be very useful for me…I tweet quite a lotI am a Software Architect at ISDCI am a big fan of Uncle BobI am one of the cofounders of RABS
  • #5 5’You need to make a clear distinction between an integration tests, and a unit testIt can be written easily and runs quickly.It’s fully automated, trustworthy, readable, and maintainable.Quality Attributes of Good Unit TestsReadableMaintainableTrustworthy
  • #6 You need to make a clear distinction between an integration tests, and a unit testIt can be written easily and runs quickly.It’s fully automated, trustworthy, readable, and maintainable.Quality Attributes of Good Unit TestsReadableMaintainableTrustworthy
  • #7 8’
  • #8 Flying people into space presents interesting challenges to engineersand astronauts, one of the more difficult being how to make sure theastronaut is ready to go into space and operate all the machinery. A fullintegration test for a space shuttle would require being in space, and that’sobviously not a safe way to test astronauts. That’s why NASA has fullsimulators that mimic the surroundings of a space shuttle’s control deck,which removes the external dependency of having to be in outer space.
  • #9 10’
  • #10 You need to make a clear distinction between an integration tests, and a unit testIt can be written easily and runs quickly.It’s fully automated, trustworthy, readable, and maintainable.Quality Attributes of Good Unit TestsReadableMaintainableTrustworthy
  • #11 11’ – Focusonly on the benefits. Short storyThe main benefit of code quality is that it REDUCE THE COST OF CHANGEChange is certain!Most of the time in our job we change existent code. We change code to add new features, because req change, because we missunderstood something, …The easier is to change it  the easier our job is  the more efficient we are  it costs us lessWe read a lot of code to find where certain behavior is implemented  we need to find our way in the codeRelated benefits - predictability of our changes or of how much it costs to add new features - efficiency: “The only way to go fast is to go well” - wellness and happiness
  • #12 It is working don’t touch it!Fragile code structureCHALLENGE: How to reach to a code structure which is not fragile and we can change easily and with higher predictability
  • #13 12’SOLID at workDesign patterns at workEach time you depend on something on which you have no control in your test you are doing an integration test!Integration tests are to be avoided because: - hard to write & maintain, depend on configurations  HIGH COSTS - not knowing where the cause of failure is (which code, is it bad config?), no benefits to your code quality  LOW BENEFITS
  • #14 SOLID at workDesign patterns at workEach time you depend on something on which you have no control in your test you are doing an integration test!Integration tests are to be avoided because: - hard to write & maintain, depend on configurations  HIGH COSTS - not knowing where the cause of failure is (which code, is it bad config?), no benefits to your code quality  LOW BENEFITS
  • #15 SOLID at workDesign patterns at workEach time you depend on something on which you have no control in your test you are doing an integration test!Integration tests are to be avoided because: - hard to write & maintain, depend on configurations  HIGH COSTS - not knowing where the cause of failure is (which code, is it bad config?), no benefits to your code quality  LOW BENEFITS
  • #16 14’All the discussion about whether the design principles and design patterns are being followed are summarized to ONE question