2011-10-14 55 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