At WeddingWire, we strive to build things as fast as possible, but still keep them high-quality. How do we do this? We write tests. Lots and lots of tests. Now, testing can often be tedious, and sometimes, rather annoying to debug when you make a change. I can’t count the number of times where a test failed only to realize that I missed some parameter or my method was returning a wrong type (cough).
Since debugging is often times tricky, wouldn’t it be nice if we could run IRB at a specific breakpoint and run our own test code DURING a run? This is where Pry comes in. Most people know how to use the IRB and Rails console to debug simple commands, but what about more complex ones? What if you don’t want to run all the commands that lead up to a method call? Pry makes this super easy. If you know how to use IRB and the Rails console, you can easily pick up Pry. All you really need to do is stick “binding.pry” in your code and it’ll act like a breakpoint in any test suite (we use Cucumber and RSpec).
I’m going to use an example of how Pry helped me debug a test recently. I wrote a test for a verification method where it takes in a code and updates the user model’s verified_flag to be true if the codes match. Easy right? Problem is, the test passed when it shouldn’t have.
Let’s go into the failing test and check out what’s wrong. For some reason, this check seems to always be returning true, never false. Let’s take a deeper look. First, we look at the RSpec test that hits the specific controller action we’re looking to enter.
It doesn’t look too off, let's see what’s actually going on by inserting a binding.pry here.
Once the test hits that section where Pry was inserted, it’ll stop and present to you a nice code snippet so you know exactly which instance of Pry you’re stopped at. Let's check our user’s verification code and see what happened to it.
So it was set correctly, and it definitely does not equal to our verification code of ABCDEFG. Why wasn’t it given a falsey value after hitting the check?
Let's type next to advance forward a couple of times to go past the patch call and see what verify_user did to our user model.
That’s… not right; a nil value would mean that the model never got saved. I never called the save option on the user model. Whoops. Of course the test would not behave correctly. My test is bad and I should feel bad. Let me fix that.
Sweet, the expect statement came back with a falsey value and the test passed! It was a small careless mistake, but when writing up a bunch of tests things like this are bound to happen (and it’s also why you should write tests in the first place).
This is a rather simple example, but it just shows how easy it is to debug a test using Pry. Of course, Pry has much more powerful uses, and I definitely would recommend checking out Pry tutorials and the gem pry-nav (which is what I used to advance execution line by line). Hopefully this will make your testing life easier!