Darrell Norton's Blog [MVP]

Sponsors

The Lounge

News

  • Darrell Norton pic

    MVP logo

    View Darrell Norton's profile on LinkedIn

    Currently Reading:

    weewar.com

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Adding tests and refactoring non-TDD code

Lately I’ve been adding unit tests around a critical subsystem of the application I am working on. Luckily I had some downtime to add unit tests to cover parts of the subsystem that I did not develop (of course with TDD all of my new code was covered!). Here are some tips I’ve learned in the process.

Since the parts that lacked a test harness (my term for a set of unit tests) had been used in testing for a while, I didn’t try to figure out what each method was supposed to do exactly. I put unit tests around the class and method that reflect the current result. That way I could refactor without fear, knowing that I had not changed any of the current behavior. If parts were later found to be incorrect, I could quickly make the change in the unit test, which would then guide my bug fix coding. I consider the ability to make a change quickly if something is wrong more important than implementing fewer unit tests that were right (at the time, since we all know requirements change).

When figuring out where to add unit tests, a code coverage tool is invaluable. I frequently used NCover and a custom application that used XPath queries to select only the code coverage reports I was interested in. My subsystem was not a separate application, and it crossed several logical layers. Initially I would target those classes with no unit test coverage (there were plenty, trust me!). After that I could find untested code within otherwise well-tested methods that might be causing a problem. I did not always write a unit test, as 100 percent test coverage was not the goal. The goal was to improve the test coverage in important areas, not to exercise every unlikely error condition. If it happens later, then I’ll add it!

Management, of course, wasn’t very interested in me working without creating new functionality. So I had to create some numbers to measure what I was doing. I started with a count of the lines of code for the entire project and my subsystem, with added emphasis that my subsystem was critical to the application’s success. I also included the number of unit tests, both total and for my subsystem. In management’s view, as long as this number increases, it doesn’t matter if you refactor your tests internally. Finally I added code coverage as a percent of each logical tier and as an overall number for my subsystem. The display looked something like the following (numbers are fictional):

  • Lines of code
    • Total: 200,000
    • Subsystem: 75,000
  • Unit test code coverage (subsystem only)
    • Services: 72.33%
    • Data: 37.45%
    • Overall: 61.17%
  • Automated unit tests:
    • Total: 580
    • Subsystem: 490

I also gave reports on how many classes were added and removed, the reduction in the number of lines of code from removing duplicate code, and the number of bugs found. It also helps to bring up any incidents where the unit tests discovered a subtle bug immediately, rather than letting QA pick it up. Some of my refactoring was also to improve performance, and a simple before/after snapshot works wonders. With all this data I was able to convince management that the refactoring work was important.


Posted 07-19-2004 2:34 PM by Darrell Norton

[Advertisement]

Comments

Jason Row wrote re: Adding tests and refactoring non-TDD code
on 07-19-2004 1:59 PM
So are you using these numbers to help convince management that TDD should be implemented as much as possible or only to justify why you're not adding new features?
Dave wrote re: Adding tests and refactoring non-TDD code
on 07-19-2004 3:08 PM
"Management, of course, wasn’t very interested in me working without creating new functionality."

This is so sad. God forbid you improve all the existing functionality by tightening the codebase, eliminating bugs, and helping performance. Boggles the mind.
Mark Bonafe wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 1:55 AM
Darrell - great job! I may try that on my project.

Dave - What do you mean "God forbid?" Of course, management wants a solid product! This isn't sad at all. Management must know their money is being wasted! This was a very good solution to let them know it is well spent.
Darrell wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 2:01 AM
Jason - to justify why I was not adding new features.

The TDD argument will play itself out when I can respond quickly to changing requirements and in the general stability of my subsystem.
Darrell wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 2:03 AM
Dave - yep, but since management usually isn't technical, that's what happens. Developers can wax eloquent about "technical debt" and "refactoring" and all that, but from management's view the project is not moving forward. So, a few metrics that management is somewhat familiar with help!
Darrell wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 2:05 AM
Bonafe - good luck. Send me an email if you have any problems you need help on. It's all about sharing the knowledge, man!
Dave wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 3:47 AM
I totally agree about providing the metrics. I was just saying that it's too bad that in most cases, managers of technical projects aren't technical. If they were, they would see the value of TDD and refactoring without asking you to justify it. I just wish that wasn't the norm.
Darrell wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 4:37 AM
Dave - me too. More and more I find myself spending more time justifying things rather than actually doing them. :)
Mark Bonafe wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 5:01 AM
Dave - yeah, that sucks. With todays "immediate gratification" style of business (i.e. "future savings be damned, just finish the project"), that's what happens. I'm sick of it, too.
Steve Hebert wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 8:31 AM
Darrell,

Are services and data subcomponents of the subsystem or are you looking at actual "data coverage"? I'm curious because data coverage is an issue that keep running into.

I really like the format. I don't necessarily agree that you are justifying your actions to management. I think this is providing metrics on your code - you are differentiating your coding against the guy sitting next to you.
Darrell wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 9:02 AM
Steve - no, just the code coverage execution of the DAL. If a particular piece of data causes a screwup, then I'll add the test for that when it happens.

I guess I don't see it as comparing myself to the guys next to me, because they are all my coworkers at CapTech. :) We've already established our credentials, otherwise we wouldn't be there as consultants. Paul is working on the UI, which is notoriously hard to test in an automated fashion (well, at least with the constraints on testing software we have, which is it must be free!). And Mark DiGiovanni is working on Excel interop. Again, hard to test. Plus I've explained to management why my subsystem demands and lends itself (at the same time) to heavy unit testing such as this (they don't know or care what TDD is).

Our project isn't over by a long shot. We'll see how it goes!
Steve Hebert wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 9:52 AM
Thanks for the clarification. I misread.

You're right that it's not about competing against the other guys on your team. I didn't mean to imply that. My situation reads a little differently, we currently have a considerable amount of functional overlap in development due to the size of the development staff (3) against the size of the application. Development is currently in campfire mode - most discussion between us involves involves introducing approaches to make life easier and the product better. When one person differentiates, the others pick up on it. This will be critical as we grow the developement team to maintain some shared practices across the org.

Thanks for sharing the details on your project, interesting stuff - sounds like a fun project.

Darrell wrote re: Adding tests and refactoring non-TDD code
on 07-20-2004 10:14 AM
"sounds like a fun project." Hehehe, you're just not here. :)

Overall I like it, mostly because I am working with 2 longtime friends and another CapTech employee, so we get to act as a team. That's always good as we try to grow our Microsoft service offering.

Make sure to post your own experiences!