在SpecFlow中,如何在步骤/功能之间共享数据?

时间:2010-05-21 11:42:45

标签: c# specflow

我有2个功能使用常见的“何时”步骤,但在不同的类中有不同的“然后”步骤。

如何在我的两个步骤中的When步骤中从我的MVC控制器调用中访问ActionResult?

6 个答案:

答案 0 :(得分:34)

在SpecFlow 1.3中有三种方法:

  1. 静态成员
  2. ScenarioContext
  3. ContextInjection
  4. 评论:

    1. 静态成员非常务实,在这种情况下并不像开发人员首先想到的那样邪恶(在步骤定义中没有线程化或需要模拟/替换)

    2. 请参阅@Si Keep的回答

    3. 如果步骤定义类的构造函数需要参数,则Specflow会尝试注入这些参数。这可用于将相同的上下文注入到多个步骤定义中。
      在这里看一个例子: https://github.com/techtalk/SpecFlow/wiki/Context-Injection

答案 1 :(得分:33)

使用ScenarioContext类,它是所有步骤共有的字典。

ScenarioContext.Current.Add("ActionResult", actionResult);
var actionResult = (ActionResult) ScenarioContext.Current["ActionResult"];

答案 2 :(得分:15)

我有一个帮助类,可以让我写

Current<Page>.Value = pageObject;

是ScenarioContext的包装器。它取决于类型名称,因此如果您需要访问两个相同类型的变量,则需要进行一些扩展

 public static class Current<T> where T : class
 {
     internal static T Value 
     {
         get { 
               return ScenarioContext.Current.ContainsKey(typeof(T).FullName)
               ? ScenarioContext.Current[typeof(T).FullName] as T : null;
             }
         set { ScenarioContext.Current[typeof(T).FullName] = value; }
     }
 }

2019编辑:我现在会使用@ JoeT的答案,看起来你无需定义扩展即可获得相同的好处

答案 3 :(得分:8)

我不喜欢使用Scenario.Context,因为需要输出每个字典条目。我找到了另一种存储和检索项目的方法,无需投射它。但是,这里有一个权衡,因为您实际上是使用类型作为键从ScenarioContext字典访问对象。这意味着只能存储该类型的一个项目。

TestPage testPageIn = new TestPage(_driver);
ScenarioContext.Current.Set<TestPage>(testPageIn);
var testPageOut = ScenarioContext.Current.Get<TestPage>();

答案 4 :(得分:0)

您可以在步骤中定义一个参数,该参数是您存储的值的关键。这样,您可以使用密钥在后续步骤中引用它。

...
Then I remember the ticket number '<MyKey>'
....
When I type my ticket number '<MyKey>' into the search box
Then I should see my ticket number '<MyKey>' in the results 

您可以将实际值存储在字典或属性包或类似内容中。

答案 5 :(得分:0)

由于这是我在Google上获得的第一个结果,所以我只是想提到@jbandi的答案是最完整的。但是,从3.0版或更高版本开始:

在SpecFlow 3.0中,我们将ScenarioContext.Current和FeatureContext.Current标记为已过时,以明确表示您以后应该避免使用这些属性。离开这些属性的原因是,在并行运行方案时它们不起作用。

ScenarioContext and FeatureContext in SpecFlow 3.0 and Later

因此,在测试期间存储数据的最新方法是使用Context Injection。我会添加示例代码,但实际上链接中的示例代码非常出色,因此请查看。

您可以通过将实例注入绑定类来模仿现在已经过时的ScenarioContext.Current。

[Binding]
public class MyStepDefs
{
 private readonly ScenarioContext _scenarioContext;

  public MyStepDefs(ScenarioContext scenarioContext) 
  { 
    _scenarioContext= scenarioContext ;
  }

  public SomeMethod()
  {
    _scenarioContext.Add("key", "value");

    var someObjectInstance = new SomeObject();
    _scenarioContext.Set<SomeObject>(someObjectInstance);
  
    _scenarioContext.Get<SomeObject>();
            
    // etc.
  }
}
相关问题