refactoring and tests manuel aldana swt-seminar ss05 veranstalter: prof. dr.-ing. stefan jähnichen...
TRANSCRIPT
Refactoring and Tests
Manuel Aldana
SWT-Seminar SS05
Veranstalter:
Prof. Dr.-Ing. Stefan Jähnichen
Dipl. Inf. Susanne Jucknath-John
30.07.05 Manuel Aldana, SWT-Seminar SS05
2
Overview
1. Introduction tests
2. Tests in refactorings
3. Test types
4. Test coverage
5. Tool examples
6. Summary
30.07.05 Manuel Aldana, SWT-Seminar SS05
3
1. Introduction tests
30.07.05 Manuel Aldana, SWT-Seminar SS05
4
Introduction Tests
• Production Code: code that implements software requirements
• Test Code: code, that checks the „intention“ of production code
30.07.05 Manuel Aldana, SWT-Seminar SS05
5
Introduction Tests
• Testcode tests Production-Code (-> overhead)
• Tests are executed independently from Production-Code
• mostly done with frameworks (e.g. JUnit)
• Tests report Success, Errors and Failures
30.07.05 Manuel Aldana, SWT-Seminar SS05
6
Success,Failure and Error
• Success: test was run successfully (no failures or errors detected)
• Failure: tested production-code does not behave as expected – example: return value is 2 instead of 3
• Error: error while running test – example: unexpected ClassNotFoundExc. is
thrown (so test cannot be run)
30.07.05 Manuel Aldana, SWT-Seminar SS05
7
2. Tests in Refactorings
30.07.05 Manuel Aldana, SWT-Seminar SS05
8
Refactoring
• Refactoring changes structure of code
• does not change functionality!
30.07.05 Manuel Aldana, SWT-Seminar SS05
9
Functionality
Functionality Functionality
StructureStructure
Refactoring-Step
System System
30.07.05 Manuel Aldana, SWT-Seminar SS05
10
Tests
• Functionality can be „tested“• Tests ensure „equal functionalities“ of structure
and structure´
• Focus: -Tests before Refactoring
-Tests after Refactoring
30.07.05 Manuel Aldana, SWT-Seminar SS05
11
Tests before Refac.
• They must exist ;-)
• Execution of Tests successful (no Errors, Failures)
• …for knowning functionality
30.07.05 Manuel Aldana, SWT-Seminar SS05
12
Tests after Refac.
• Same Tests are executed
• Case 1: Success (->no Failure or Error)
->Refactoring-Step successful
• Case 2: Failure or Error: ->Refactoring-Step mistake
30.07.05 Manuel Aldana, SWT-Seminar SS05
13
Side effect refactoring
• Problem: Refactored code shows often total different structure (interfaces, methods, packages…)
• Tests must be changed, too
• Two strategies: 1) Code First
2) Test First
30.07.05 Manuel Aldana, SWT-Seminar SS05
14
Code First
• First: produce your feature• Second: code your tests
• Advantage: - most programmers are used to this approach
• Disadvantage: - not all features could be tested
- production code could be difficult to test
->feature=software-requirement
30.07.05 Manuel Aldana, SWT-Seminar SS05
15
Code First Refactoring
• Doing refactoring-step
• Tests are adapted to new Production-code
TestCode Production-Codeadapts_to
30.07.05 Manuel Aldana, SWT-Seminar SS05
16
Test First
• First: test the feature you wanna have• Second: code your feature (…slogan: a feature without a test does not exist)
• Advantage: - good testable code - better structured code (feature
focused)
• Disadvantage: - no quick hacking… - Test-First needs experience
->feature=software-requirement
30.07.05 Manuel Aldana, SWT-Seminar SS05
17
Test First Refactoring
• Changing Test-Code
• Doing Refactoring-step
• As long as test-cases fail, refactoring is not finished
TestCodeProduction-Code adapts_to
30.07.05 Manuel Aldana, SWT-Seminar SS05
18
Side effect test change
• Problem: Test-code is changed -> could be buggy (another point of failure)
• Divide refactoring into small steps!
30.07.05 Manuel Aldana, SWT-Seminar SS05
19
3. Testtypes
30.07.05 Manuel Aldana, SWT-Seminar SS05
20
SW-Design
• Software-systems often are „sliced“ into layers
• Example: 3-tier Architecture
30.07.05 Manuel Aldana, SWT-Seminar SS05
21
Test-“layers“(from: JUnit in Action; Manning 2004)
30.07.05 Manuel Aldana, SWT-Seminar SS05
22
Test-“layers“
• Unit: testing only inside one(!) class, no interactions to other classes/components
• Integrational: testing interaction between different classes/packages
• Functional: testing Use-Cases (visible functionality of whole system)
30.07.05 Manuel Aldana, SWT-Seminar SS05
23
Recall 3-tier arch.
30.07.05 Manuel Aldana, SWT-Seminar SS05
24
Test-“layers“
B D
C
Business-Layer Persistence-Layer
A
Integrational
Inte
gra
tio
nal
Unit
Functional
30.07.05 Manuel Aldana, SWT-Seminar SS05
25
Beispiel
• Use-Case: Registration Student
• Unit: Check e-mail address contains @-char• Integrational: Check, if email address is saved to DB• Functional: Check, if all data (name,email, course...) of
student exists in system and confirmation e-mail is sent to student
30.07.05 Manuel Aldana, SWT-Seminar SS05
26
Big Refactorings
• Many Refactorings affect just one class• But architecture/design refactorings affect whole
system (e.g. package-refactoring)• Tests good saving-net for system wide
refactorings• Don‘t think of Unit-testing only, think bigger ;-)
30.07.05 Manuel Aldana, SWT-Seminar SS05
27
4. Test coverage
30.07.05 Manuel Aldana, SWT-Seminar SS05
28
Test coverage
• Not only production needs „quality“• Test code needs „quality“, too• Measured by tested/covered code in syntax-tree
of production code
30.07.05 Manuel Aldana, SWT-Seminar SS05
29
Test coverage
• „Good enough“ to do some refactoring?• „Good“ means: Every production-code line is
tested• -> code that is not tested could result to errors in
refactored code, which are not detected!• „Dangerous“ saving-net…
30.07.05 Manuel Aldana, SWT-Seminar SS05
30
Test coverage analysis
1. Statement coverage
2. Decision coverage
3. Path coverage
30.07.05 Manuel Aldana, SWT-Seminar SS05
31
Statement coverage• Just concentrates on code-lines• Tells that a line has been executed in a test• 100% coverage, when call with a simple statement=true;
• What happens when input statement=false; not tested?• -> statement coverage doesn‘t know conditions (e.g.
if/else)
String foo=null;//check if trueif(statement==true) foo=„init“;//return valuereturn foo;
100% coverage
30.07.05 Manuel Aldana, SWT-Seminar SS05
32
Decision Coverage
• Looks at conditions, too (e.g. if/else)• Decision Coverage: only 50% code coverage with a
simple statement=true; value in a test
• For 100%: statement=false; condition must be checked, too
String foo=null;//check if trueif(statement==true) foo=„init“;//return valuereturn foo;
50% coverage
30.07.05 Manuel Aldana, SWT-Seminar SS05
33
Path Coverage• Checks that all „internal“ conditions are tested
if(cond1 && cond2){ ………………}
Example:
cond1=true, cond2=true;cond1=true, cond2=false;
Decision coverage:100% coverage(‚else‘ case checked)Conditions tested:
Path coverage:50% coverage(only 2 of 2²=4 possibilities checked)
30.07.05 Manuel Aldana, SWT-Seminar SS05
34
Path coverage
• Problem: testing gets to nasty exponential condition checking…
• means: 2n checks for a if(1,2…n) construct
cond1=true, cond2=true;cond1=true, cond2=false;cond1=false,cond2=true;cond1=false,cond2=false;
Conditions tested:Path coverage:100% coverage(all of 2²=4 possibilities checked)
30.07.05 Manuel Aldana, SWT-Seminar SS05
35
Path coverage as statechart
if(cond1 && cond2){ ………………}
Example:
30.07.05 Manuel Aldana, SWT-Seminar SS05
36
Test coverage
• Test coverage: test in place, but do you test the right thing?
• 100% test-coverage does not mean application is 100% tested and ready to be refactored
30.07.05 Manuel Aldana, SWT-Seminar SS05
37
5. Tool Examples
30.07.05 Manuel Aldana, SWT-Seminar SS05
38
Tool examples
• Functional testing: Rational Functional Tester
• Unit testing, Integrational Testing: JUnit
• Code Coverage: Clover
30.07.05 Manuel Aldana, SWT-Seminar SS05
39
JUnit
30.07.05 Manuel Aldana, SWT-Seminar SS05
40
Clover
30.07.05 Manuel Aldana, SWT-Seminar SS05
41
Clover
30.07.05 Manuel Aldana, SWT-Seminar SS05
42
6. Summary
30.07.05 Manuel Aldana, SWT-Seminar SS05
43
Summary tests
• Tests ensure equal functionality before and after refactoring
• Side effects can occur for both refactored production-code and test-code
• Different grained Test-types (Functional, Integrational, Unit)
• Code coverage helps to test as many parts of production-code as possible
30.07.05 Manuel Aldana, SWT-Seminar SS05
44
Summary visualization
• Visualization of path coverage tests in statecharts
• Visualization of test results
• Visualization of test-outcome in whole project timeline
30.07.05 Manuel Aldana, SWT-Seminar SS05
45
Points to think of…
• Never refactor without tests
• Don‘t test for the sake of testing
• 100% code-coverage does not mean 100% tested system
• A fool with a tool is still a fool…
30.07.05 Manuel Aldana, SWT-Seminar SS05
46
Sources
• Massol,Husted; „JUnit in Action“; Manning Press • Roock, Lippert; „Refactoring in Grossprojekten“,• Fowler; „Refactoring“; Addison-Wesley • Kerievsky; „Refactoring to Patterns“; Addison Wesley• Wang; „Einführung in die Code-Coverage-Analyse“; Java Magazin
7/05