How to increase reusability between SpecFlow/Gherkin steps?

爱⌒轻易说出口 提交于 2019-12-03 00:25:59

This is not an answer, but some hints:

  • you can put multiple Given/When/Then attributes on the same method. If the parameters are the same and the difference is only in phrasing, this can be useful
  • in many project we use driver/page object pattern, so the step definitions are usually quite short (2-3 lines), so we bother less about the number of them
  • I like your scenarios, I would not change them. On the other hand try to focus on the readability and not the reusability. If your language is consistent, the reusability will come.
  • For increasing the reusability especially when there are a lot of "variations" of the entity you are talking about, you can consider using the step argument transformations. Here is an example:

you need a class to represent a permit in the tests with decorations:

class PermitDescription{
  bool suspended;
  bool draft;
}

create converter methods:

[StepArgumentTransformation("permit")]
public PermitDescription CreateSimple(){
  return new PermitDescription();
}
[StepArgumentTransformation("draft permit")]
public PermitDescription CreateDraft(){
  return new PermitDescription() { draft = true; }
}
[StepArgumentTransformation("suspended permit")]
public PermitDescription CreateSuspended(){
  return new PermitDescription() { suspended = true; }
}

you can have now more flexible step definitions that require permits:

[Given(@"I have a (.*) for the day shift")]
public void Something(PermitDescription p)
{ ... }

that matches to:

Given I have a permit for the day shift
Given I have a draft permit for the day shift
Given I have a suspended permit for the day shift

of course this is tool that can be also abused, but in some cases it can help.

Adding onto the answer from @gaspar-nagy It follows the pattern of class design in C programming. Anywhere a common group of classes share common properties/methods, those properties/methods can be refactored into a base class.

What it looks like in our SpecFlow tests is that common browser operations are in the base classes:

Login()
Logout()
NavigateToUrl(string url)
UserHasPermission(string permission)
WaitForElementToAppearById(string id)
WaitForElementToAppearByClass(string class)

And each of those methods could have 1 or more Given/When/Then attributes like @gasper-nagy stated.

Another technique which proves invaluable is to share variables between .features and their respective C# step files is to use the ScenarioContext.

For example, whenever Login() is called to initiate our browser based tests, we do this:
ScenarioContext.Current.Set<IWebDriver>(driver, "driver")

Then anywhere else that needs the driver, can get it by:
var driver = ScenarioContext.Current.Get<IWebDriver>("driver")

This makes steps re-usable, such as user input tests for validation you may decide to pass the element being validated around like this: ScenarioContext.Current.Set<IWebElement>(element, "validation-element")

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!