The "R" word. Refactoring. The first step in refactoring code is to make sure we are covering the existing code with tests. If we aren't refactoring against tested code, we are just changing stuff. In this lesson, we'll start taking a look at some code that needs refactoring, and get test coverage reports setup.
Hey, everyone. Today I want to talk to you about refactoring code. If you've been working with code for any length of time you've probably heard of the term "refactoring" and you've likely done some refactoring yourself.
What you might not know is there's actually quite a storied history around refactoring. There's a lot of theory behind it.
The canonical work on refactoring is a book called "Refactoring." It's by Martin Fowler with the help of Kent Beck and some other Java superstars. Since it was released in 1999 it has itself been refactored into a number of other languages like Ruby.
Today I wanted to share with you some of the takeaways from that book and help you give some names to the refactorings that you probably already do.
The new functionality we're adding is going to be some new types of movies. We see there's already a regular, new release, and children's type, it seems. We need to add some associated functionality regarding how much it costs to rent that specific movie and how many frequent renter points you should get based on the type of movie that you've rented.
This statement method is pretty big and it seems pretty intimidating. One of the reasons we're going to refactor is to improve our understanding of the code that's already been written to make sure that we know how to add functionality to it. The other reason we're going to refactor is to make it easier to add this functionality because I don't even know where to start.
One of the tools that's going to help us in doing this is called the coverage report. A coverage report looks a little something like this. We can see that, so far for this particular file, we only have 22 percent of our statements covered, none of the branches covered, and only half of the functions covered.
We get a little bit more detailed here with these colors. Pink represents statements that have not been covered by any tests. Orange represents functions that are not covered by any tests. We want to make sure that everything is covered by tests so that we don't break anything and everything continues to work the same was as it did before.
That way when we add new functionality we understand that the previous functionality also still works.
Let's see what it looks like when we have more of our code covered here. Maybe we'll just uncomment some of this here. We'll re-comment some of this so we can see what some of these other helpers look like.
We've got much more coverage now. This I indicates an if clause that's never being followed. We see these pink statements are showing us that none of these statements are being evaluated. The E clause usually represents that an else statement is not being evaluated but we see that these aren't pink. This actually lets us know that this if is unnecessary here. It would be the same as if we had just had this else clause in here.
We can prove that that's true by heading back into our customer. We can delete that if statement. Let me see that that would go away and that if we come back here to our customer and uncomment this. Now we would have 100 percent coverage.
I think that this probably indicated the intention of the original programmer a little better so we'll add it back in so that when we're refactoring this in the future we have a better understanding of what's going on.
This shows us that we don't have full coverage but we already know by evaluating this by hand that we do really have all of our code covered by tests here.
We can also look at all of our files. We see that all of our files have very similar coverage. This is the point that we'd be pretty safe to start refactoring.
I want to show you how we can get set up with this. In particular, I'm going to be using the Karma coverage library, which is a part of the larger Karma Test Runner suite. We're also going to use a Grunt task to set us up here and the Jasmine library as our testing framework and our Karma configuration file which helps us set up things like the framework we want to use, the files we want to test, the browsers we test against, et cetera.
We want to have this pre-processors bit set up which tells us that we want a coverage report for everything in our lib folder. Then in our reporters, we just want to add coverage here.
We also have a Grunt file that sets up these tasks for us which you can check out in the show notes. This works simply by running Grunt auto test.
We can see that this runs each of our tests and they pass. This generates this coverage folder for us, which has each of these files for our models. That's what we're looking at here.
We can see our other models like movie are also being fully tested.
This is important where we'd want to start refactoring. We'll do that in the next refactoring video. The first thing that you'll want to get set up when you start refactoring anything, whether it's something that you've written but particularly if it's something that you haven't written, is to set up a coverage report like this so that you can be sure of what the code does and that you're not breaking any code that's previously been written.
Take it easy, everyone.