40

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

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

4

6 回答 6

37

在 SpecFlow 1.3 中有三种方法:

  1. 静态成员
  2. 场景上下文
  3. 上下文注入

注释:

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

  2. 请参阅此线程中@Si Keep 的答案

  3. 如果步骤定义类的构造函数需要参数,Specflow 会尝试注入这些参数。这可用于将相同的上下文注入到多个步骤定义中。

    在此处查看示例: https ://docs.specflow.org/projects/specflow/en/latest/Bindings/Context-Injection.html

于 2010-06-03T06:12:37.497 回答
35

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

ScenarioContext.Current.Add("ActionResult", actionResult);
var actionResult = (ActionResult) ScenarioContext.Current["ActionResult"];
于 2010-05-21T11:43:36.633 回答
16

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

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 的答案,看起来您无需定义扩展即可获得相同的好处

于 2012-12-20T11:54:23.657 回答
12

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

TestPage testPageIn = new TestPage(_driver);
ScenarioContext.Current.Set<TestPage>(testPageIn);
var testPageOut = ScenarioContext.Current.Get<TestPage>();
于 2015-07-06T11:54:03.967 回答
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 

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

于 2018-01-15T05:54:43.137 回答
0

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

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

SpecFlow 3.0 及更高版本中的 ScenarioContext 和 FeatureContext

因此,在测试期间存储数据的最新方法是使用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.
  }
}
于 2020-10-14T04:41:58.527 回答