TL; DR:如何在遇到错误时停止rspec中止所有规范?
运行rails'内置测试套件,我得到类似于以下内容的输出:
...F..F.EE...E
Finished in 0.64396 seconds
14 examples, 2 failures, 3 errors
.
表示通过测试,F
表示失败测试,E
表示错误测试。测试失败意味着rails应用程序的代码失败,错误的测试意味着您的实际测试代码失败。错误的测试永远不会好。
我对此感兴趣的是,当程序遇到E
时,它会继续进行所有其他测试。
我正在使用rpsec,虽然我喜欢它,但我有点讨厌当它遇到错误的规格时,它完全放弃了幽灵,并退出所有规格,如下:
12:39:37 - INFO - Running: spec
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/validations.rb:57:in `save!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
from /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/attribute_methods/dirty.rb:41:in `save!'
from /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/transactions.rb:275:in `block in save!'
from /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/gems/1.9.1/gems/activerecord-4.0.1/lib/active_record/transactions.rb:326:in `block in with_transaction_returning_status'
虽然我确实喜欢错误报告,但我真的希望它在遇到错误的规范时继续运行所有规范。而不是上面的输出,我真的想要以下几点:
12:40:01 - INFO - Running: spec
...F..F..E
Failures:
1) User A new user can be created email should == "awesomedog@hotmail.co.uk"
Failure/Error: its(:email) { should == "awesomedog@hotmail.co.uk" }
expected: "awesomedog@hotmail.co.uk"
got: "awesomedozg@hotmail.co.uk" (using ==)
# ./spec/model/user_spec.rb:11:in `block (3 levels) in <top (required)>'
2) User A new user can be created should not be valid
Failure/Error: it { should_not be_valid }
expected valid? to return false, got true
# ./spec/model/user_spec.rb:20:in `block (3 levels) in <top (required)>'
Errors:
1) `save!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
Finished in 0.64396 seconds
10 examples, 2 failures, 1 error
Failed examples:
rspec ./spec/model/user_spec.rb:11 # User A new user can be created email should == "awesomedog@hotmail.co.uk"
rspec ./spec/model/user_spec.rb:20 # User A new user can be created should not be valid
我在我的规范中使用工厂女孩和工厂,以及数据库清理器在每个规范之间清理我的数据库。我使用rspec-guard来运行所有项目文件(除tmp
,log
或db
中的项目文件)之外的所有规范。因为如果遇到错误,rpsec会一直保持缄默,我收到了这个错误:
How can I clean my database between erroneous rspec specs?
基本上,数据库清理程序配置为在规范开始时和规范完成时清理我的数据库。由于rspec在遇到错误时退出规范中间,因此数据库清理程序无法检测到规范已完成,因此永远不会清除我的数据库。这意味着我必须使用我的数据库shell手动清空它。
我也更愿意看到我所有其他规格的状态,即使一个是错误的!在这方面,Rspec真的很愚蠢!
这是我的工厂和我的规范:
规格/型号/ user_spec.rb:
require 'spec_helper'
describe User do
context "Valid user" do
user = FactoryGirl.create(:user_with_all_valid)
subject { user }
its(:first_name) { should == "Jimmy" }
its(:last_name) { should == "Thehat" }
its(:profile_name) { should == "Jimbohatboy893" }
its(:email) { should == "awesomedog@hotmail.co.uk" }
its(:password) { should == "thisisasupersecretpassword12234234" }
its(:password_confirmation) { should == "thisisasupersecretpassword12234234" }
end
end
规格/ factories.rb:
FactoryGirl.define do
factory :user_with_all_valid, class: User do
first_name "Jimmy"
last_name "Thehat"
profile_name "Jimbohatboy893"
email "awesomedog@hotmail.co.uk"
password "thisisasupersecretpassword12234234"
password_confirmation "thisisasupersecretpassword12234234"
end
end
答案 0 :(得分:1)
由于模型验证,您每次都需要发送一封唯一的电子邮件 顺便说一下,其他7或8个正在通过(点)。
尝试添加:
new_user_time = Time.new
保存当前时间。 然后将其传递给create user工厂。 然后用它来检查用户的电子邮件是否正确。
答案 1 :(得分:1)
使用序列详见:https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#sequences
可以使用序列生成特定格式的唯一值(例如,电子邮件地址)。序列是通过调用定义块中的序列来定义的,序列中的值是通过调用FactoryGirl.generate生成的:
# Defines a new sequence
FactoryGirl.define do
sequence :email do |n|
"person#{n}@example.com"
end
end
FactoryGirl.generate :email
# => "person1@example.com"
FactoryGirl.generate :email
# => "person2@example.com"
...
只是让您的规范检查电子邮件地址的一部分是否正确,例如@something.com
或使用正则表达式进行比较,例如match(/person.*@something\.com/)
答案 2 :(得分:1)
您的问题是这一行:
context "Valid user" do
user = FactoryGirl.create(:user_with_all_valid) # Right here!
...
测试设置应始终在before
块中完成;变量定义在let
块中完成。在测试定义中执行此操作将导致rspec失败,如上所述。通常,您应该只在context
块中拥有rspec指令(before,after,let,subject,it,it等)。如果你正在运行测试设置,应用程序代码,无论如何,你将打开这个问题。你想要的是:
context "Valid user" do
let(:user) { FactoryGirl.create(:user_with_all_valid) }
或:
context "Valid user" do
before { @user = FactoryGirl.create(:user_with_all_valid) }
套件将按预期运行整个事件,并报告未能正确执行其定义设置(用户定义)的测试失败,而不是从整个套件中轰炸。