generatingcharacterizationtestsforlegacycode
TRANSCRIPT
![Page 1: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/1.jpg)
Generating Characterization Tests for Legacy Code
Slides via Jonas Follesø (@follesoe)
![Page 2: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/2.jpg)
Huge methods (~3000+ lines)
![Page 3: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/3.jpg)
Dav
e &
Kar
in h
ttp:
//w
ww
.flic
kr.c
om/p
hoto
s/dn
k_uk
/352
5103
502/
~50 slow integration tests
![Page 4: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/4.jpg)
How the development team felt...
![Page 5: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/5.jpg)
What they needed
![Page 6: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/6.jpg)
What you should read
![Page 7: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/7.jpg)
Fras
er S
peirs
htt
p://
ww
w.fl
ickr
.com
/pho
tos/
fras
ersp
eirs
/339
5595
360/
Legacy code is code without tests. Code without tests is bad code.
-Michael C. Feathers
![Page 8: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/8.jpg)
A characterization test is test that characterizes the actual behavior of a piece of code.
It acts as a change detector, protecting legacy code from unintended changes
![Page 9: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/9.jpg)
public double Calc(double inv, double rt, int y){ double ret = 0; for (int i = 1; i <= y; i++) { ret = inv * Math.Pow(1.0 + rt / 100.0, i); } return ret;}
![Page 10: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/10.jpg)
[TestMethod]public void Calc_characterization(){ var calc = new CalcUtil(); double result = calc.Calc(10000, 10, 10);
Assert.AreEqual(42.0, result); }
![Page 11: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/11.jpg)
Assert.AreEqual failed. Expected:<42>.
Actual:<25937.424601>.
![Page 12: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/12.jpg)
[TestMethod]public void Calc_characterization(){ var calc = new CalcUtil(); double result = calc.Calc(10000, 10, 10);
Assert.AreEqual(25937.424601, result); }
![Page 13: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/13.jpg)
Test run completed. Results 1/1 passed.
![Page 14: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/14.jpg)
public double CalculateCompoundInterest(double investment, double interest, int
years){ double projectedValue = 0.0; for (int year = 1; year <= years; year++) { projectedValue = investment *
Math.Pow(1.0 + interest / 100.0, year); }
return projectedValue;}
![Page 15: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/15.jpg)
Fras
er S
peirs
htt
p://
ww
w.fl
ickr
.com
/pho
tos/
fras
ersp
eirs
/339
5599
536/
…A pinch point is a natural encapsulation boundary. When you find a pinch point, you’ve found a narrow funnel for all the effects of a large piece of code…
-Michael C. Feathers
![Page 16: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/16.jpg)
fast characterization tests
![Page 17: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/17.jpg)
The Golden Master Approach
Before making any change to production code, do the following:
1) Create X number of random inputs, always using the same random seed, so you can always generate the same set over and over again. You will probably want LOTS of inputs for good coverage. 2) Bombard the class or system under test with these random inputs.
3) Capture the outputs for each individual random input.
![Page 18: Generatingcharacterizationtestsforlegacycode](https://reader035.vdocument.in/reader035/viewer/2022070315/554fb5e2b4c90586258b546c/html5/thumbnails/18.jpg)
A picture's worth a 1000 tests.
Unit testing asserts can be difficult to use.
Approval tests simplify this by taking a snapshot of the results, and confirming that they have not changed.