Welcome back! This lesson focuses on debugging strategies that you’ll find useful—both when fixing errors in your project, and in fixing errors in software generally.
Between this lesson and a second that also focuses on debugging, we’ll be developing a checklist that we’ll expect you to have followed before you can receive help on the tutoring site. But we also expect that, by following these simple steps, you’ll find your mistakes faster, with less frustration, and needing less help from us. So let’s get to it!
Before we get started, we should emphasize that this guide is focused on how to figure out why your code is not working as expected. It assumes that you’ve tried to solve the problem, but your code either isn’t passing the tests or is crashing. These steps are not intended to be used starting from scratch. Our other MP lessons provide plenty of tips for getting started and understanding what you need to do. This is about what to do when things go wrong—as they inevitably do…
Whenever you’re debugging, an important first step is simply to tidy up your code so that you can more easily understand what’s going on. Depending on how you work, that might involve:
Overall our goal is to tidy up our source code so that we can more easily understand the code that we’ve written, and continue on with the debugging process. Let’s look at this using an example drawn from MP0.
On some level, debugging is an investigative process. Something is not working properly. We’re trying to determine why not.
However, it’s hard to make much progress without a clear idea of what is going wrong! This means being able to say more to the course staff member helping you than “it’s not working” or “I’m not getting the points”. Over the days and weeks ahead, staff will increasingly respond to this level of vagueness by asking you to narrow down the problem first, before they are willing to provide one-on-one assistance.
At this stage, our goal is to be able to provide a clear and concise explanation of what is wrong with our code. Imagine you’re explaining the problem to an inanimate object, like a rubber duck. There’s actually a name for this: rubber duck debugging.
For your project, the test suites represent the expected behavior. As a result, identifying the problem usually requires understanding what the test suites are expecting to happen. Happily, they are fairly well-commented, and designed to be straightforward for you to use. Let’s talk through how to do this using an example from MP1.
With a clearer idea of what’s going wrong, our next steps focus on what is happening, paying attention as we go to how the behavior of our code might not match up with expectations. Bugs in code frequently result from a mismatch between our assumptions about what the code is doing, and what it’s actually doing.
One of the best ways to test our assumptions is through well-placed log messages.
Log messages—also known as printf
debugging, after the equivalent of System.out.println
in the C programming language—is a ubiquitous, if sometimes maligned debugging technique.
printf
debugging works by inserting log messages into the code, running the tests, and using the output from the print statements to help understand what is going on.
You can use Android Log.d
statements, or good old System.out.println
, to both determine of certain code paths are being executed, and to examine the values of variables as your code executes.
Again, let’s walk through a simple example drawn from MP1.
That’s all for this lesson! But, to recap, here are the steps that we’ll expect you have to completed before you ask for help using the tutoring site or forum:
Need more practice? Head over to the practice page.