2013-10-28 62 views
5

[AfterScenario]步驟我們正在努力實現我們的specflow測試全局鉤子,並不能完全肯定[BeforeScenario][AfterScenario]歸因方法是如何工作的。全球[BeforeScenario],在SpecFlow

我見過它做的方式,這些屬性中包含了幾個方案中使用的具體步驟一類總是定義。

他們可以去某個地方,所以他們適用於所有情況?或者是否將[BeforeScenario][AfterScenario]的方法歸因於它們是針對所有場景運行的,而不管它們實際放置在哪裏?

+0

AlSki和Truan是正確的,這個答案沒有按預期工作。不接受並接受Alkski的,我會刪除我的答案。 –

回答

7

是的,您可以創建全球的BeforeScenario和AfterScenario方法,但實際上我發現這是不可取的,因爲通常在步驟之前和之後步驟不適用於所有步驟的測試項目。

相反,我創建一個基類爲我的步驟定義,這將對我想例如適用於所有的我的情景BeforeScenario和AfterScenarios方法

public class BaseStepDefinitions 
{ 
    [BeforeScenario] 
    public void BeforeScenario() 
    { 
     // BeforeScenario code 
    } 

    [AfterScenario] 
    public void AfterScenario() 
    { 
     // AfterScenario code 
    } 
} 

請注意,我沒有使用這個類的Binding屬性。如果您確實包含它,那麼BeforeScenario和AfterScenario步驟將是全球性的。

然後我得到這個基地步驟定義類我一步definion班,使他們有前和情景方法如後

[Binding] 
public class SpecFlowFeature1Steps : BaseStepDefinitions 
{ 
    [Given(@"I have entered (.*) into the calculator")] 
    public void GivenIHaveEnteredIntoTheCalculator(int inputValue) 
    { 
     ScenarioContext.Current.Pending(); 
    } 

    [When(@"I press add")] 
    public void WhenIPressAdd() 
    { 
     ScenarioContext.Current.Pending(); 
    } 

    [Then(@"the result should be (.*) on the screen")] 
    public void ThenTheResultShouldBeOnTheScreen(int expectedResult) 
    { 
     ScenarioContext.Current.Pending(); 
    } 
} 

雖然這種方法不是全局,使所有的StepDefinitions從BaseStepDefinition類派生我們實現相同的效果。

它也提供了更多的控制,即如果你不希望BeforeScenario或AfterScenario結合那麼不從基礎步驟得到根本。


對不起,這不起作用。一旦你開始使用多個綁定類,你最終會有多個調用。例如,如果我延長上面的例子綁定分成三類,

[Binding] 
public class SpecFlowFeature1Steps : BaseStepDefinitions 
{ 
    [Given(@"I have entered (.*) into the calculator")] 
    public void GivenIHaveEnteredIntoTheCalculator(int inputValue) 
    { 
     //ScenarioContext.Current.Pending(); 
    } 
} 

[Binding] 
public class SpecFlowFeature2Steps : BaseStepDefinitions 
{ 
    [When(@"I press add")] 
    public void WhenIPressAdd() 
    { 
     //ScenarioContext.Current.Pending(); 
    } 
} 

[Binding] 
public class SpecFlowFeature3Steps : BaseStepDefinitions 
{ 
    [Then(@"the result should be (.*) on the screen")] 
    public void ThenTheResultShouldBeOnTheScreen(int expectedResult) 
    { 
     //ScenarioContext.Current.Pending(); 
    } 
} 

public class BaseStepDefinitions 
{ 
    [BeforeScenario] 
    public void BeforeScenario() 
    { 
     // BeforeScenario code 
     Console.WriteLine("Before. [Called from "+ this.GetType().Name+"]"); 
    } 

    [AfterScenario] 
    public void AfterScenario() 
    { 
     // AfterScenario code 
     Console.WriteLine("After. [Called from " + this.GetType().Name + "]"); 
    } 
} 

然後當我運行它時,輸出爲

Before. [Called from SpecFlowFeature1Steps] 
Before. [Called from SpecFlowFeature2Steps] 
Before. [Called from SpecFlowFeature3Steps] 
Given I have entered 50 into the calculator 
-> done: SpecFlowFeature1Steps.GivenIHaveEnteredIntoTheCalculator(50) (0.0s) 
And I have entered 70 into the calculator 
-> done: SpecFlowFeature1Steps.GivenIHaveEnteredIntoTheCalculator(70) (0.0s) 
When I press add 
-> done: SpecFlowFeature2Steps.WhenIPressAdd() (0.0s) 
Then the result should be 120 on the screen 
-> done: SpecFlowFeature3Steps.ThenTheResultShouldBeOnTheScreen(120) (0.0s) 
After. [Called from SpecFlowFeature1Steps] 
After. [Called from SpecFlowFeature2Steps] 
After. [Called from SpecFlowFeature3Steps] 
+0

從AlSki擴展示例,您可以顯示這些方法仍然是Global。 添加 '方案:查看是否BeforeSpecification鉤被稱爲仍然 由於沒有else' 然後從'Unrelated'做出'JustTheTest'從'Unrelated'繼承步驟定義和刪除'[綁定]',並添加 ' [裝訂] 公共類AnotherTestNotUsingBase { [文(@ 「沒什麼」) 公共無效GivenNothingElse(){ // 別的什麼也不做 } }' – Truan

+0

你仍然可以得到 '我還是全球 沒有任何東西 - >完成:JustTheTest.GivenNothing()(0.0s) 我還是全球 鑑於沒有別的 - >完成:AnotherTestNotUsingBase.GivenNothingElse()(0.0s)' – Truan

+0

@BenSmith抱歉編輯您的文章,但它看起來不是這樣的作品。你還可以確認嗎 – AlSki

9

嗯......從我所瞭解的,並根據文檔這些掛鉤始終是全局的,即從http://www.specflow.org/documentation/hooks/

魚鉤

掛鉤(BI事件ndings)可以用來對特定事件執行額外的自動化邏輯,就像執行場景之前一樣。

掛鉤是全球性的,但可以僅限於對功能或場景與特定標籤(見下文)運行。相同事件的鉤子執行順序未定義。

其實用以下

[Binding] 
public class Unrelated 
{ 
    [BeforeScenario] 
    public void WillBeCalledIfGlobal() 
    { 
    Console.WriteLine("I'm global"); 
    } 
} 

[Binding] 
public class JustTheTest 
{ 
    [Given("nothing")] 
    public void GivenNothing() 
    { 
    // Don't do anything 
    } 
} 

生產小型示範項目,隨後的

As a developer 
In order to understand how BeforeSpecifcation works 
I want to know what the following does 

Scenario: See if BeforeSpecifcation hook gets called 
Given nothing 

的測試規範中得到的輸出

I'm global 
Given nothing 
-> done: JustTheTest.GivenNothing() (0.0s) 

所以它真的看起來好像文檔是正確的,喲你應該使用標記來控制在方案之前或之後是否運行BeforeScenario \ AfterScenario

還有的標註如何在這裏工作一個很好的例子 - >Feature-scoped step definitions with SpecFlow?

3

你可以做什麼,以控制「BeforeScenario」和「AfterScenario」是使用標籤。這使您可以控制哪些場景應該在塊之前和之後運行。你的情況應該是這樣的:

@GoogleChrome 
Scenario: Clicking on a button 
    Given the user is on some page 
    When the user clicks a button 
    Then something should happen 

在這裏,您可以讓「BeforeScenario」開始在谷歌瀏覽器的瀏覽器會話的你,並實施類似的標籤爲不同的瀏覽器。你「BeforeScenario」應該是這樣的:

[Binding] 
class Browser 
{   
    [BeforeScenario("GoogleChrome")] 
    public static void BeforeChromeScenario() 
    { 
     // Start Browser session and do stuff 
    } 

    [AfterScenario("GoogleChrome")] 
    public static void AfterChromeScenario() 
    { 
     // Close the scenario properly 
    } 

我認爲使用標籤是保持你的場景的清潔,給你額外的功能,讓你控制每個場景應該做的事情的一個很好的方式。