I have a scenario that looks as the following:
scenario("Websocket client sends data to websocket server on SAP when is UP") {
Given("Websocket server on SAP is ACTIVE")
And("it supports websocket channel")
When("Websocket client get started")
Then("print message `Connection has been successfully established`")
Given("Websocket server on SAP is ACTIVE")
And("it does not support websocket channel")
When("Websocket client get started")
Then("throws RunException")
succeed
}
As you can see, the Given
is repeating twice. The question is, would it be also correct, if I would just leave the second Given
as the following
scenario("Websocket client sends data to websocket server on SAP when is UP") {
Given("Websocket server on SAP is ACTIVE")
And("it supports websocket channel")
When("Websocket client get started")
Then("print message `Connection has been successfully established`")
And("it does not support websocket channel")
When("Websocket client get started")
Then("throws RunException")
succeed
}
In general it's usually a bad idea to have scenarios relying on other scenarios to set up their context. That's a pattern we call a "GivenScenario". It makes it harder to see the behaviour (you now have to read the whole of the first scenario to understand the context of the second) and if the first scenario fails, the second won't even be run.
It's also possible that someone who doesn't know that the second scenario is relying on the first might change the first or add one between them.
If you have some kind of behaviour that's "always on", most BDD tools put this in something they call the "Background". The equivalent of this in ScalaTest looks like the "BeforeAndAfter" trait (I'm not as familiar with ScalaTest so someone correct me if I'm wrong!).
So instead of having that "always on" active websocket in the scenario, you could move the behaviour to "Before".
Of course, the "background" in ScalaTest doesn't print when you run it; it's silent. But you could get around this by calling it anyway, and moving the English to either the title (note the addition of "active"):
class ExampleSpec extends FeatureSpect with BeforeAndAfter {
before {
server = startServer()
}
scenario("Websocket client sends data to active websocket server on SAP when is UP") {
Given("it supports websocket channel")
// etc...
}
}
or the first given:
class ExampleSpec extends FeatureSpect with BeforeAndAfter {
before {
server = startServer()
}
scenario("Websocket client sends data to websocket server on SAP when is UP") {
Given("an active server with a client that supports websocket channel")
// etc...
}
}
(Again, not familiar with ScalaTest and it's been forever since I programmed Scala, so please correct any syntax errors; this answer is more focused on the principle. The documentation I found on this shows all steps as lower-case.)
The only time I tend to use GivenScenarios is when I'm being lazy (or pragmatic) and there's a (usually human) interaction which will result in one or more tries of something before getting a success:
Given Florence Forgetful is at the login page
When she puts in the wrong username
Then she should be told there was an error
When she puts in the wrong password
Then she should be told there was still an error
When she puts in the right username and right password
Then she should be taken to her home page.
However, if it isn't readable like this, or the very first time the interaction in those first steps becomes anything other than trivial (e.g. you also have to fill in a captcha box), or the very first time I get an error in one of those steps, I'll refactor them out into separate scenarios.
If turning the support on and off in the client is an action that a human being could perform, then you could follow the same pattern, but the need for two "whens" in a row is a good sign that now there's more than one capability being illustrated here:
scenario("Websocket client sends data to websocket server on SAP when is UP") {
Given("Websocket server on SAP is ACTIVE")
And("websocket support is turned off")
When("Websocket client get started")
Then("throws RunException")
When("websocket support is turned on")
And("Websocket client get started") // <-- This is a second "When" here
Then("print message `Connection has been successfully established`")
succeed
}
So probably not the right way to go for this one. If in doubt, avoid the GivenScenario pattern completely.