Em um mundo ideal, todo o código escrito por um determinado desenvolvedor será bem documentado, bem estruturado e testado de maneira abrangente, tanto com ferramentas automáticas como testes de unidade quanto scripts de casos de uso que um usuário executa para verificar se você obtém o resultado esperado.
No entanto, a primeira coisa que você aprenderá é que não vivemos em um mundo ideal!
Muitos desenvolvedores não documentam seu código adequadamente, se é que misturam lógica de negócios com código não relacionado, e o único teste que eles fazem é uma rápida execução do que eles esperam ser o caso de uso normal.
Ao trabalhar com código como este, a primeira coisa que você precisa fazer é estabelecer o que ele deve fazer. Se houver comentários, eles podem fornecer pistas, mas não conte com isso. É minha experiência que muitos programadores não são bons em se explicar e, mesmo que deixem comentários, podem não ter sentido. No entanto, a menos que você seja o único codificador da empresa, alguém certamente deve ter pelo menos uma idéia básica de para que serve o código e o que ele deve fazer. Pergunte por aí!
Se você tiver testes de unidade, eles tornarão sua vida muito mais fácil. Caso contrário, parte do aprendizado da base de código pode envolver a escrita de testes de unidade para códigos que já existem. Normalmente, isso não é considerado uma boa prática, porque se você escrever testes de unidade para ajustar-se ao código existente, você terminará com testes de unidade que pensam que o código funciona como está (eles serão escritos para assumir que o comportamento que é realmente um bug é correto), mas pelo menos fornece uma linha de base. Se você descobrir mais tarde que algum comportamento que você achou correto está de fato errado, poderá alterar o teste de unidade para testar qual é o resultado esperado e não o resultado que o código fornece agora. Depois de fazer um teste de unidade, você pode fazer alterações e avaliar quais efeitos colaterais têm as alterações.
Finalmente, o melhor recurso que você tem ao lidar com um trecho de código não documentado é perguntar aos usuários finais. Eles podem não saber nada sobre código, mas sabem o que desejam que o aplicativo faça. A coleta de requisitos é o primeiro estágio de qualquer projeto, e conversar com os possíveis usuários do sistema a ser desenvolvido é sempre uma parte importante disso. Pense nisso como realizar o estágio de captura de requisitos para um novo projeto que, por acaso, já foi construído.
Lembre-se de que mesmo código bem escrito e bem documentado pode ser difícil para um estranho entender. Código é essencialmente uma expressão de como a pessoa que o escreveu estava pensando na época, e todo mundo tem seu próprio processo de pensamento. Você terá que aprender a ser um pouco paciente e a ser um detetive. Ser capaz de entrar no processo de pensamento de outra pessoa é difícil, mas é uma habilidade essencial para um programador que faz manutenção no código existente. Como a maioria das codificações (cerca de 70%) está relacionada à manutenção do código existente, é uma habilidade importante a aprender.
Ah, e agora que você viu a dor que um código mal documentado, não testado e confuso pode causar, você não fará isso com o próximo desenvolvedor ruim, certo? :) Aprenda com os erros do seu antecessor, comente bem seu código, verifique se todos os módulos têm uma responsabilidade claramente definida e se assegura de ter um conjunto abrangente de testes de unidade que você escreve primeiro (para metodologias TDD) ou pelo menos ao lado do código que está sendo desenvolvido.