My team consisted of four software engineers, one project manager (Scrum Master), and one QA engineer. The QA engineer was a permanent part of our team. He was a white-box tester. We wrote our own unit tests and demonstrated scalability with our component tests while our QA engineer reviewed our logic. He'd look for obvious issues like uncaught null pointer exceptions while digging deeper in search of ambiguous cases like poor security implementations.
New Code HereAny issues our QA engineer found in our code, during a sprint, were fixed by the software engineers on our team. The rest of the bugs (outside of our recent sprints) were entered into Apple's bug tracking system, Radar. Then, once a week, we'd meet to prioritize bug fixes in Radar. We off-shored the bug fixes to India since it wasn't sexy work. Once it was fixed, we reviewed the code and verified it before integrating it into the main branch.
Bug Fix ThereOffshoring bug fixes worked beautifully. Each bug was clearly documented: what really happened vs. what was suppose to happen. I had no idea who was on the other end fixing our bugs but I realized they were intelligent and hard working. However, I could tell they weren't experienced with our technology (WebObjects) or conventions. As one example, I reviewed code where the offshore team had hard coded SQL queries directly into Java. Other times, I saw Java objects instantiated simply to access static Java methods.
The beauty of offshoring a bug fix is we could focus on new feature development.
New Code ThereSince offshoring bug fixes worked so well we decided to give them a shot at new development. We quickly discovered that was a mistake. The offshore team didn't have enough context to write good code. Their implementations were too brittle.
This problem frequently happens in any coding organization that's offshoring new development. Without a product roadmap, the offshore team simply writes code to do exactly what you asked for; and no more.
I never saw requirements sent to an offshore team to refactor code. That would be too nebulous of a task. By the time I would have documented all the ins and outs of a refactoring requirement, I could have written the code myself. The real problem is that we don't know how our code will behave until we run it.
And that was the crux of the problem with the code written by the offshore teams I've dealt with. They could only do exactly what you asked for, now, without knowing what was coming. Plus, the requirements had to be very explicit.
Software engineering isn't an event – it's a process. It's a process of continue improvement and refinement. It's iterative.