No Tests? No Excuses!

There is a strong testing vibe in our community. It’s a frequent topic in local groups, conferences, and interviews. Even with that drive in our community it’s common to land projects that have no working tests.

If you are only used to unit testing then it may seem overbearing to trash the existing test suite and start fresh. That’s because it is! It is impractical to delay your project to comb through every class and define it’s behavior in a test.

Getting a test suite quickly is possible when approaching it from the angle of acceptance testing. Ensuring the details are working together instead of testing them independently.

For example, when you hit a piñata, do you get candy? We’re not ensuring the piñata is mounted, that it can take a couple of whacks, or that the candy is delicious. We have a working example and can assume those attributes are true. If one of them is off the entire process fails.

In a Ruby on Rails project I can spend an afternoon and get a decent coverage of an applications expected behavior. Here is a sample of testing a home page using Rspec.

I’m not testing for every working component . This asks if the someone requests the homepage, do they get the elements that make the homepage. It is much easier to do a quick analysis and implementation with this method. I don’t even have to look at the source code to define expected behavior and ensure it doesn’t change.

This has an advantage in a refactoring scenario. It doesn’t matter how much we change the underlying code, the results of the homepage are expected to the same. Having integration tests gives us the confidence to strip out any code and give us quick feedback on the consequences.

 

Quick Fixes With Vim And The Command Line

Vim allows you to perform external commands with the !(bang) operator. The most common use I see is when someone opens a file requiring sudo permissions. They don’t find out until they’ve made their changes and try to save.

Instead of losing the work and re-opening the file under sudo permissions you can save it with :w !sudo tee %. Nathan Long provides an explanation of what’s happening here on Stack Overflow.


I’ve been having issues with a local Ruby on Rails app for the past few days. It doesn’t have the records I expect it to. I’ve run the seed files and they are still missing.

I discovered the reason was that the slugs had been modified. Two months ago I refactored the seed files when I added data to them.

Original

content = Content.find_or_initialize_by(slug: 'easy-reading-title')
content.name = "Easy Reading Title"
content.save!

Refactored

assessment_generator = GenerateContent.new(
slug: 'brand-easy-reading-title',
title: "Easy Reading Title"
)

By refactoring procedural code to objects I could easily use macros to convert a spreadsheet into a seed file.

I’ve reduced this code for demonstrations but left my error in place. The slug changed to something it wasn’t supposed to. At first glance, my problem seems pretty large. I have to compare the current files to what they were months ago. They are completely different in structure and source lines of code.

For 30+ files the process is

  1. Open a file for editing.
  2. Open the file to it’s state two months ago in version control.
  3. Identify the original slug.
  4. Update the current files slug.

Using Vim and the External Command operator I can do this with efficiency. While having the current file open in vim I can type the following: /slug:<enter>:read !git show 0abbdaa37057d:% | grep -o "slug: '.*'" | sed 's/$/,/'<enter>==kdd:w<enter>

  • /slug: Find the first line containing ‘slug’ and put the cursor there.
  • :read !git show 0abbdaa37057d:% | grep -o “slug: ‘.*'” | sed ‘s/$/,/’
    • read: Write the input to current file.
    • !: Perform external command.
    • git show 0abbdaa37057d:%: Show the current file (%) at the state of commit 0abbdaa37057d.
    • |: Pipe operator, take the output from the git statement and input it into the grep.
    • grep -o “slug: ‘.*'”: Find a line containing ‘slug:’ with anything between two quotations. The -o flag tells grep to only return what matches in the pattern. This means instead of getting the entire line, we will just get the slug.
    • |: Pipe operator, take the output from grep and put it into sed.
    • sed ‘s/$/,/’: Append the line with a comma.

At this point we should have the incorrect slug followed by the correct slug.

slug: 'brand-easy-reading-title',
slug: 'easy-reading-title',

  • ==: Correctly indent the new ‘slug’ line.
  • k: Move the cursor up to the incorrect ‘slug’ line.
  • dd: Delete the incorrect ‘slug’ line.
  • :w: Save the changes.

To recap, we add the correct slug by retrieving from git, filtering it with grep, and correct syntax with sed. Then delete the old slug line.

Now that I have my macro I can perform it on all my seed files.

  • vim $(find db/seeds -type f): Open all my seed files in vim.
  • Copy my macro into a register ‘m’.
  • :argdo normal @m: In vim, perform the macro on every file.

Knowing Vim enables you to spend time on greater problems because it’s so easy to solve repetitive problems like this one. Having experience with the command line empowers the use of Vim in greater ways.

99 Bottles of OOP – Shameless Green

I’ve been reading through Katrina Owen’s and Sandi Metz’s latest book 99 Bottles of OOP. I have a history with Object Oriented languages and wasn’t sure what to expect but I have been pleasantly surprised.

99 Bottles starts with the Beer Song exercise over at Exercism.io. You are tasked to write a class that puts out the verses to ’99 bottles of beer’. There are 4 different solutions presented, all based on different needs.

The last example, Shameless Green, is the preferred. It’s redundant and has no scrap of DRY. However, it passes all the tests and is the easiest to read.

My solution extrapolated every duplication. The flog score for my code is 42.3 while the flog score of Shameless green is 29.3. That’s a significant difference.

This was very interesting to me and I think the authors pin me down in their summary:

“As programmers grow, they get better at solving challenging problems, and become comfortable with complexity. This higher level of comfort sometimes leads to the belief that complexity is inevitable, as if it’s the natural, inescapable state of all finished code. However, there’s something beyond complexity—a higher level of simplicity. Infinitely experienced programmers do not write infinitely complex code; they write code that’s blindingly simple.”

Excerpt From: Sandi Metz, Katrina Owen. “99 Bottles of OOP.”