### Guardfile Configuration for RSpec Source: https://www.betterspecs.org/index Provides an example of a Guardfile configuration to automate the RSpec test suite. Guard runs only the tests related to the changed files, improving workflow efficiency. ```ruby # Guardfile require 'guard/rspec' guard :rspec, cmd: 'bundle exec rspec' do watch(%r{^spec/.*_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m|"spec/#{m[1]}_spec.rb" } watch(%r{^app/(.+)\.rb$}) { |m|"spec/#{m[1]}_spec.rb" } end ``` -------------------------------- ### RSpec: Shared Examples for DRY Tests Source: https://www.betterspecs.org/index Explains the concept and utility of shared examples in RSpec to eliminate code duplication and keep the test suite DRY. It notes that shared examples are particularly useful for controllers. ```ruby # spec/support/shared_examples/unauthorized_access.rb RSpec.shared_examples 'unauthorized access' do |resource| it 'returns unauthorized status' do expect(response).to have_http_status(:unauthorized) end end # spec/controllers/posts_controller_spec.rb RSpec.describe PostsController do it_behaves_like 'unauthorized access', :post end ``` -------------------------------- ### Ruby RSpec let and let! Usage Source: https://www.betterspecs.org/index Explains the difference between `let` (lazy evaluation and caching) and `let!` (eager evaluation) in RSpec for variable assignment and setup. ```Ruby # Using let (lazy evaluation) let(:user) { User.create(name: 'Test') } it 'does something with the user' do expect(user.name).to eq('Test') # user is created here end # Using let! (eager evaluation) let!(:post) { Post.create(title: 'Example') } it 'exists' do expect(Post.count).to eq(1) # post is created before this test runs end ``` -------------------------------- ### Ruby RSpec Context Usage Source: https://www.betterspecs.org/index Illustrates how to use contexts in RSpec to organize tests and make them more readable. Context descriptions should start with 'when', 'with', or 'without'. ```Ruby describe 'Array' do context '#push' do it 'adds an element to the end' do # ... end end context '#pop' do it 'removes the last element' do # ... end end end ``` -------------------------------- ### RSpec: Faster Tests with Zeus and Guard Source: https://www.betterspecs.org/index Shows how to configure Guard to work with Zeus for faster test execution by preloading the Rails environment. Notes the requirements for Zeus, such as Ruby version and OS support. ```ruby # Guardfile (with Zeus) require 'guard/rspec' guard :rspec, cmd: 'zeus test' do watch(%r{^spec/.*_spec\.rb$}) watch(%r{^app/controllers/(.*)\.rb$}) { |m| "spec/controllers/#{m[1]}_spec.rb" } # ... other watches end # To run tests: # 1. Start Zeus server: zeus start # 2. Run Guard: bundle exec guard ``` -------------------------------- ### Ruby RSpec Expect vs Should Syntax Source: https://www.betterspecs.org/index Shows the recommended 'expect' syntax for RSpec, contrasting it with the older 'should' syntax. Configuration advice is provided for new projects. ```Ruby # Bad it 'should be valid' do expect(model).to be_valid end # Good it 'is valid' do expect(model).to be_valid end # One line expectation it { is_expected.to be_valid } ``` -------------------------------- ### RSpec: Faster Tests with Spork and Guard Source: https://www.betterspecs.org/index Details how to use Spork (or similar tools like Zeus, Spin) in conjunction with Guard to speed up RSpec tests by preloading the Rails application. Includes a sample spec_helper and Guardfile configuration. ```ruby # spec/spec_helper.rb (with Spork) require 'spork' Spork.prefork do # Loading more in this block will cause you to go through # the process of restarting Spork each time you modify this # file. cf. http://github.com/spork/spork/wiki/Spork-and-Rails require 'rails/application' unless Rails.root.join('tmp', 'pids', 'spork.pid').exist? system("bundle exec spork") end Spork.each_run do FactoryBot.reload # This code will be run each time you do `rails console` or `rails server` end end # Guardfile (with Spork) require 'guard/rspec' guard :rspec, cmd: 'bundle exec spork rspec' do watch(%r{^spec/.*_spec\.rb$}) watch(%r{^app/models/(.*)\.rb$}) { |m| "spec/models/#{m[1]}_spec.rb" } # ... other watches end ``` -------------------------------- ### RSpec: Using Factories instead of Fixtures Source: https://www.betterspecs.org/index Demonstrates the recommended approach of using factories (like FactoryBot) for creating test data instead of fixtures, which are considered harder to control. It emphasizes reducing verbosity in data creation. ```ruby RSpec.describe User do let(:user) { create(:user) } # Using FactoryBot it 'does something' end ``` -------------------------------- ### Stubbing HTTP Requests with Webmock Source: https://www.betterspecs.org/index This snippet demonstrates how to stub external HTTP requests using the webmock library, which is crucial when the real service cannot be relied upon during testing. It often works in conjunction with VCR. ```ruby require 'webmock/rspec' ``` -------------------------------- ### Ruby RSpec Method Naming Convention Source: https://www.betterspecs.org/index Demonstrates the correct convention for referring to Ruby methods in RSpec descriptions. Use '.' for class methods and '#' for instance methods to clearly distinguish them. ```Ruby describe MyClass do describe '.class_method' do # ... end describe '#instance_method' do # ... end end ``` -------------------------------- ### RSpec: Readable Matchers Source: https://www.betterspecs.org/index Highlights the importance of using clear and readable matchers provided by RSpec to improve test clarity. It encourages exploring the available RSpec matchers. ```ruby RSpec.describe 'String manipulation' do it 'reverses a string correctly' do expect(reverse_string('hello')).to eq('olleh') end it 'checks if a string is empty' do expect('').to be_empty end end ``` -------------------------------- ### Ruby RSpec Subject Usage Source: https://www.betterspecs.org/index Demonstrates how to use `subject` in RSpec to reduce redundancy when multiple tests relate to the same object or value. ```Ruby # Bad describe 'User' do it 'is active' do user = User.new(active: true) expect(user.active?).to be_truthy end it 'has a name' do user = User.new(name: 'Test') expect(user.name).to eq('Test') end end # Good describe 'User' do subject { User.new(name: 'Test', active: true) } it 'is active' do expect(subject.active?).to be_truthy end it 'has a name' do expect(subject.name).to eq('Test') end end ``` -------------------------------- ### RSpec: Testing Observable Behavior (Integration Tests) Source: https://www.betterspecs.org/index Advocates for focusing integration tests on observable application behavior (what the user sees) rather than low-level controller logic. It suggests that most tests naturally fall into models and integration tests. ```ruby require 'rails_helper' RSpec.describe 'User registration flow', type: :feature do scenario 'User successfully registers' visit '/users/new' fill_in 'Name', with: 'Test User' fill_in 'Email', with: 'test@example.com' click_button 'Sign up' expect(page).to have_content('Welcome, Test User!') end end ``` -------------------------------- ### RSpec: Avoiding 'should' Syntax Source: https://www.betterspecs.org/index Recommends against using the 'should' syntax in RSpec tests, favoring the third-person present tense and the newer expectation syntax. It mentions gems like `should_not` and `should_clean` for enforcement. ```ruby RSpec.describe Calculator do it 'adds two numbers' do # Old syntax (avoid) # expect(Calculator.new.add(2, 3)).should eq(5) # New syntax (preferred) expect(Calculator.new.add(2, 3)).to eq(5) end end ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.