Unit testing best practices
-
Upload
nickokiss -
Category
Technology
-
view
25.020 -
download
0
description
Transcript of Unit testing best practices
![Page 1: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/1.jpg)
www.nickokiss.com
![Page 2: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/2.jpg)
Code
Production code
Tests code
Purpose: Meet business (functional) requirementsMeet non-functional (system) requirements
Purpose: TestingDocumentationSpecification
![Page 3: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/3.jpg)
Code
Production code
Tests code
Purpose: Meet business (functional) requirementsMeet non-functional (system) requirements
Purpose: TestingDocumentationSpecification
Differentpurpose
Different best practices=
![Page 4: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/4.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 5: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/5.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 6: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/6.jpg)
3 steps
Prepare an input
Call a method
Check an output
![Page 7: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/7.jpg)
3 steps (5 steps)
Set up
Prepare an input
Call a method
Check an output
Tear down
![Page 8: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/8.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 9: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/9.jpg)
Execution time - be fast
Frequent executionSeveral times per day [Test-after development]Several times per hour [Test driven development]Every few minutes [IDE - Execute after save]
Execution in groups10 tests = Execution time x 10100 tests = Execution time x 100Weak link: a slow test slows the whole suite
Why is it so important?
![Page 10: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/10.jpg)
Execution time - be fast
Expected average execution time in unit testingSingle test: <200ms Small suite: <10s All tests suite: <10min
What are the good numbers?
![Page 11: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/11.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 12: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/12.jpg)
Consistent
Multiple invocations of the test should consistently return true or consistently return false, provided no changes was made on code.
What code can cause problems?
Date currentDate = new Date();
int value = random.nextInt(100);
How to deal with this?MocksDependency injection
![Page 13: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/13.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 14: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/14.jpg)
Atomic
Only two possible results: Pass or FailNo partially successful tests A test fails -> The whole suite failsBroken window effect
![Page 15: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/15.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 16: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/16.jpg)
Single responsibility
One test should be responsible for one scenario only.
Test behaviour, not methods:
One method, multiple behaviours Multiple tests
One behaviour, multiple methods One test
A method calls private and protected methodsA method calls very simple public methods
(Especially: getters, setters, value objects, simple constructors)
Multiple asserts in the same test - acceptable as long as they check the same behaviour
![Page 17: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/17.jpg)
Single responsibilityOne method, multiple behaviours
testMethod(){ ... assertTrue(behaviour1); assertTrue(behaviour2); assertTrue(behaviour3); }
testMethodCheckBehaviour1(){ ... assertTrue(behaviour1);}testMethodCheckBehaviour2(){ ... assertTrue(behaviour2);}testMethodCheckBehaviour3(){ ... assertTrue(behaviour3);}
![Page 18: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/18.jpg)
Single responsibilityBehaviour1 = condition1 + condition2 + condition3Behaviour2 = condition4 + condition5
testMethodCheckBehaviours(){ ... assertTrue(condition1); assertTrue(condition2); assertTrue(condition3); ... assertTrue(condition4);assertTrue(condition5); }
testMethodCheckBehaviour1(){ ... assertTrue(condition1); assertTrue(condition2); assertTrue(condition3); }testMethodCheckBehaviour2(){ ... assertTrue(condition4); assertTrue(condition5);}
![Page 19: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/19.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 20: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/20.jpg)
Tests isolation
Different execution order - the same results
No state sharing
Instance variablesJUnit - separatedTestNG - shared
Tests should be independent from one another
![Page 21: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/21.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 22: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/22.jpg)
Environment isolation
Unit tests should be isolated from any environmental influences
Database accessWebservices callsJNDI look up Environment variablesProperty files System date and time
![Page 23: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/23.jpg)
Environment isolationProduction code: A class heavily uses the environment
myMethod() { ... ... ...}
![Page 24: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/24.jpg)
Environment isolationUnder unit testing: It doesn't work!
testMyMethod() { ... myClass.myMethod(...) ...}
myMethod() { ... ... ...}
![Page 25: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/25.jpg)
Environment isolationSolution: Use mocks
testMyMethod() { ... myClass.myMethod(...) ...}
myMethod() { ... ... ...}
![Page 26: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/26.jpg)
Environment isolationSolution: Use mocks
Advantages:No test logic in production codeFast Easy to writeEasy to re-use
![Page 27: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/27.jpg)
Environment isolationSolution: Use mocks
Java mocking libraries (open source):EasyMock [ www.easymock.org ]JMock [ www.jmock.org ]Mockito [ www.mockito.org ]
![Page 28: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/28.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 29: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/29.jpg)
Classes isolation
The less methods are executed by the test, the better(better code maintenance)
The less tests execute the method the better(better tests maintenance)
![Page 30: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/30.jpg)
Classes isolation
high code coverage is a must (ideally 100%)
BUT:
![Page 31: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/31.jpg)
Classes isolation
high code coverage is a must(ideally 100%)
The less methods are executed by the test, the better(better code maintenance)
The less tests execute the method the better(better tests maintenance)
![Page 32: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/32.jpg)
Classes isolationLet's come back to our previous example to ilustrate the problem
Step 0: The class under test has no dependencies
![Page 33: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/33.jpg)
Classes isolationLet's come back to our previous example to ilustrate the problem
Step 1: The class depends on some other classes
![Page 34: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/34.jpg)
Classes isolationLet's come back to our previous example to ilustrate the problem
Step 2: Dependencies of dependencies
![Page 35: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/35.jpg)
Classes isolationLet's come back to our previous example to ilustrate the problem
Step 3: Dependencies of dependencies of dependencies
![Page 36: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/36.jpg)
Classes isolationLet's come back to our previous example to ilustrate the problem
Step 4, 5, 6,...
![Page 37: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/37.jpg)
Classes isolationConclusion: Mocking the environment is not enough
![Page 38: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/38.jpg)
Classes isolationSolution: Mock dependencies!
![Page 39: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/39.jpg)
Classes isolationSolution: Mock dependencies!
![Page 40: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/40.jpg)
Classes isolation
Can be hard if code is not testable
How to write testable code?
Don't call constructors inside a method. Use factories or dependency injection
Use interfaces
![Page 41: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/41.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 42: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/42.jpg)
Fully automated
No manual steps involved into testing.
Automated tests executionAutomated results gatheringAutomated decision making (success or failure)Automated results distribution
EmailIMSystem tray iconDashboard web pageIDE integrationLava lamps
![Page 43: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/43.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 44: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/44.jpg)
Self-descriptive
Unit test = development level documentation Unit test = method specification which is always up to date
![Page 45: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/45.jpg)
Self-descriptive
Unit test must be easy to read and understand
Variable names Method namesClass namesNo conditional logicNo loops
} Self-descriptive
![Page 46: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/46.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 47: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/47.jpg)
No conditional logic
Correctly written test contains no "if" or "switch" statements.
No uncertaintyAll input values should be knownMethod behaviour should be predictible Expected output should be strict
Split the test into two (or more) tests instead of adding "if" or "switch" statement.
![Page 48: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/48.jpg)
No conditional logicOne test, multiple conditions
testMethodBeforeOrAfter(){ ... if (before) { assertTrue(behaviour1); } else if (after) { assertTrue(behaviour2); } else { //now assertTrue(behaviour3); }}
testMethodBefore(){ before = true; assertTrue(behaviour1);}testMethodAfter(){ after = true; assertTrue(behaviour2);}testMethodNow(){ before = false; after = false; assertTrue(behaviour3);}
![Page 49: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/49.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 50: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/50.jpg)
No loopsHigh quality test contains no "while", "do-while" or "for" statements.
Typical scenarios involving loops:
Hundreds of repetitions A few repetitions Unknown number of repetitions
![Page 51: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/51.jpg)
No loops
Case 1: Hundreds of repetitions
If some logic in a test has to be repeated hundreds of times, it probably means that the test is too complicated and should be simplified.
![Page 52: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/52.jpg)
No loops
Case 2: A few repetitions
Repeating things several times is OK, but then it's better to type the code explicitly without loops.You can extract the code which needs to be repeated into method and invoke it a few times in a row.
![Page 53: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/53.jpg)
No loops
Case 3: Unknown number of repetitions
If you don't know how many times you want to repeat the code and it makes you difficult to avoid loops, it's very likely that your test is incorrect and you should rather focus on specifying more strict input data.
![Page 54: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/54.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 55: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/55.jpg)
No exception catching
Catch an exception only if it's expected
Catch only expected type of an exception
Catch expected exception and call "fail" method
Let other exceptions go uncatched
![Page 56: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/56.jpg)
Catching expected exception
testThrowingMyException(){ try { myMethod(param); fail("MyException expected"); } catch(MyException ex) { //OK }}
![Page 57: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/57.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 58: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/58.jpg)
Assertions
Use various types of assertions provided by a testing framework
Create your own assertions to check more complicated, repetitive conditions
Reuse your assertion methods
Loops inside assertions can be a good practice
![Page 59: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/59.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 60: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/60.jpg)
Informative assertion messages
By reading an assertion message only, one should be able to recognize the problem.
It's a good practice to include business logic information into assertion message.
Assertion messages:
Improve documentation of the code Inform about the problem in case of test failure
![Page 61: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/61.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 62: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/62.jpg)
No test logic in production code
Separate unit tests and production code
Don't create methods/fields used only by unit tests
Use "Dependency Injection"
![Page 63: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/63.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 64: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/64.jpg)
Separation per business module
Create suites of tests per business module
Use hierarchical approach
Decrease the execution time of suites by splitting them into smaller ones (per sub-module)
Small suites can be executed more frequently
![Page 65: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/65.jpg)
Unit testing best practices
3 stepsFastConsistentAtomicSingle responsibilityTests isolationEnvironment isolationClasses isolationFully automatedSelf-descriptive
No conditional logicNo loopsNo exception catchingAssertionsInformative assertion messagesNo test logic in production code Separation per business moduleSeparation per type
![Page 66: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/66.jpg)
Separation per type
Keep unit tests separated from integration tests
Different purpose of execution
Different frequency of execution
Different time of execution
Different action in case of failure
![Page 67: Unit testing best practices](https://reader034.fdocuments.us/reader034/viewer/2022051512/5406dbf68d7f7288088b4811/html5/thumbnails/67.jpg)
Thank you!
Find out more on:
http://www.nickokiss.com/2009/09/unit-testing.html
www.nickokiss.com