views:

86

answers:

4

If you were assigned to a very large project, with sparse documentation/comments and little access to previous developers, and tasked with fixing some tricky little bugs, how would you go about:

  1. Learning how the project works
  2. Locating the source/cause of the bugs
  3. Fixing them, hopefully without causing (too many) new problems

I know it's a slightly sweeping, open question, but the experiences and strategies of developers who've been in this situation will be invaluable.

+3  A: 

I don't think the solution to this is all that complicated, but it still may be quite difficult in practice:

  1. Read (the code and any/all accompanying documentation... but mostly the code)
  2. Use the IDE to read through common code paths
  3. Use the debugger on a running instance to see how things actually work
  4. (and this may actually be the most important) Write unit tests to determine boundary conditions of methods and classes that you have difficulty understanding.

If this is a large codebase, this will take a while... but there are few shortcuts to learning a large codebase in my experience.

jsight
+1 for being short :)
willcodejavaforfood
+1  A: 

Firstly, I wouldn't think about fixing the bugs until I understood how the project worked.

Beyond that, I'd pick up the common uses of the code, and trace through the execution path this would entail (either by just looking at the code, or by stepping through a debugger; both have their own advantages). Once you've done this for a few cases, you'll likely have a good "feel" for the layout of the code, which classes/packages form the important business logic, which ones are trivial audit functionality, or simple data containers, etc.

Then I'd either look at the test cases to pick up the definition of individual methods if they exist - or more likely, try to write test cases based on the execution paths I've just seen. This will teach you a little bit about using the API, and if you use the inputs/outputs you've been tracing then you have a mini regression test right there, to ensure that future modifications don't change this behaviour. (Of course, check that the behaviour you're observing isn't the erroneous one you need to fix!)

I think alternatively between these two steps at progressively finer levels of detail should do the trick. First read/*watch* to see what things do, then write tests to cement this in your mind and check you've understood the API correctly. If you have a good bug report with reproducible test cases, and the expected output, then the first run through the code should give you a good feel for which modules are responsible for the bit that goes wrong. Tracing slowly through those modules, checking the state at every point until you see "good" go to "bad" shouldn't take long, and then you have the cause of the error.

Your third step is possibly the hardest; without a full, over-arching undertanding of the system it's difficult to feel confident that you're not breaking something else. IDEs' "Find Usages"-type capability will help a lot here, to let you know what's depending on something, but they're not infallible (e.g. reflection-based uses, or calls from other source trees). At this point, come up with a solution you believe is OK, and ask other more experienced developers to code review it for problems. They ought to know whether there are any external dependencies, something you can hardly be expected to take into account at this point and with insufficient documentation.

Andrzej Doyle
+1  A: 

I would start writing unit tests if none exist. It would catch bugs, force you to understand the intent of each piece of functionality, and provide a guard against introducing new bugs.

edit -- if tests exist, i would start by looking at those. Tests, in a manner, provide documentation for how the code works...

hvgotcodes
+1  A: 
  • You might want to start with reverse engineering the code into UML diagrams. Look at this and this question asked here on SO. Also see this link. This can help you get the big picture and a sense of the relationships between the classes in your code.
  • Once you have some idea about where to start, you can use a debugger to step through the code and understand the control flow.
  • Once you have a grasp on the functionality being provided by parts of the code and you understand the control flow, the next step could be to write unit tests. Write as many tests as you can. If you already have a regression test suite, you can take a good look at it as well to understand the expected.
  • Finally, when you go and fix bugs, make sure that all the tests that you have pass.
Samit G.