SlideShare a Scribd company logo
Unit Testing
Unit testing
Definitions and Best Practices
The Ideal testing pyramid
Source: martinfowler.com
Our testing pyramid
Source: agile faqs
Unit Test: a definition
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.
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.
Source: The art of unit testing
How is it different that an integration test?
An integration test usually is not in-memory: it may touch the disk file system, databases,
registry or other shared resources. It may read or need a configuration file of the file system,
whereas a unit test can be fully configured in-memory, for example.
An integration test will usually run much slower because it does not run in-memory.
An integration test can be less consistent – it may use threads or random number generators
so that the result of the test is not always consistent.
Source: Roy Osherove Blog
● Self-descriptive
● No conditional logic, No loops
● No exception handling
● Assertions & Assertion messages
● No test logic in production code
● Test code organization & structure
Unit test: best practices
● 3 Steps
● Fast
● Consistent
● Atomic & Isolated
● Single responsibility
● Environment isolation
● Classes isolation
● Fully automated
3 steps - AAA
● Setup
● Prepare an input
● Call a method
● Check an output
● Tear down
Fast
Frequent execution
● Several times per day [Test-after development]
● Several times per hour [Test driven development]
● Every few minutes [IDE - Execute after save]
Execution in groups
● 100 tests = Execution time x 100
● Weak link: a slow test slows the whole suite
Multiple invocations of the test should consistently return true or consistently return false, provided
no changes was made on code.
So we cannot:
DateTime currentDateTime = DateTime.Now;
int currentValue = new Random().Next();
We can use Mocks and Dependency Injection (DI)
Consistent
Atomic & Isolated
● Only two possible results: Pass or Fail
● No partial results
● Different execution order must yield same results.
● Test B should not depend on outcome of Test A
● Use Mocks instead of Dependencies
Single Responsibility
One test should be responsible for one scenario
So we test behavior not methods
● 1 methdod, n behaviors → n tests
● n methods, 1 behavior → 1 test
Environment Isolation
Unit tests should be isolated from an environmental influences
● Database
● Web services
● Environment variables
● Property files
● System date/time
Environment Isolation
In order to achieve Environment Isolation we use Mocks and Fakes
● Handwritten mock / fake objects
● Isolation Frameworks (RhinoMocks, NSubstitute etc)
Goals
● Minimal method calls in a test
● Minimal tests per method
● High code coverage
Anti-patterns
● Constrained test order
● Hidden test call
● Shared state corruption (bad set up or teardown, use of singletons or static instances)
Classes Isolation
Fully automated
Automated execution
Automated decision making (success or failure)
IDE Integration
Self-descriptive
A Unit test
● Is development level documentation
● Ensures that method specs are up to date
● Naming template: Method_Scenario_ExpectedBehavior() or Method_State_ExpectedBehavior()
● Test only one thing
● Meaningful assert message
● Separating Assert from Actions (Wrong: Assert.AreEqual(COULD_NOT_READ_FILE,log.GetLineCount("abc.txt"));)
No conditional logic, No loops
No conditional logic
● Conditional logic reveals different behavior
● All inputs should be known
● Expected output should be strictly defined
● Instead of “if” or “switch” we split into two or more tests
No loops
● If we need to repeat the test logic then it's too complicated
No Exception Handling
● Catch only the expected type of exception
● Fail test if expected exception is not caught
● Let all other exceptions uncaught
Assertions & Assertion messages
● Extend Assert with custom assertions (object comparer, repetitive conditions etc)
● Expressive message (reading the message only should be able to recognize the problem)
● Include business logic info (input values etc.)
● Consider assert messages as code documentation
No test logic in production code
Separate projects for production code and tests
Do not create methods/fields/properties only for testing
Dependency Injection
Test code organization & structure
● Source control
● File structure
○ One test class per feature or
○ One test class per class under test
● Test code structure
○ Abstractions
○ Inheritance
○ Template class
○ Generics
Unit Testing
Design prerequisites, pros & cons
Design for testability
● Make methods virtual
● Interface-based design
● Non Sealed classes
● Do not instantiate classes inside methods
● Do not call static methods directly
● Do not use static constructors
● Do not use construction logic
● Separate singletons and singleton holders
Pros
● Clean code
● Safer refactoring
● Decoupled code
● Documentation of requirements
● Cheaper maintenance
Cons
● Amount of work
● Complexity
● Exposing sensitive info
● Sometimes you can’t
Pros & cons
● The Liar (test passes but not really testing)
● Excessive Setup (might be integration test?)
● The Giant (alt to God Class)
● The Mockery (similar to Excessive Setup)
● The Inspector
● Generous Leftovers
● The Local Hero (dev environment dependencies)
● The Nitpicker (asseting unimportant details)
● The Secret Catcher
Unit Testing Anti-patterns
● The Sequencer (order dependency)
● Hidden Dependency
● The Enumerator (bad naming)
● The Stranger (not relative to the case)
● The Distant Relative
● The Operating System Evangelist
● Success Against All Odds
● The Free Ride (stuffing assertions)
● The One (Giant & Free Ride)
Unit Testing
Working with legacy code
Legacy code
Definition: Legacy code is the code without tests
The Legacy Code Dilemma:
When we change code, we should have tests in place. To put tests in place, we often
have to change code.
The Legacy Code Change Algorithm
1. Identify change points
2. Find test points
3. Break dependencies
4. Write tests
5. Make changes and refactor
Legacy code
Where to start adding tests?
Rate every component for
● Logical complexity
● Dependency level
● Priority
Legacy code
Easy-first approach Hard-first approach
Unit Testing
Real world examples
Isolation frameworks
Unit Testing Frameworks
Real world example: Unit
Real world example: Unit Test
Real world example: Unit Test
Here we can discuss about the need of this unit test and if the “unit” should follow the creative
or defensive programming strategy and trust the input or not!
Real world example: Unit
Dependencies
Before we test we must obviously isolate the unit from CookieHelper and TimeZoneInfo dependencies.
We can also safely refactor the unit by breaking it into two pieces.
A simple safe refactoring: extract method with Resharper
A simple safe refactoring: extract method with Resharper
Refactored methods
Breaking the dependencies with Dependency Injection
1) Use the Bridge design pattern to separate a class's interface from its
implementation so you can vary or replace the implementation without
changing the client code
Breaking the dependencies with Dependency Injection
Bridging the CookieHelper and TimeZoneInfo classes
Breaking the dependencies with Dependency Injection
2) Create a non-static DateExtensions class and Inject Dependencies
Finally: The Test
Scenario: date: 2/2/2011 23:55, timezone id: 55, expected result: 3/2/2011 1:55
Finally: The Test
Scenario: date: 2/2/2011 23:55, timezone id: empty, expected result: 3/2/2011 1:55
Resources
Thank you
Panagiotis Pnevmatikatos pnevmap@gmail.com

More Related Content

PDF
Unit testing best practices
PDF
Unit testing best practices with JUnit
PDF
Unit testing with Junit
PDF
Test driven development - JUnit basics and best practices
PPTX
PPTX
JUnit- A Unit Testing Framework
PDF
Unit testing with JUnit
PPS
JUnit Presentation
Unit testing best practices
Unit testing best practices with JUnit
Unit testing with Junit
Test driven development - JUnit basics and best practices
JUnit- A Unit Testing Framework
Unit testing with JUnit
JUnit Presentation

What's hot (20)

PPT
Automated Unit Testing
PPT
Software testing basics and its types
PPTX
.Net Unit Testing with Visual Studio 2010
PPSX
PPTX
Java Unit Testing
PPTX
Thread & concurrancy
PPTX
Best practices unit testing
PPTX
JUNit Presentation
PPTX
Introduction to JUnit
PPTX
Testing with Junit4
PPTX
Unit Testing with JUnit4 by Ravikiran Janardhana
PPTX
TestNG Session presented in PB
PPT
05 junit
PDF
PDF
TestNG vs. JUnit4
PPT
Junit and testNG
PPT
Simple Unit Testing With Netbeans 6.1
PPT
Unit testing with java
PPT
New Features Of Test Unit 2.x
PPTX
Test NG Framework Complete Walk Through
Automated Unit Testing
Software testing basics and its types
.Net Unit Testing with Visual Studio 2010
Java Unit Testing
Thread & concurrancy
Best practices unit testing
JUNit Presentation
Introduction to JUnit
Testing with Junit4
Unit Testing with JUnit4 by Ravikiran Janardhana
TestNG Session presented in PB
05 junit
TestNG vs. JUnit4
Junit and testNG
Simple Unit Testing With Netbeans 6.1
Unit testing with java
New Features Of Test Unit 2.x
Test NG Framework Complete Walk Through
Ad

Viewers also liked (12)

PDF
Ooorza.com
PDF
Factor_ETF_ServiceMark
PDF
Danzante Bay Golf Club
PPTX
öKoseep
DOCX
La mujer adúltera
PDF
PDF
VILLAGE REALTORS REFFERAL OPEN HOUSE MARCH 12 2016
PPTX
Thinking of Buying a Business?
PPT
Oyster Living Divino
PPTX
ENHANCING STUDENTS’ ATTITUDE AND MOTIVATION TOWARDS LEARNING AND USING ENGLIS...
PPTX
Types of maintenance of industrial pharmacy
PDF
Javaslang @ Devoxx
Ooorza.com
Factor_ETF_ServiceMark
Danzante Bay Golf Club
öKoseep
La mujer adúltera
VILLAGE REALTORS REFFERAL OPEN HOUSE MARCH 12 2016
Thinking of Buying a Business?
Oyster Living Divino
ENHANCING STUDENTS’ ATTITUDE AND MOTIVATION TOWARDS LEARNING AND USING ENGLIS...
Types of maintenance of industrial pharmacy
Javaslang @ Devoxx
Ad

Similar to Unit testing (20)

PPTX
Unit Testing and TDD 2017
PPTX
Unit testing
PPTX
Unit testing
PDF
An Introduction to Unit Test Using NUnit
PDF
Unit testing - An introduction
PPTX
Skillwise Unit Testing
PPTX
Building unit tests correctly with visual studio 2013
PPTX
Binary Studio Academy: .NET Code Testing
PPTX
TDD Best Practices
PPTX
Unit testing basics with NUnit and Visual Studio
PPTX
Unit tests and TDD
PPTX
Testing 101
PDF
Workshop unit test
PDF
What is Unit Testing_ - A Complete Guide.pdf
PDF
What is Unit Testing? - A Complete Guide
PPTX
Rc2010 tdd
PPTX
NET Code Testing
PPTX
Unit testing & TDD concepts with best practice guidelines.
PDF
What Is Unit Testing A Complete Guide With Examples.pdf
PDF
What Is Unit Testing_ A Complete Guide With Examples.pdf
Unit Testing and TDD 2017
Unit testing
Unit testing
An Introduction to Unit Test Using NUnit
Unit testing - An introduction
Skillwise Unit Testing
Building unit tests correctly with visual studio 2013
Binary Studio Academy: .NET Code Testing
TDD Best Practices
Unit testing basics with NUnit and Visual Studio
Unit tests and TDD
Testing 101
Workshop unit test
What is Unit Testing_ - A Complete Guide.pdf
What is Unit Testing? - A Complete Guide
Rc2010 tdd
NET Code Testing
Unit testing & TDD concepts with best practice guidelines.
What Is Unit Testing A Complete Guide With Examples.pdf
What Is Unit Testing_ A Complete Guide With Examples.pdf

Recently uploaded (20)

PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
medical staffing services at VALiNTRY
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
Digital Strategies for Manufacturing Companies
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Understanding Forklifts - TECH EHS Solution
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Nekopoi APK 2025 free lastest update
PPTX
Online Work Permit System for Fast Permit Processing
PDF
PTS Company Brochure 2025 (1).pdf.......
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
Odoo Companies in India – Driving Business Transformation.pdf
medical staffing services at VALiNTRY
Navsoft: AI-Powered Business Solutions & Custom Software Development
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Digital Strategies for Manufacturing Companies
Odoo POS Development Services by CandidRoot Solutions
How to Choose the Right IT Partner for Your Business in Malaysia
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
How Creative Agencies Leverage Project Management Software.pdf
Understanding Forklifts - TECH EHS Solution
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Design an Analysis of Algorithms I-SECS-1021-03
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Nekopoi APK 2025 free lastest update
Online Work Permit System for Fast Permit Processing
PTS Company Brochure 2025 (1).pdf.......
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Wondershare Filmora 15 Crack With Activation Key [2025

Unit testing

  • 3. The Ideal testing pyramid Source: martinfowler.com
  • 5. Unit Test: a definition 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. 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. Source: The art of unit testing
  • 6. How is it different that an integration test? An integration test usually is not in-memory: it may touch the disk file system, databases, registry or other shared resources. It may read or need a configuration file of the file system, whereas a unit test can be fully configured in-memory, for example. An integration test will usually run much slower because it does not run in-memory. An integration test can be less consistent – it may use threads or random number generators so that the result of the test is not always consistent. Source: Roy Osherove Blog
  • 7. ● Self-descriptive ● No conditional logic, No loops ● No exception handling ● Assertions & Assertion messages ● No test logic in production code ● Test code organization & structure Unit test: best practices ● 3 Steps ● Fast ● Consistent ● Atomic & Isolated ● Single responsibility ● Environment isolation ● Classes isolation ● Fully automated
  • 8. 3 steps - AAA ● Setup ● Prepare an input ● Call a method ● Check an output ● Tear down
  • 9. Fast Frequent execution ● Several times per day [Test-after development] ● Several times per hour [Test driven development] ● Every few minutes [IDE - Execute after save] Execution in groups ● 100 tests = Execution time x 100 ● Weak link: a slow test slows the whole suite
  • 10. Multiple invocations of the test should consistently return true or consistently return false, provided no changes was made on code. So we cannot: DateTime currentDateTime = DateTime.Now; int currentValue = new Random().Next(); We can use Mocks and Dependency Injection (DI) Consistent
  • 11. Atomic & Isolated ● Only two possible results: Pass or Fail ● No partial results ● Different execution order must yield same results. ● Test B should not depend on outcome of Test A ● Use Mocks instead of Dependencies
  • 12. Single Responsibility One test should be responsible for one scenario So we test behavior not methods ● 1 methdod, n behaviors → n tests ● n methods, 1 behavior → 1 test
  • 13. Environment Isolation Unit tests should be isolated from an environmental influences ● Database ● Web services ● Environment variables ● Property files ● System date/time
  • 14. Environment Isolation In order to achieve Environment Isolation we use Mocks and Fakes ● Handwritten mock / fake objects ● Isolation Frameworks (RhinoMocks, NSubstitute etc)
  • 15. Goals ● Minimal method calls in a test ● Minimal tests per method ● High code coverage Anti-patterns ● Constrained test order ● Hidden test call ● Shared state corruption (bad set up or teardown, use of singletons or static instances) Classes Isolation
  • 16. Fully automated Automated execution Automated decision making (success or failure) IDE Integration
  • 17. Self-descriptive A Unit test ● Is development level documentation ● Ensures that method specs are up to date ● Naming template: Method_Scenario_ExpectedBehavior() or Method_State_ExpectedBehavior() ● Test only one thing ● Meaningful assert message ● Separating Assert from Actions (Wrong: Assert.AreEqual(COULD_NOT_READ_FILE,log.GetLineCount("abc.txt"));)
  • 18. No conditional logic, No loops No conditional logic ● Conditional logic reveals different behavior ● All inputs should be known ● Expected output should be strictly defined ● Instead of “if” or “switch” we split into two or more tests No loops ● If we need to repeat the test logic then it's too complicated
  • 19. No Exception Handling ● Catch only the expected type of exception ● Fail test if expected exception is not caught ● Let all other exceptions uncaught
  • 20. Assertions & Assertion messages ● Extend Assert with custom assertions (object comparer, repetitive conditions etc) ● Expressive message (reading the message only should be able to recognize the problem) ● Include business logic info (input values etc.) ● Consider assert messages as code documentation
  • 21. No test logic in production code Separate projects for production code and tests Do not create methods/fields/properties only for testing Dependency Injection
  • 22. Test code organization & structure ● Source control ● File structure ○ One test class per feature or ○ One test class per class under test ● Test code structure ○ Abstractions ○ Inheritance ○ Template class ○ Generics
  • 24. Design for testability ● Make methods virtual ● Interface-based design ● Non Sealed classes ● Do not instantiate classes inside methods ● Do not call static methods directly ● Do not use static constructors ● Do not use construction logic ● Separate singletons and singleton holders
  • 25. Pros ● Clean code ● Safer refactoring ● Decoupled code ● Documentation of requirements ● Cheaper maintenance Cons ● Amount of work ● Complexity ● Exposing sensitive info ● Sometimes you can’t Pros & cons
  • 26. ● The Liar (test passes but not really testing) ● Excessive Setup (might be integration test?) ● The Giant (alt to God Class) ● The Mockery (similar to Excessive Setup) ● The Inspector ● Generous Leftovers ● The Local Hero (dev environment dependencies) ● The Nitpicker (asseting unimportant details) ● The Secret Catcher Unit Testing Anti-patterns ● The Sequencer (order dependency) ● Hidden Dependency ● The Enumerator (bad naming) ● The Stranger (not relative to the case) ● The Distant Relative ● The Operating System Evangelist ● Success Against All Odds ● The Free Ride (stuffing assertions) ● The One (Giant & Free Ride)
  • 28. Legacy code Definition: Legacy code is the code without tests The Legacy Code Dilemma: When we change code, we should have tests in place. To put tests in place, we often have to change code.
  • 29. The Legacy Code Change Algorithm 1. Identify change points 2. Find test points 3. Break dependencies 4. Write tests 5. Make changes and refactor
  • 30. Legacy code Where to start adding tests? Rate every component for ● Logical complexity ● Dependency level ● Priority
  • 31. Legacy code Easy-first approach Hard-first approach
  • 36. Real world example: Unit Test
  • 37. Real world example: Unit Test Here we can discuss about the need of this unit test and if the “unit” should follow the creative or defensive programming strategy and trust the input or not!
  • 38. Real world example: Unit Dependencies Before we test we must obviously isolate the unit from CookieHelper and TimeZoneInfo dependencies. We can also safely refactor the unit by breaking it into two pieces.
  • 39. A simple safe refactoring: extract method with Resharper
  • 40. A simple safe refactoring: extract method with Resharper
  • 42. Breaking the dependencies with Dependency Injection 1) Use the Bridge design pattern to separate a class's interface from its implementation so you can vary or replace the implementation without changing the client code
  • 43. Breaking the dependencies with Dependency Injection Bridging the CookieHelper and TimeZoneInfo classes
  • 44. Breaking the dependencies with Dependency Injection 2) Create a non-static DateExtensions class and Inject Dependencies
  • 45. Finally: The Test Scenario: date: 2/2/2011 23:55, timezone id: 55, expected result: 3/2/2011 1:55
  • 46. Finally: The Test Scenario: date: 2/2/2011 23:55, timezone id: empty, expected result: 3/2/2011 1:55