theory rspec Flashcards

You may prefer our related Brainscape-certified flashcards:
1
Q

RSpec

A

RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

red-green loop

A
  • Write the smallest possible test case that matches what we need to program.
  • Run the test and watch it fail. This gets you into thinking how to write only the code that makes it pass.
  • Write some code to make the test pass.
  • Run your test suite. Repeat steps 3 and 4 until all tests pass.
  • Go back and refactor your new code, making it as simple and clear as possible while keeping the test suite green.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

describe block

A

We are using another describe block to describe the add class method. By convention, class methods are prefixed with a dot (“.add”), and instance methods with a dash (“#add”).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

context block

A

We are using a context block to describe the context under which the add method is expected to return zero. context is technically the same as describe, but is used in different places, to aid reading of the code.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

it block

A

We are using an it block to describe a specific example, which is RSpec’s way to say “test case”. Generally, every example should be descriptive, and together with the context should form an understandable sentence. This one reads as “add class method: given an empty string, it returns zero“.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

expect(…).to and the negative variant expect(…).not_to

A

expect(…).to and the negative variant expect(…).not_to are used to define expected outcomes. The Ruby expression they are given (in our case, StringCalculator.add(“”)) is combined with a matcher to fully define an expectation on a piece of code. The matcher we are using here is eq, a basic equality matcher.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

purposes of specs

A

1) to drive development, and 2) as a verification mechanism.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Specs Directory Structure

A

Model specs reside in the spec/models directory

Controller specs reside in the spec/controllers directory

Request specs reside in the spec/requests directory. The directory can also be named integration or api.

Feature specs reside in the spec/features directory

View specs reside in the spec/views directory

Helper specs reside in the spec/helpers directory

Mailer specs reside in the spec/mailers directory

Routing specs reside in the spec/routing directory

Job specs reside in the spec/jobs directory

System specs reside in the spec/system directory

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Model specs

A

A model spec is a thin wrapper for an ActiveSupport::TestCase, and includes all
of the behavior and assertions that it provides, in addition to RSpec’s own
behavior and expectations.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Controller specs

A

It allows you to simulate a single http request in each example, and then
specify expected outcomes such as:

rendered templates
redirects
instance variables assigned in the controller to be shared with the view
cookies sent back with the response

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Request spec

A

Request specs provide a thin wrapper around Rails’ integration tests, and are
designed to drive behavior through the full stack, including routing
(provided by Rails) and without stubbing (that’s up to you).
With request specs, you can:

specify a single request
specify multiple requests across multiple controllers
specify multiple requests across multiple sessions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Feature spec

A

Feature specs are high-level tests meant to exercise slices of functionality
through an application. They should drive the application only via its external
interface, usually web pages.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

View spec

A

Use them to test the content of view templates
without invoking a specific controller.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Helper spec

A

Helper specs expose a helper object, which includes the helper module being
specified, the ApplicationHelper module (if there is one) and all of the
helpers built into Rails. It does not include the other helper modules in
your app.

To access the helper methods you’re specifying, simply call them directly
on the helper object.

NOTE: helper methods defined in controllers are not included.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Mailer specs

A

A mailer spec is a thin wrapper for an ActionMailer::TestCase, and includes all
of the behavior and assertions that it provides, in addition to RSpec’s own
behavior and expectations.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Routing specs

A

Simple apps with nothing but standard RESTful routes won’t get much value from
routing specs, but they can provide significant value when used to specify
customized routes, like vanity links, slugs, etc.

17
Q

Job spec

A

Job specs provide alternative assertions to those available in ActiveJob::TestHelper and help assert behaviour of the jobs themselves and that other entities correctly enqueue them.
With job specs, you can:

specify the job class which was enqueued
specify the arguments passed to the job
specify when the job was enqueued until
specify the queue which the job was enqueued to

18
Q

System spec

A

System specs are RSpec’s wrapper around Rails’ own
system tests.

System tests allow you to test user interactions with your application,
running tests in either a real or a headless browser. System tests use
Capybara under the hood.

By default, system tests are run with the Selenium driver, using the
Chrome browser, and a screen size of 1400x1400. The next section explains
how to change the default settings.

19
Q

What is Better Specs

A

Describe Your Methods
Use contexts
Keep your description short
Single expectation test
Test all possible cases
Expect vs Should syntax
Use subject
Use let and let!
Mock or not to mock
Create only the data you need
Use factories and not fixtures
Easy to read matchers
Shared Examples
Test what you see
Don’t use should
Automatic tests with guard
Faster tests (preloading Rails)
Stubbing HTTP requests
Useful formatter

20
Q

Describe Your Methods

A

Be clear about what method you are describing. For instance, use the Ruby documentation convention of . (or ::) when referring to a class method’s name and # when referring to an instance method’s name.

21
Q

Use contexts

A

Contexts are a powerful method to make your tests clear and well organized (they keep tests easy to read). When describing a context, start its description with ‘when’, ‘with’ or ‘without’.

22
Q

Keep your description short

A

A spec description should never be longer than 40 characters. If this happens you should split it using a context.

23
Q

Single expectation test

A

The ‘one expectation’ tip is more broadly expressed as ‘each test should make only one assertion’. This helps you on finding possible errors, going directly to the failing test, and to make your code readable. In isolated unit specs, you want each example to specify one (and only one) behavior. Multiple expectations in the same example are a signal that you may be specifying multiple behaviors.
Anyway, in tests that are not isolated (e.g. ones that integrate with a DB, an external webservice, or end-to-end-tests), you take a massive performance hit to do the same setup over and over again, just to set a different expectation in each test. In these sorts of slower tests, I think it’s fine to specify more than one isolated behavior.

24
Q

Test all possible cases

A

Testing is a good practice, but if you do not test the edge cases, it will not be useful. Test valid, edge and invalid case. For example, consider the following action.
The error I usually see lies in testing only whether the resource has been removed. But there are at least two edge cases: when the resource is not found and when it’s not owned. As a rule of thumb think of all the possible inputs and test them.

25
Q

Expect vs Should syntax

A

On new projects always use the expect syntax.
Configure the RSpec to only accept the new syntax on new projects, to avoid having the 2 syntax all over the place.

26
Q

Use subject

A

If you have several tests related to the same subject use subject{} to DRY them up.
RSpec has also the ability to use a named subject (learn more about rspec subject).

27
Q

Use let and let!

A

When you have to assign a variable instead of using a before block to create an instance variable, use let. Using let the variable lazy loads only when it is used the first time in the test and get cached until that specific test is finished. A really good and deep description of what let does can be found in this stackoverflow answer.
Use let to initialize actions that are lazy loaded to test your specs.
Use let! if you want to define the variable when the block is defined. This can be useful to populate your database to test queries or scopes. Here an example of what let actually is (learn more about rspec let).

28
Q

Mock or not to mock

A

As general rule do not (over)use mocks and test real behavior when possible, as testing real cases is useful when validating your application flow.
Mocking makes your specs faster but they are difficult to use. You need to understand them well to use them well.

29
Q

Create only the data you need

A

If you have ever worked in a medium size project (but also in small ones), test suites can be heavy to run. To solve this problem, it’s important not to load more data than needed. Also, if you think you need dozens of records, you are probably wrong.

30
Q

Use factories and not fixtures

A

This is an old topic, but it’s still good to remember it. Do not use fixtures because they are difficult to control, use factories instead. Use them to reduce the verbosity on creating new data (learn about Factory Bot).
One important note. When talking about unit tests the best practice would be to use neither fixtures or factories. Put as much of your domain logic in libraries that can be tested without needing complex, time consuming setup with either factories or fixtures.

31
Q

Easy to read matchers

A

Use readable matchers and double check the available rspec matchers.

32
Q

Shared Examples

A

Making tests is great and you get more confident day after day. But in the end you will start to see code duplication coming up everywhere. Use shared examples to DRY your test suite up.

33
Q

Test what you see

A

Deeply test your models and your application behaviour (integration tests). Do not add useless complexity testing controllers.

When I first started testing my apps I was testing controllers, now I don’t. Now I only create integration tests using RSpec and Capybara. Why? Because I believe that you should test what you see and because testing controllers is an extra step you wont usually need. You’ll find out that most of your tests go into the models and that integration tests can be easily grouped into shared examples, building a clear and readable test suite.

This is an open debate in the Ruby community and both sides have good arguments supporting their idea. People supporting the need of testing controllers will tell you that your integration tests don’t cover all use cases and that they are slow. Both are wrong. You can easily cover all use cases (why shouldn’t you?) and you can run single file specs using automated tools like Guard. In this way you will run only the specs you need to test blazing fast without stopping your flow.

34
Q

Don’t use should

A

Do not use should when describing your tests. Use the third person in the present tense. Even better start using the new expectation syntax.

35
Q

Automatic tests with guard

A

Running all the test suite every time you change your app can be cumbersome. It takes a lot of time and it can break your flow. With Guard you can automate your test suite running only the tests related to the updated spec, model, controller or file you are working at.
Guard is a fine tool but as usual it doesn’t fit all of your needs. Sometimes your TDD workflow works best with a keybinding that makes it easy to run just the examples you want when you want to. Then, you can use a rake task to run the entire suite before pushing code.

36
Q

Faster tests (preloading Rails)

A

When running a test on Rails the whole Rails app is loaded. This can take time and it can break your development flow. To solve this problem use solutions like Zeus, Spin or Spork. Those solutions will preload all libraries you (usually) do not change and reload controllers, models, view, factories and all the files you change most often.

Here you can find a spec helper and a Guardfile configuration based on Spork. With this configuration you will reload the whole app if a preloaded file (like initializers) change and you will run the single tests really, really fast.

The drawback of using Spork is that it aggressively monkey-patches your code and you could lose some hours trying to understand why a file is not reloaded. If you have some code examples using Spin or any other solution let us know.

Here you can find a Guardfile configuration for using Zeus. The spec_helper does not need to be modified, however, you will have to run zeus start in a console to start the zeus server before running your tests. Although Zeus takes a less aggressive approach than Spork, one major drawback is the fairly strict usage requirements; Ruby 1.9.3+ (recommended using backported GC from Ruby 2.0) as well as an operating system that supports FSEvents or inotify is required.

Many criticisms are moved to those solutions. Those libraries are a band aid on a problem that is better solved through better design, and being intentional about only loading the dependencies that you need.

37
Q

Stubbing HTTP requests

A

Sometimes you need to access external services. In these cases you can’t rely on the real service but you should stub it with solutions like webmock.

38
Q

Useful formatter

A

Use a formatter that can give you useful information about the test suite. I personally find fuubar really nice. To make it work add the gem and set fuubar as default formatter in your Guardfile.