2011-10-14 56 views
3

有没有办法用rspec有条件地分组测试?我的意思是说,有没有办法说:“如果这个变量是某个值,运行这组测试。如果这个变量是其他变量,运行这个其他的测试”?Rspec中的条件测试?

基本的例子,它将需要(实际上并不工作,显然,但应该告诉你我想要什么)。假设要测试的用户在其他地方定义,并且正在测试的当前用户是@user。尽管你可能有更好的选择,但没关系。

before do 
    login_as_user(@user) #This logs them in and brings them to the homepage to be tested 
    page.visit("/homepage") 
end 
describe "Check the user homepage" 
    subject {page} 
    it {should have_content("Welcome, #{@user.name}!")} 
    if(@user.role=="admin") 
    it {should have_link("List Users"} 
    end 
end 

请记住我没有对用户没有控制被测试 - 我不能动态创建的用户,例如,没有给用户保证存在,我不知道随便什么样的组合给定用户将具有的角色。所以我确实需要一些方法来说“只有满足这些条件才运行这个测试”,而不是创建每个测试都可以运行的情况。

+0

我很好奇,实际使用情况下这是什么。 –

+0

我必须为几个用户编写一些断言测试,其权限设置相当复杂。最常见的情况是我会想检查用户属性,看看他们是否有权限查看给定的页面 - 如果他们这样做,我想运行标准测试,如果他们不是我想确保他们得到正确权限拒绝他们正在访问的页面的页面。有许多用户需要检查各种权限(和权限继承)。 – GlyphGryph

+0

是否有一个特定的原因,你不能为不同的测试环境分开'describe' /'context'块,然后在每个上下文中将用户的权限模拟/存储在'before'中? –

回答

1

好了,显然这个问题是这样简单:@user是一个实例变量,正在被执行的测试时,其只存在。出于这个原因,动态生成测试不适用于实例变量。

但是,通过在任何测试样式块(之前,之后,它或指定)之外将其声明为局部变量,您可以访问它以获取条件逻辑。

该解决方案与从用户正面取下@符号一样简单。

2

您可以使用let(或可能是let!)来定义登录的用户应该是谁。 (显然与适当的工厂/夹具更换@regular_user & @admin_user /等)

before do 
    login_as_user(user) 
    page.visit "/homepage" 
end 
let(:user) { @regular_user } 

describe "Check the user homepage" do 
    subject { page } 
    it { should have_content "Welcome, #{@user.name}!" } 

    context "when an administrator" do 
    let(:user) { @admin_user } 
    it { should have_link "List Users" } 
    end 
end 
+0

由于我无法访问我正在测试的系统,所以这类事情的工厂/设备都是正确的。不幸的是,不能保证给定的用户将存在(并且由于他们不能被创建,所以如果没有admin_user,我仍然需要一种不运行admin_user测试的方式)。这种方法实际上有一些有趣的用途,我会考虑,但我不完全确定它会解决我的问题。我会在原始问题中记下无法根据需要创建用户的情况。 – GlyphGryph

0

在同一种想法,你可以使用静态变量

为了轻松环境之间切换,我甚至使用该系统的全局变量

我spec_helper.rb

,我已经设置默认设置

default_env = { 
    'SITE_ROOT' => "http://localhost:3000", 
    'ACCOUNT_ID' => 'user', 
    'ACCOUNT_PASSWORD' => 'password', 
    'SUBMIT_REAL_MONEY' => 'false' 
} 

# setting default env variables if no ENV ones exists 
default_env.each do |const_name, value| 
    val = ENV[const_name].nil? ? value : ENV[const_name] 
    eval_str = "#{const_name}='#{val}'" 
    puts eval_str 
    eval eval_str 
end 

然后,我可以在命令行中指定我的设置叫我的规格:

SITE_ROOT='https://my.production.site/' SUBMIT_REAL_MONEY=true rspec 

这里是背后一个简单的条件的规范:

if SUBMIT_REAL_MONEY == 'true' 
    it { should respond_with 200 } 
end