For some beginners, debugging can be a weary chore. It can lead to a lot more questions than answers. It can waste time and seem endless.
Throw test suites into the mix and, for a beginner, the result can be a volatile debugging process where the nuts and bolts of your code can appear to rattle apart at the seams. It can suck.
There’s no substitute for hard work here. Beginners need to invest many hours before feeling comfortable whether it’s for debugging or for test building activities. With that said, a few rules and tips can make it easier to add test-driven methodology into your coding and debugging processes.
You might ask, “Why should a beginner learn about testing and complicate an already challenging learning process?”
That’s a great question for which I offer four reasons.
1. Everybody’s doing it.
Assuming you want to have a career in programmer or do a tech start up or code as a hobby, test-driven development has become de rigeur. You need to know how to work with tests, and that means write them, fix them, use them, and debug with them. You’ll need to know the development cycle and how unit testing (typically the sort of testing you’ll be doing alone on your personal code) fits into the bigger domain of QA.
At the previous company I worked for, I help manage QA which involved managing a suite of tests including smoke tests, functional tests, black box and white box tests, integration tests, load tests, acceptance tests, and on and on. The point is that testing is a critical component of the development cycle, and your unit test is just the first and most atomic part of these tests you’ll want to perform.
2. It saves time on debugging.
If you want quality code, and you want it fast, test it as you write it. Doing this will speed up the development of quality code. It helps eliminate coding artifacts and bugs from creeping in and breaking parts of your core base code, thus saving tons of time in your debugging process. You don’t see this and it isn’t apparent but trust me – it saves time.
Testing does this by providing a fast feedback loop that allows you to see if and where things go wrong in your code base. As you make changes to your code, functionality that used to work before can break without you knowing. You don’t want that. You want to be able to know as frequently as possible that the things you do don’t accidentally break your base code.
It may seem counter-intuitive since you’re spending extra time writing tests – but you have to sacrifice a short term loss for long term gains – gains which will compound exponentially as time goes on.
3. It saves time on documentation.
This one’s simple. Well-written tests serve as drafts of your product documentation thus killing two birds with one stone. In many cases, the tests actually serve as the documentation proper.
4. It shows you’re responsible.
No one likes sloppy code. What better way than showing that you’re a responsible, conscientious programmer who cares about the quality of your code than to adopt test-driven methods and practices?
5. Bad habits are harder to break than good habits are to learn.
Learning to test as you code is especially important to beginners because it’s easier to learn new habits correctly than to undo and change bad ones later.
For the first 500 hours of learning Ruby, you’re going to be constantly feeling challenged so there’s little upside in waiting until you reach a plateau of comfort to adopt testing into your coding process. Adopt it early. Adopt it now.
The only time you shouldn’t use tests when coding is when you’re writing throw-away code: stuff like quick and dirty prototypes, sketches, etc.
Here a couple of good blog posts on testing:
The instructions below seem like common sense (because they are), but because many beginners tend to ignore vital tools in the test-driven debugger’s arsenal, it’s important to be super clear that each tool and tip listed below are important. Don’t ignore any.
1. Use Rspec.
Rspec is, at this time, probably the best test suite out there for Ruby. In bash, do a ‘gem install rspec’ and follow instructions here. http://rspec.info/
2. Set up four quick-toggle windows
Once you’re set up and you have an rspec to test your code against, set up your environment so that you can quickly and easily toggle between the following four screens:
- Your code in your text editor
- The corresponding rspec code in your text editor
- An open bash window to run your rspec tests
- An open pry or irb window to play around with errors quickly
I like to have all windows open in four quadrants on a single screen so that everything I need to toggle to is visually there. Here’s what mine looks like:
3. Use ALL FOUR windows to debug.
Over time, trust that you’ll develop strong instincts to hone into the errors quickly and directly, but for beginners, it’s important to constantly cycle through all four windows when you debug. The focus now is on working meticulously to develop good habits, not on being super fast. ‘Fast’ will come in time.
1. Go SLOWLY and METHODICALLY. Understand each line of code.
For some beginners, the faster you try to debug, the longer it will take. Take a break. Be methodical. Go line by line. Pause to understand what each part of the code is doing before moving on. The more methodically you can debug, the faster you will find and fix your errors.
2. Use the fail fast flags in your rspec command in bash.
You want to do everything you can to speed up your feedback loop. The fail fast flags output only the first test that fails obviating the need to scroll through the entire list of failures every time your run rspec:
3. READ the error message CAREFULLY.
You will usually find all the clues to fix your code entirely in the error message. Read every word very carefully. Learn the syntax of the error message. This is super critical to becoming a proficient debugger.
4. Read the spec.
Read the spec alongside the code.
Not only do some errors become apparent only upon reading the spec, sometimes there are errors in the spec that you may need to correct – something that won’t be as apparent.
5. Use PRY and bind it to your code.
IRB and PRY are underused by many beginners. They are powerful tools that will greatly speed up the debugging process.
Using these tools to debug can seem daunting, but it’s really simple. There are just two things beginners need to do when debugging: copy-paste relevant code into pry/irb to test it directly and create new objects to test methods on the fly.
One way to do this quicker is by having your Ruby code jump immediately into Pry for debugging upon running it. You enable this by requiring Pry in your code and adding ‘binding pry‘ at the very bottom of your code.
None of this is hard – even for developers. They’re just new habits that may be a bit awkward and uncomfortable at first, but are essential to becoming a proficient, responsible coder.
In an upcoming post, I’ll expand on reading error messages with some examples and tips. Until then, cheers!
Make yourself useful.