rspec - stoa social · rspec hooks run automatically at specific times during testing helper...

34
RSpec Based on the book “Effective Testing with RSpec 3”

Upload: others

Post on 05-Jun-2020

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec

Based on the book “Effective Testing with RSpec 3”

Page 2: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec

● RSpec is a productive Ruby test framework● Use natural (English) language to define tests● Support the Behaviour Driven Development● Support you to write test that:

○ Pays for the cost of writing and running it○ Helps you to design your code○ Helps you finding errors in your code

Page 3: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec GEMS

● RSpec is made of three independent Ruby Gems○ RSpec::Core is the overall test infrastructure that runs

your specs○ RSpec::Expectations provides a readable, powerful

syntax for checking properties of your code○ RSpec::Mocks makes it easy to isolate the code you’re

testing from the rest of the system

Page 4: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Setup

Install a recent ruby version: $ rvm install 2.4.0

Install bundler: $ gem install bundler

Create a new folder for your project: $ mkdir my-project && cd my-project

Create a Gemfile with the following content:

Run bundler $ bundle install

Page 5: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

First RSpec

● Let’s create a bowling game!

● To design it, we basically describe a bowling game and its features

○ Describe a normal bowling game

○ It has 10 pins

○ It allows players to hit the available pins

○ It computes the score based on the sequence of plays

Page 6: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

First RSpec

Setup rspec: $ rspec --init

Create the Bowling class in lib/bowling.rb file with the following content:

Page 7: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

First RSpec

Run the test: $ rspec

Create a rspec for the Bowling class in spec/bowling_spec.rb file with the following content:

Page 8: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

First RSpec

● Implement the missing code and run the test again. It should pass =)● If you intend to make improvements to your code structure, you can do it

safely now● This is how TDD cycle works

Page 9: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec Structure

● Each spec file has the specifications of the desired behaviour of your code● RSpec.describe block creates an example group that defines what you’re

testing (i.e. bowling)● The it block is an example of the bowling use (similar to a test case)● The expect verifies an expected outcome (similar to assertion)

Page 10: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec Structure

● Each spec file has the specifications of the desired behaviour of your code● RSpec.describe block creates an example group that defines what you’re

testing (i.e. bowling)● The it block is an example of the bowling use (similar to a test case)● The expect verifies an expected outcome (similar to assertion)

It reads almost like spoken

English

Page 11: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

More examples

● The following code describes how to add a new player to the bowling game

● As you write more specs, you’ll find yourself repeating setup code● You can share setup across examples through:

○ RSpec hooks run automatically at specific times during testing○ Helper methods are regular Ruby methods; you control when they run○ RSpec’s let construct removes some of the gotchas around helper

methods

Page 12: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec Hook

● before hook adds a block that will run automatically before each example

● The setup code is shared across specs, but the individual Bowling instance is not

Page 13: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec Hook

● There are three types of hooks in RSpec○ before - defines a block of code to be run before a set of examples○ after - defines a block of code to be run after a set of examples, even if

the example fails○ around - part of the hook runs before the example, and part runs after

Page 14: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Helper Methods

● Hooks will run for all examples, even if it’s not necessary

● Instead, you may write helper methods and call it where you need

Page 15: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Sharing Objects with let

● let defines a binding name (bowling) to the result of a computation (the block)

● RSpec will run the block the first time any example calls bowling

Page 16: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec context block

● When you use RSpec on a real-world project, you’ll build up a suite of many examples

● To improve our spec code and output, we can group a set of related examples and their setup code together with a common description

Page 17: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

RSpec context block

The output tells us exactly what behavior is failing:

Page 18: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Running spec tips

Output with documentation format $ rspec --format documentation

List the top time-waster examples $ rspec --profile 2

Run specific specs in a folder $ rspec spec/unit

Run specific specs in a file $ rspec spec/unit/specific_spec.rb

Run specific example in a file $ rspec spec/unit/specific_spec.rb:25

Run specific example by name $ rspec -e milk -fd

Page 19: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Exploring RSpec::Expectations

● Expectations express what you expect to be true at a specific point in your code

● The primary goal of RSpec::Expectations is clarity● Try reading the following examples out loud

Page 20: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Parts of an Expectation

The syntax of a expectation consist of three main parts:

Subject - the thing you’re testing; i.e., an instance of a Ruby class

Page 21: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Parts of an Expectation

The syntax of a expectation consist of three main parts:

Subject - the thing you’re testing; i.e., an instance of a Ruby class

Matcher - an object which specifies what you expect to be true about the subject, and provides the pass/fail logic

Page 22: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Parts of an Expectation

The syntax of a expectation consist of three main parts:

Subject - the thing you’re testing; i.e., an instance of a Ruby class

Matcher - an object which specifies what you expect to be true about the subject, and provides the pass/fail logic

(Optionally) - a custom failure message

Page 23: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Equality and Identity

● Identity: e.g., two references to one object

● Value equality: two objects of compatible types with the same meaning; e.g., the integer 42 and the floating-point number 42.0

Page 24: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Truthiness

● The objects false and nil are both treated as false● Everything else is treated as true

Page 25: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Truthiness

● The objects false and nil are both treated as false● Everything else is treated as true

If you want to specify that a value is precisely equal to true or false:

Page 26: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Operator Comparisons

● You can use the comparison operators implemented by objects

Page 27: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Higher-Order

● Higher-order matchers are matchers that you can pass other matchers into● With this technique, you can build up composed matchers that specify exactly

the behavior you want

Page 28: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - start_with, end_with and all

● Useful when you care about the contents of a string or collection

Page 29: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - match

● If you call JSON or XML APIs, you often end up with deeply nested arrays and hashes

● For this purpose, you can use match rathern than eq

Page 30: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Mutation

● It’s common for external actions—such as submitting a Web form—to change some state inside the system

● The change matcher helps you specify these sorts of mutations by:

1. Run your change block and store the result, array.size , as the before value

2. Run the code under test, array << 43. Run your change block a second time

and store the result, array.size, as the after value

4. Pass the spec if the before and after values are different

Page 31: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Mutation with details

● The change matcher offers an easy way to give details about the change

Page 32: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Matchers - Others

● Ranges:

● A predicate is a method that answers a question with boolean answer, usually ends with a question mark. I.E., empty?

● RSpec supports dynamic matchers with predicate methods

Page 33: RSpec - Stoa Social · RSpec hooks run automatically at specific times during testing Helper methods are regular Ruby methods; you control when they run RSpec’s let construct removes

Subject

● The subject method defines how to build the object we’re testing● RSpec gives us is_expected as shorthand for expect(subject)