SaaS Legacy Homework 2: Lessons Learned

This week's SaaS homework has been the most elaborate so far. As the instructors explain in the lectures, after teaching the class for a while, they asked some of the top software companies what one thing they wish graduates of computer science programs would learn before entering the workforce. The overwhelming answer was "how to work with legacy code". So even though at first they had no idea how to teach this, they set out to do so in this class. And thus we have legacy homework 1 and 2 (last week and this week).

Instead of working on a new custom app, we are given an existing app (the Typo blog platform) that has a long history, sometimes messy code, and spotty test coverage. Last week we were asked to fix a bug in it. This week, we had to add a new feature!

Our feature in a nutshell: add the ability to merge two articles into one. The body of the new article will be a concatenation of the two previous articles. The title and author will be from one of the two articles. And the comments of all previous articles (if any) will now be comments of this article. Only administrators can merge articles. All other users will not see the option at all.

picture of what the typo merge feature should look like

I spent a LONG time on this homework. Around 15 hours. The hardest part was writing the tests. That shouldn't be a surprise because writing the test is always the hardest part for me! I am still very new to Rspec and TestUnit syntax, and spend so long trying to figure out exactly how to phrase things. But I'm proud to say that I stuck to it this time and wrote all the tests before writing the actual code (except for the view and some skeleton methods so it didn't throw method-not-found errors--basically I had to get it to the point where the tests failed for the right reasons and not because it couldn't find some method).

First I wrote the Cucumber integration tests for the happy path only. Then I wrote the unit test for the controller. It was at this time that I realized I was planning to put way too much logic in the controller. So instead of putting all the tests there, I just wrote a few to make sure the controller was asking the model for that information. Then I had to write a bunch of unit tests for the model. At last I allowed myself to write some actual code, which didn't take long.

Then at the very end I wrote the cucumber integration tests for the sad paths. The one thing that was SUPER helpful was using the debugger gem and plain old rails console (with the --sandbox option) while writing the tests, because it helped me figure out exactly how to get to certain elements in order to test them.

Even though I could have knocked out the homework in probably less than half the time without testing, I really liked the practice. It was hard but satisfying. There isn't a more satisfying and empowering feeling than when you can get all your tests passing AND you haven't even looked at your app in the browser yet with your own eyeballs... but you know it's working! This is so different than the way I used to program.

I also feel like testing frees up my brain from worrying about every little bit of my application. If what I'm doing now will break something else, then I'll know about it soon enough (if I wrote my tests right). So all I have to do now is concentrate on writing whatever little bit I'm working on now, instead of trying to keep the entire app in my head and worry about not breaking anything else.

A few SPECIFIC things I learned:

And if you're curious about the code I wrote for this week's homework, it's up on Github.