Creating an RSpec Test — A Brief History + Cheatcheat

What is RSpec and a quick guide to creating your first RSpec test

SO, I decided to take a dive into learning RSpec and hopefully by the end of my journey I can get learn more about the green and annoying red lights. (Note: all i can think about is John Legend’s- Green Light)

What will be covered

  • What is RSPEC
  • Quick History
  • Why use RSpec
  • Why Software testing is important
  • How to write Good Tests
  • What to test
  • How to Get Started/Syntax
  • Quick Guide to creating an RSpec test for a Palindrome

How my journey started:

What is RSpec?

  • RSpec is a testing framework.
  • It is a mash-up of R(uby) and short for Spec(ifications). Ruby Specs
  • it allows for executable code to run and check whether it returns the expected behavior. i.e. true or false.

In a nutshell,

  • When you provide context
  • If/When some event occurs
  • Then what is the outcome that I expect to occur.

RSpec History

  • Written in Ruby, so you must know Ruby in order to use it.
  • Created in 2005 by Steven Baker
  • Uses domain-specific language(DSL)- meaning we need to write code in a way that RSpec will accept not just in Ruby.
  • Used for Ruby on Rails mostly, but can be used for Ruby as well.

Why use RSpec?

  • If you have coded in the past you have done code testing/debugging on your own code by inputting data and seeing if the test either passes or fails based on the inputs that were given.
  • RSpec allows coders to write out test to account for all testing inputs as well as edge cases without having to manually keep testing for the different inputs that are provided.
  • Tests could be thought of as Stories/Scenarios that use the keywords Given, When, Then.

Why should we care about writing Software tests?

First, why would you not want to write tests?

  • Writing tests requires more time
  • Time is money.
.

Now, why should we write tests?

  • Most important: TO FIND BUGS
  • Critical thinking- it allows you to think about what you expect your code to do and also to find those edge cases that could potentially brake your code.
  • Manual testing may only test once for those edge cases.
  • Exposes poor code
  • Code Smells- it could meant that you are not following the DRY principles or that a bigger issue may be present within your code.
  • Allows for easier time to refactor/improve code.
  • Easier to improve features and software.

Saves Time

  • In the long run, it saves time that would need for the same tests to be run again once code has been refactored or fixed.
  • Allows others to run your test code, including edge cases, rather than have others think of the same edge cases you have already accounted for.

How to write good Tests

Creating a User Story

A user story is a basic template on how to use the GIVEN, WHEN, and THEN keywords to create RSpec tests.

Template:

  • GIVEN x scenario, WHEN x is happening, THEN do x scenario based on WHEN.
  • Great communication tool with developers and clients.

Example:

  • GIVEN that a user is not logged in
  • WHEN the user visits the login page
  • THEN the user should be able to see the form fields for username, password, and a submit button.

What to test?

  • Test only the parts that need to work.
  • Depends on your preference and comfort level — What parts of the software should we test on to make sure we are covering the most critical parts.
  • Depends on complexity and risk involved. — if a user is trying to sign up for blog updates and a user is trying to sign up for an account. Signing up for an account would take priority over signing up for blog updates because if users can’t sign up for an account then they can’t use the app.
  • Existing code? Write tests based on priorities, i.e. being able to make purchases, Credit Card encryption is working, login credentials are being saved.
  • Valid path? Good Data — If the inputs are valid is the user reaching the page you want them to reach?
  • Invalid Path? Bad Data — if the inputs are invalid are they getting the appropriate warning/alerts?
  • Edge Cases? Not too often, less important, but can be necessary.
  • Test for fixed bugs so it does not happen again.

What Not to test?

  • Don’t test basic ruby. — Ex. making sure a string is being upcase-d or downcase-d.
  • Don’t test Basic Ruby on Rails — Don’t test application framework since RoR already has it’s own tests.
  • Don’t test most Third Party API’s — most api’s can handle their own data as long as we pass in good data
  • Don’t repeat testing that is already being tested somewhere else — if a method is already being tested to output the correct info we do not need to test it again when that input gets passed onto another method/area.

Other

  • Bad, partial, or incomplete tests can be worse than none — Make sure your tests are relevant and working as needed.
  • Keep test suite fast; you will run it more often
  • Run tests often
  • Commit to keeping all tests passing
  • Avoid easily breakable tests.

RSpec Cheatsheet

Setting up Ruby project with rspec:
rspec --init
Will create the template files needed to have rspec used.
--no-color, --color 
"Provides color output of red and green showing if the test passed or failed"
--format progress 
"Will show dots of failed/passed tests"
--format documentation 
"Will give you failure messages and passes on which tests failed/passed (recommended)"
--no-profile, --profile
--no-fail-fast, --fail-fast (--f-f)
If you want to fail more than 1 item you can add a number
"--f-f=#number", ex :--f-f=3
--order defined => Runs tests in the predefined method
--order random => Will run tests randomly
Single tests can be ran by running the test file and appending a ":" followed by the test file line.
“example_spec.rb:7” 
7 being the line the test starts on.

Getting Started

  1. Go to your project folder
  2. You will run “rspec init” and it will create the folders needed
Project_folder
----.rspec (created with "rspec --init")
----lib
--------main.rb
----spec (created with "rspec --init")
--------spec_helper.rb (created with "rspec --init")
--------main_spec.rb (created by you)
**within main_spec.rb you will need to add the following line**
---require "main"

Syntax

The following section will cover the basic syntax on how to create a basic rspec and what each of it’s components accomplishes.

NOTE: Using “should” is deprecated in newer rspec versions. You may see it on older RSpec tests, but it should not be used. Should was deprecated since it needed to account for strings, integers, classes, etc.

it ‘does not allow negative values’
  1. First, describe covers the class/file we are working with and are describing.
  2. The second describe will provide details on the method and a block statement.
  3. Within the block we write our first test.
  4. it let’s rspec know is the beginning of the first matcher we are testing for.
  5. ‘it’ is followed by what we expect it to do in plain text (you write this portion out as if you were saying it out loud)
  • pass the parameter/data/string/etc. we will be testing
  • expect(the method).to — what we are checking
  • match_array/puts/not_
describe 'Main' do
describe '.options' do 
it "returns an array of available options" do
opt = ["first","second","third","4th"]
expect(Main.options).to match_array(opt)
end 
end
end

Basic syntax on what our code should or should not do

  • expect ( ).to( ) #followed by what you are expecting it to do (i.e. match, equal, match_array, etc.
  • expect ( ).not_to( )

RSpec Hierarchy

  • spec_file — main_spec.rb
  • — example_group — — describe
  • — — — nested group — — describe/ context
  • — — — — example — — — — it
  • — — — — — expectations — — — expect().to()

Creating an RSpec Test

Besides researching and learning about RSpec tests I decided to write my own test for the following:

  • Given a string
  • When the string gets passed into the palindrome method
  • Then it should return true if it is a palindrome, false if it is not.

First, I created a project, a palindrome.rb file, and added the palindrome method. The next two images show my initial code and my refactored code once all tests were passing.

Refactored:

Next, I created my rspec file using the terminal and typing in:

rspec --init
Which created the rspec files I needed

Then, using the cheat-cheat mentioned above I added some formats to the .rspec file in order to get the correct appearance that we have grown to love within the Learn.co labs.

  • color provides the green/red lights
  • format documentation provides a list of the tests with the appropriate color.

Writing my tests:

After thinking of different types of inputs I needed to account for I created 3 tests. Below are results that rspec provided when I ran ‘rspec’ in the terminal.

I ended up writing incorrect tests. The test was supposed to return true or false, but it returned a string. Since it was the first tests I wrote I had to play around with the outputs and how to best write all cases.

Example of how first tests were written. eq() should be eq(true)

I went back and fixed the expected values and wrote more tests. The first tests were to make sure if the string that I was passing it would return true.

Then I wrote bad data to test that it would not return true if the string was not a palindrome.

Finally, I got them green lights we keep searching for:

What I learned

  • Current tests descriptions could use improvements.
  • Setup and syntax of RSpec.
  • How to configure my rspec testing.
  • History and why we should write software tests.
  • Becoming familiar with the format and other options can be beneficial.

For the future

  • Create a part 2 expanding on rspec and trying more complicated test statements
  • Becoming more familiar with the syntax and testing options available.
  • Adding rspec tests to upcoming projects.

SOURCES