How to write better rspec

How to describe your methods

Hãy rõ ràng về cách thức bạn viết describe. Ví dụ, dùng documentation convention Ruby của "." (Hoặc: 🙂 khi đề cập đến tên của một phương thức của lớp và # khi đề cập đến tên của một instance method’s name.
Bad example:

describe 'the authenticate method for User' do describe 'if the user is an admin' do 

Good example:

describe '.authenticate' do describe '#admin?' do 

Use contexts

Contexts là một cách thức mạnh mẽ để làm cho test của bạn rõ ràng và được tổ chức tốt. Về lâu dài việc dùng context sẽ giúp đỡ cho test của bạn dễ đọc hơn.
Bad example:

it 'has 200 status code if logged in' do   expect(response).to respond_with 200 end it 'has 401 status code if not logged in' do   expect(response).to respond_with 401 end 

Good example:

context 'when logged in' do   it { is_expected.to respond_with 200 } end context 'when logged out' do   it { is_expected.to respond_with 401 } end 

Single expectation test

dùng ‘one expectation’" được cho xem rộng rãi hơn là "mỗi test chỉ nên thực hiện một assertion". Điều này giúp đỡ bạn tìm ra lỗi có thể diễn ra, đi trực tiếp vào test fail và để làm cho code của bạn dễ đọc hơn.
Trong specs đơn vị cô lập, bạn muốn mỗi ví dụ để chỉ định một (và chỉ một) hành vi. Nhiều expectations trong cùng một ví dụ là một tín hiệu mà bạn có thể chỉ định nhiều hành vi.
Dù sao, trong những test không bị cô lập (ví dụ những bài cập nhật với một DB, một webservice bên ngoài, hay những test sau cùng), bạn sẽ đạt được hiệu suất lớn để thực hiện cùng một thiết lập lặp đi lặp lại, Một kỳ vọng khác nhau trong mỗi test. Trong những loại chạy thử chậm hơn, tôi nghĩ rằng nó tốt để chỉ định nhiều hơn một hành vi bị cô lập.
Good example(ISOLATED):

it { is_expected.to respond_with_content_type(:json) } it { is_expected.to assign_to(:resource) } 

Good example(NOT ISOLATED):

it 'creates a resource' do   expect(response).to respond_with_content_type(:json)   expect(response).to assign_to(:resource) end 

Test all possible cases

chạy thử là một thực hành tốt, nhưng nếu bạn không kiểm tra các hoàn cảnh phụ, nó sẽ không hữu ích. Kiểm tra hoàn cảnh hợp lệ, phụ và không hợp lệ. Ví dụ, hãy xem xét hành động sau đây.

DESTROY ACTION  before_filter :find_owned_resources before_filter :find_resource  def destroy   render 'show'   @consumption.destroy end 

Lỗi tôi thường thấy nằm trong test chỉ cho dù tài nguyên đã được xoá. Nhưng có ít nhất hai hoàn cảnh phụ: khi tài nguyên không được tìm thấy và khi nó không thuộc giữ của user thực hiện hành động xoá. Vậy nên bạn nên suy nghĩ đến tất cả các hoàn cảnh đầu vào và test chúng.
Good example:

describe '#destroy' do    context 'when resource is found' do     it 'responds with 200'     it 'shows the resource'   end    context 'when resource is not found' do     it 'responds with 404'   end    context 'when resource is not owned' do     it 'responds with 404'   end end 

Expect vs Should syntax

On new projects always use the expect syntax.
Bad example:

it 'creates a resource' do   response.should respond_with_content_type(:json) end 

Good example:

it 'creates a resource' do   expect(response).to respond_with_content_type(:json) end 

Configure the Rspec to only accept the new syntax on new projects, to avoid having the 2 syntax all over the place.
Good example:

# spec_helper.rb RSpec.configure do |config|   # ...   config.expect_with :rspec do |c|     c.syntax = :expect   end end 

On one line expectations or with implicit subject we should use is_expected.to.
Bad example:

context 'when not valid' do   it { should respond_with 422 } end 

Good example

context 'when not valid' do   it { is_expected.to respond_with 422 } end 

reference:
https://github.com/reachlocal/rspec-style-guide
http://www.betterspecs.org/ ,

Nguồn viblo.asia