460 likes | 636 Views
Refactoring and Tests. Manuel Aldana SWT-Seminar SS05 Veranstalter: Prof. Dr.-Ing. Stefan Jähnichen Dipl. Inf. Susanne Jucknath-John. Overview. Introduction tests Tests in refactorings Test types Test coverage Tool examples Summary. 1. Introduction tests. Introduction Tests.
E N D
Refactoring and Tests Manuel Aldana SWT-Seminar SS05 Veranstalter: Prof. Dr.-Ing. Stefan Jähnichen Dipl. Inf. Susanne Jucknath-John
Overview • Introduction tests • Tests in refactorings • Test types • Test coverage • Tool examples • Summary Manuel Aldana, SWT-Seminar SS05
1. Introduction tests Manuel Aldana, SWT-Seminar SS05
Introduction Tests • Production Code: code that implements software requirements • Test Code: code, that checks the „intention“ of production code Manuel Aldana, SWT-Seminar SS05
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 Manuel Aldana, SWT-Seminar SS05
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) Manuel Aldana, SWT-Seminar SS05
2. Tests in Refactorings Manuel Aldana, SWT-Seminar SS05
Refactoring • Refactoring changes structure of code • does not change functionality! Manuel Aldana, SWT-Seminar SS05
Functionality Functionality Functionality Structure Structure Refactoring-Step System System Manuel Aldana, SWT-Seminar SS05
Tests • Functionality can be „tested“ • Tests ensure „equal functionalities“ of structure and structure´ • Focus: -TestsbeforeRefactoring -TestsafterRefactoring Manuel Aldana, SWT-Seminar SS05
Tests before Refac. • They must exist ;-) • Execution of Tests successful (no Errors, Failures) • …for knowning functionality Manuel Aldana, SWT-Seminar SS05
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 Manuel Aldana, SWT-Seminar SS05
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 Manuel Aldana, SWT-Seminar SS05
Code First ->feature=software-requirement • 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 Manuel Aldana, SWT-Seminar SS05
Code First Refactoring • Doing refactoring-step • Tests are adapted to new Production-code Production- Code TestCode adapts_to Manuel Aldana, SWT-Seminar SS05
Test First ->feature=software-requirement • 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 Manuel Aldana, SWT-Seminar SS05
Test First Refactoring • Changing Test-Code • Doing Refactoring-step • As long as test-cases fail, refactoring is not finished Production- Code TestCode adapts_to Manuel Aldana, SWT-Seminar SS05
Side effect test change • Problem: Test-code is changed -> could be buggy (another point of failure) • Divide refactoring into small steps! Manuel Aldana, SWT-Seminar SS05
3. Testtypes Manuel Aldana, SWT-Seminar SS05
SW-Design • Software-systems often are „sliced“ into layers • Example: 3-tier Architecture Manuel Aldana, SWT-Seminar SS05
Test-“layers“ (from: JUnit in Action; Manning 2004) Manuel Aldana, SWT-Seminar SS05
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) Manuel Aldana, SWT-Seminar SS05
Recall 3-tier arch. Manuel Aldana, SWT-Seminar SS05
Test-“layers“ Integrational Unit A B D Integrational C Business-Layer Persistence-Layer Functional Manuel Aldana, SWT-Seminar SS05
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 Manuel Aldana, SWT-Seminar SS05
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 ;-) Manuel Aldana, SWT-Seminar SS05
4. Test coverage Manuel Aldana, SWT-Seminar SS05
Test coverage • Not only production needs „quality“ • Test code needs „quality“, too • Measured by tested/covered code in syntax-tree of production code Manuel Aldana, SWT-Seminar SS05
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… Manuel Aldana, SWT-Seminar SS05
Test coverage analysis • Statement coverage • Decision coverage • Path coverage Manuel Aldana, SWT-Seminar SS05
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 true if(statement==true) foo=„init“; //return value return foo; 100% coverage Manuel Aldana, SWT-Seminar SS05
Decision Coverage • Looks at conditions, too (e.g. if/else) • Decision Coverage: only 50% code coverage with a simplestatement=true;value in a test • For 100%: statement=false; condition must be checked, too String foo=null; //check if true if(statement==true) foo=„init“; //return value return foo; 50% coverage Manuel Aldana, SWT-Seminar SS05
Path Coverage • Checks that all „internal“ conditions are tested if(cond1 && cond2){ ……………… } Example: Decision coverage: 100% coverage (‚else‘ case checked) cond1=true, cond2=true; cond1=true, cond2=false; Conditions tested: Path coverage: 50% coverage (only 2 of 2²=4 possibilities checked) Manuel Aldana, SWT-Seminar SS05
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; Path coverage: 100% coverage (all of 2²=4 possibilities checked) Conditions tested: Manuel Aldana, SWT-Seminar SS05
Path coverage as statechart if(cond1 && cond2){ ……………… } Example: Manuel Aldana, SWT-Seminar SS05
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 Manuel Aldana, SWT-Seminar SS05
5. Tool Examples Manuel Aldana, SWT-Seminar SS05
Tool examples • Functional testing: Rational Functional Tester • Unit testing, Integrational Testing: JUnit • Code Coverage: Clover Manuel Aldana, SWT-Seminar SS05
JUnit Manuel Aldana, SWT-Seminar SS05
Clover Manuel Aldana, SWT-Seminar SS05
Clover Manuel Aldana, SWT-Seminar SS05
6. Summary Manuel Aldana, SWT-Seminar SS05
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 Manuel Aldana, SWT-Seminar SS05
Summary visualization • Visualization of path coverage tests in statecharts • Visualization of test results • Visualization of test-outcome in whole project timeline Manuel Aldana, SWT-Seminar SS05
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… Manuel Aldana, SWT-Seminar SS05
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 Manuel Aldana, SWT-Seminar SS05