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

Sim*_*eep 35 c# specflow

我有2个功能使用常见的'When'步骤,但在不同的类中有不同的'Then'步骤.

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

jba*_*ndi 35

在SpecFlow 1.3中有三种方法:

  1. 静态成员
  2. ScenarioContext
  3. ContextInjection

评论:

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

  2. 请参阅此主题中@Si Keep的回答

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

  • 我认为也可以使用实例变量,例如:http://github.com/techtalk/SpecFlow-Examples/blob/master/BowlingKata/BowlingKata-Nunit/Bowling.Specflow/BowlingSteps.cs (2认同)

Sim*_*eep 33

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

ScenarioContext.Current.Add("ActionResult", actionResult);
var actionResult = (ActionResult) ScenarioContext.Current["ActionResult"];
Run Code Online (Sandbox Code Playgroud)

  • 西蒙已经为这个问题做了正确的实施.op现在可以根据需要进行重构,而不是Simon尝试猜测他是怎么想的.mcintyre321在下面做了一个很好的帮助方法. (6认同)
  • 这太可怕了:( (2认同)
  • 为什么说这是可怕的上校呢? (2认同)

mci*_*321 15

我有一个帮助类让我写

Current<Page>.Value = pageObject;
Run Code Online (Sandbox Code Playgroud)

这是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; }
     }
 }
Run Code Online (Sandbox Code Playgroud)

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


Joe*_*oeT 9

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

TestPage testPageIn = new TestPage(_driver);
ScenarioContext.Current.Set<TestPage>(testPageIn);
var testPageOut = ScenarioContext.Current.Get<TestPage>();
Run Code Online (Sandbox Code Playgroud)