我有一个如下所示的场景:
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
}
如您所见,Given
重复了两次。问题是,如果我仅将第二个Given
保留为以下
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
}
答案 0 :(得分:4)
通常,使场景依赖其他场景来设置其上下文通常是一个坏主意。这就是我们称为“ GivenScenario”的模式。这样一来,很难观察到该行为(现在您必须阅读第一种情况的全部内容才能理解第二种情况的上下文),并且如果第一种情况失败,则第二种情况甚至无法运行。
不知道第二种情况是否依赖第一种情况的人也可能会更改第一种情况或在它们之间添加一个。
如果您有某种“始终存在”的行为,则大多数BDD工具会将其放在他们称为“背景”的东西中。与此类似,在ScalaTest中看起来像是“ BeforeAndAfter”特征(我对ScalaTest并不熟悉,所以如果我错了,有人可以纠正我!)。
因此,您可以将行为移至“之前”,而不是在方案中始终保持活动的Websocket。
当然,ScalaTest中的“背景”在您运行时不会打印;没声音但是您仍然可以通过调用它来解决此问题,并将英语移动到任一标题(请注意添加“ 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...
}
}
或第一个给定的
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...
}
}
(再次,对ScalaTest并不熟悉,自从我编写Scala以来就一直存在,因此请更正所有语法错误;此答案更着重于原理。The documentation I found on this将所有步骤都显示为小写。)< / p>
我唯一倾向于使用GivenScenarios的情况是当我懒惰(或务实)并且存在(通常是人为的)交互作用时,将导致对成功进行一次或多次尝试:
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.
但是,如果这样的可读性很差,或者非常第一次,那么第一步中的交互就变得不那么琐碎了(例如,您还必须填写验证码),或第一次,在其中一个步骤中出现错误,我会将其重构为单独的场景。
如果打开和关闭客户端支持是人类可以执行的操作,那么您可以遵循相同的模式,但是连续两次“何时”的需要是一个好兆头,表明现在还有更多此处没有说明一种功能:
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
}
所以这可能不是正确的方法。如有疑问,请完全避免使用GivenScenario模式。
答案 1 :(得分:3)
第二个@Lunivore答案,分别为受支持和不受支持的频道分别指定方案:
scenario("Websocket client sends data to server over supported channel")
scenario("Websocket client sends data to server over unsupported channel")
可以像这样通过fixtures来实现Given
子句中的重复代码
class HelloSpec extends fixture.AsyncFeatureSpec with Matchers with GivenWhenThen {
type FixtureParam = String // FIXME: Provide real SapWebSocket type
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
Given("Websocket server on SAP is ACTIVE")
val activeSapWebsocketFixtureParam = "activateSapWebSocket()" // FIXME: implement activateSapWebSocket()
withFixture(test.toNoArgAsyncTest(activeSapWebsocketFixtureParam))
}
feature("Kafka distribution to a server via websocket") {
scenario("Websocket client sends data to server over supported channel") {
givenActiveSapWebsocket =>
And("given websocket channel is SUPPORTED")
When("Websocket client get started")
Then("print message `Connection has been successfully established`")
succeed
}
scenario("Websocket client sends data to server over unsupported channel") {
givenActiveSapWebsocket =>
And("given websocket channel is UNSUPPORTED")
When("Websocket client get started")
Then("throws RunException")
succeed
}
}
}
请注意如何将Given("Websocket server on SAP is ACTIVE")
移至withFixture
。另请注意,使用fixture.AsyncFeatureSpec
而非AsyncFeatureSpec
来提供灯具支持。这应该输出
[info] Feature: Kafka distribution to a server via websocket
[info] - Scenario: Websocket client sends data to server over supported channel
[info] + Given Websocket server on SAP is ACTIVE
[info] + And given websocket channel is SUPPORTED
[info] + When Websocket client get started
[info] + Then print message `Connection has been successfully established`
[info] - Scenario: Websocket client sends data to server over unsupported channel
[info] + Given Websocket server on SAP is ACTIVE
[info] + And given websocket channel is UNSUPPORTED
[info] + When Websocket client get started
[info] + Then throws RunException
就个人而言,我不会为测试源代码的可读性而烦恼固定装置并保持重复,但是我绝对会将场景分开。