世界上最伟大的投资就是投资自己的教育

全场限时 5 折

首页Ruby
随风 · 练气

RSpec 全套测试环境搭建从零入门

随风发布于2403 次阅读

1. 缘起

要帮朋友的项目搭一套测试环境,选用了 rspec 作为测试环境,在搭建的过程中记录整个过程,以后让这种重复的工作简单点,不想又造轮子。

2. 能学到什么

  • 各种 rspec 测试标配
  • 使用 spring 加速测试过程,也会和 guard 结合,加速 guard 的运行过程
  • 使用 guard 让文件一保存就自动测试
  • 使用 capybara 写类似于 cucumber 的 feature 测试

3. 安装过程

由于guard的安装需要高版本的 ruby 支持,建议使用 ruby 2.3.0 以上。

首先安装rspec这个 gem,我们选用的是适合 rails 项目的rspec-rails这个 gem。

3.1 rspec-rails

在 Gemfile 文件里加入下面这几行:

group :development, :test do
  gem 'rspec-rails', '~> 3.4'
end

执行bundle install安装。

装好之后,执行下面的两行命令,生成必要的配置文件。

rails generate rspec:install
bundle binstubs rspec-core
3.2 factory_girl_rails

factory_girl_rails是一个代替测试夹具 (Fixtures) 的工具,用它可以在测试的时候造一些实例。

group :development, :test do
  gem 'factory_girl_rails'
end

执行bundle install安装。

接下来找到spec/rails_helper.rb文件的下面一行,把其删除或注释掉。

config.use_transactional_fixtures = true

并且增加下面一行。

config.include FactoryGirl::Syntax::Methods

再到config/application.rb文件中,添加下面几行:

config.generators do |g|
  g.test_framework :rspec,
    fixtures: true,
    view_specs: false,
    helper_specs: false,
    routing_specs: false,
    request_specs: false
  g.fixture_replacement :factory_girl, dir: 'spec/factories'
end

为了方便后绪的 demo 测试,现在我们都可以生成一个夹具文件,名字叫users.rb,位于spec/factories

FactoryGirl.define do
  factory :user do
    email                    'user@example.com'
    username                 'name'
    password                 'password'
  end
end
3.3 database_cleaner

database_cleaner是一个自动清除数据库数据的工具,每次运行完测试用例它就会自动清除数据库。

Gemfile中添加下面几行。

group :test do
  gem 'database_cleaner'
end

执行bundle install安装。

然后在spec/rails_helper.rb文件中添加下面几行:

config.before(:suite) do
  DatabaseCleaner.strategy = :transaction
  DatabaseCleaner.clean_with(:truncation)
end

config.around(:each) do |example|
  DatabaseCleaner.cleaning do
    example.run
  end
end

到现在为止,已经能够正常跑测试了,我们来写一个测试案例,让它跑起来。

新建文件spec/models/user_spec.rb,内容如下:

require 'rails_helper'

RSpec.describe User, type: :model do
  let(:user) { create :user }

  describe '#email' do
    context '有效的邮箱' do
      addresses = %w( user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn )
      addresses.each do |valid_address|
        let(:user) { build(:user, email: valid_address) }
        it { expect(user.valid?).to eq true }
      end
    end

    context '空' do
      let(:user) { build(:user, email: '') }
      it { expect(user.valid?).to eq false }
    end

    context '错误邮箱格式' do
      addresses = %w{ invalid_email_format 123 $$$ () ☃ bla@bla. }
      addresses.each do |invalid_address|
        let(:user) { build(:user, email: invalid_address) }
        it { expect(user.valid?).to eq false }
      end
    end

    context '重复' do
      let(:user_with_same_username) { build :user, username: user.username }
      it { expect(user_with_same_username.valid?).to eq false }
    end
  end
end

可以使用bundle exec rspec spec/models/user_spec.rb来测试这个刚才写的测试案例。

你会发现运行起来还是比较慢的。

接下来我们使用spring来加速测试的运行。

3.4 spring-commands-rspec

spring是 rails 默认就有的,而spring-commands-rspec是让springrspec结合起来。

Gemfile中添加下面这行:

gem 'spring-commands-rspec', group: :development

接着执行bundle exec spring binstub rspec这条指令。

现在我们就可以使用bundle exec spring rspec来加速测试的运行了。

3.5 guard

guard是一个让你一修改测试文件,就自动跑测试的工具。

需要注意的是guard需要高版本的 ruby 支持,目前为止,它官方写的是至少需要 ruby 2.2.5 以上

Gemfile中添加下面几行:

group :development do
  gem 'guard'
  gem 'guard-rspec', require: false
  gem 'guard-bundler', require: false
end

至于guard-rspecguard-bundlerguard的两个插件,是分别让guardrspec还有bundler结合。

分别执行下面几行指令。

bundle exec guard init
bundle exec guard init rspec
bundle exec guard init bundler

接着找到Guardfile文件,找到第一行未注释的代码,修改成类似下面这样。

guard :rspec, cmd: 'spring rspec', all_on_start: true do

现在可以运行bundle exec guard执行测试了,也能监控文件的更改,测试文件一旦有修改,也会马上运行测试。

springguard结合之后,运行测试是很快的。

3.6 capybara

capybara是一个可以编写 feature 测试的工具,它可以编写 BDD 测试、模拟浏览器点击,填充表单的测试功能。

Gemfile中添加下面一行:

group :development, :test do
  gem 'capybara'
end

执行bundle install安装。

安装完之后,找到spec/rails_helper.rb文件添加下面一行:

require 'capybara/rails'

现在我们可以编写一个 feature 测试案例。

文件名为spec/features/login_spec.rb

require 'rails_helper'

describe '登录功能', type: :feature do
  let(:user) { create(:user) }

  before { visit new_user_session_path }

  it { expect(page).to have_selector('h1', text: '登录') }

  it '没有填任何信息就点登录' do
    click_button '登录'
    expect(page).to have_content('登录账号或密码错误')
  end

  it '输入邮箱成功登录' do
    within('#new_user') do
      fill_in 'user_login', with: user.email
      fill_in 'user_password', with: user.password
    end
    click_button '登录'
    expect(page).to have_content '登录成功'
    expect(page).to have_current_path(root_path)
  end

  it '输入用户名成功登录' do
    within('#new_user') do
      fill_in 'user_login', with: user.username
      fill_in 'user_password', with: user.password
    end
    click_button '登录'
    expect(page).to have_content '登录成功'
    expect(page).to have_link('注销')
    expect(page).to have_current_path(root_path)
  end

  it '密码错误的失败登录' do
    within('#new_user') do
      fill_in 'user_login', with: user.email
      fill_in 'user_password', with: 'wrong_password'
    end
    click_button '登录'
    expect(page).to have_content '登录账号或密码错误'
    expect(page).to have_current_path(user_session_path)
  end

end

现在整个测试环境都搭建好了,接下来就是尽情地写测试就可以了。

本篇完结。

本站文章均为原创内容,如需转载请注明出处,谢谢。

0 条回复
暂无回复~~
喜欢
统计信息
    学员: 29178
    视频数量: 1985
    文章数量: 489

© 汕尾市求知科技有限公司 | Rails365 Gitlab | Qiuzhi99 Gitlab | 知乎 | b 站 | 搜索

粤公网安备 44152102000088号粤公网安备 44152102000088号 | 粤ICP备19038915号

Top