I don't have more than 6 months of experience and I am a little lazy . I work on Android platform . I have very good skills in understanding what is happening in general . The problem is that I don't have the experience to read and understand someone elses code (btw I just got a new project which I will develop a new feature in Android) . I would ask for some advice on how to be a good debugger and understand what is happening in detail . I am facing lots of problems reading it. I don't know how to write unit tests also.
I have more than 20 years of experience and I am profoundly lazy. I work in many platforms.
The way I read and understand someone else's code is primarily with my fingers.
Why yes I am the kid who was always getting told you don't look with your fingers. I am forever touching the signs that say do not touch.
I am fortunate enough to work in a shop where we do tests. When it comes time for me to understand someone else's code I don't just read it. I run it. I test it. I run the old tests for it. The smallest ones I can find. I write new tests for it. I ask questions about it. I challenge the code in every way I can think of. Somewhere in there I find time to read it and laugh at the lies we call comments. Only once I've done all that do I start to think I might understand it. That's when I start to refactor it. I change it to be something other than what it was, while not yet changing what it does. I do this to make adding a new feature easier or to prepare to make an old bug go away. After adding tests that show my intent, I make my changes. I also look for other little changes to make so I can leave it a little nicer than I found it. Then I go do something else, and for a time, forget this code exists.
The ability to do this is WHY I care about tests. Tests help me read code. Tests don't prove your program does what it's supposed to do. They show what it actually does. You have to figure out if that is what it's supposed to do.
When you're new it is so tempting to reach for lazy ways of thinking. One of the most damaging is to focus on mechanics and structure. It is far better to focus on ideas. To help you with this let me teach you a really good pattern to know about when learning your testing. It's called the humble object.
Someone of the mechanical/structural mind set will insist every class, every method, be under test or they'll insist that testing doesn't work and is a waste of time. They'll say that the only good code coverage number is 100% or that code coverage is a pointless unobtainable fantasy. All of which are true, to someone that thinks this way.
The humble object pattern just flat out admits that there is such as thing as hard to test code. This is very healthy to understand. Sometimes the problem isn't you. It's the code the problem demands.
Nothing's completely untestable but rather than throw every magical mocking and reflection trick at the code to test it as-is the humble object pattern expects us to do a little re-architecting. We change the code to separate testable behavior from uninteresting structural glue code that frankly doesn't need testing. Why? Because testing is about understanding code.
This is exactly why views and presenters aren't the same thing. View's, backed by presenters, have had their interesting behavior removed. They are nothing but boring structural code. The interesting decisions are all happening in the presenters. We test the presenters. We don't test the views.
Views and presenters aren't the only places we do this. Anything that has a boring mechanical need to be wired up can benefit from the humble object pattern. Talking to the DB, a service, a chip, a driver, all can end up with this same dynamic. Give them the wiring they need and scrape away any interesting behavior the app needs to exhibit into a nice testable module that proves the behavior is what we need.
In this way you can enshrine any needed behavior in testable code regardless of any mechanical or structural need to create hard to test code. That way you can focus on your real idea.
There are many many things to study to help you develop your testing skills but understanding why not every lump of code is going to welcome your testing efforts, or even needs to, is right at the top of my list.
This is something that I have to say I don't entirely understand. I have encountered a number of occasions when someone has asked me a question about why something has happened without having actually fired up a debugger and stepped into the code to look.
This is all you need to do for a starting point - open the application, fire up your favoured debugging tool and step into the code. See where it goes, see if you can see the patterns being used.
Once you've got the hang of how your colleague has structured their code (however it is that they have done it), try to write your new feature in a similar pattern, as this will make life considerably easier for the next new developer to come along.
The point here is that you don't have to just read the code - we have the tools that allow you to follow the flow through. Use them.
The way I've learned to get better at reading code is often by reading other things. I read blogs, books, and questions and answers here on the various Stack Exchange sites about programming and architecture. It can be difficult to separate the useful bits from the dogma surrounding it, but doing so is extremely useful.
For example, there are rules people mention frequently when discussing software architecture. SOLID, the law of Demeter, design patterns, etc. Each of these ideas are useful to some degree. So learn them and try them out. You will likely find that there are limits where these ideas break down. For example, short functions are generally a good idea. It's easier to understand the flow of control and the logic in a shorter function. But it can be taken to an extreme. I've seen people recommend that no function should be longer than about 3 lines. I have, unfortunately, had to work with code like that and it is actually harder to follow because there's not enough context in a given function. So try these things out and learn where their limits are.
For debugging, learning how to use the debugger is a great first step. Be aware that debugger designers are sadists and the user interface for most debuggers are atrocious. If you can use an IDE with a debugger that has a GUI, I highly recommend it. They're not perfect, but they're a step up from using the awful command-line interfaces for most debuggers.
But you need other tools besides the debugger. You need memory watching tools; you need static analyzers; you need profilers, etc. Each one targets a specific set of problems. For example, there are tools for finding memory leaks while running. A profiler will time your code to find which parts are using the most CPU time, etc.
Tools help make the work of debugging easier.