验收风格测试有利于使用Specs2进行单元样式测试?

时间:2012-11-19 02:28:58

标签: scala specs2

在Specs2的上下文中,纯粹主义者可能会争辩说应该使用单元测试样式进行单元测试。并且Specs2 验收测试样式用于进行验收测试。这听起来有点明显; - )

但是,我赞成接受测试的写作风格甚至我的单元测试(主要是为了保持一致)。是否有任何技术原因我不应该这样做?

我只是喜欢以相同的方式编写所有测试的一致性,而单元测试样式对我的项目所有者(不是技术人员)来说有点难以导航。虽然验收测试样式允许他们在偶然发现缺失特征时添加新测试,例如:

"Cool new feature" ! todo ^

正如您从以下示例中所看到的(改编自Specs2 site),验证测试风格对于非怪异的人来说更具可读性,并且可以更好地分离关注点,尤其是随着规格变大。此外,它可能会导致更多的构图风格或写作测试。

单元测试风格:

  import org.specs2.mutable._

  class HelloWorldSpec extends Specification {

    "The 'Hello world' string" should {
      "contain 11 characters" in {
        "Hello world" must have size(11)
      }
      "start with 'Hello'" in {
        "Hello world" must startWith("Hello")
      }
      "end with 'world'" in {
        "Hello world" must endWith("world")
      }
    }
  }

验收测试方式:

 import org.specs2._

  class HelloWorldSpec extends Specification { def is =

    "This is a specification to check the 'Hello world' string"       ^
                                                                      p^
    "The 'Hello world' string should"                                 ^
      "contain 11 characters"                                         ! e1^
      "start with 'Hello'"                                            ! e2^
      "end with 'world'"                                              ! e3^
      "do something cool"                                             ! todo^
      "do something cooler"                                           ! todo^
                                                                      end

    def e1 = "Hello world" must have size(11)
    def e2 = "Hello world" must startWith("Hello")
    def e3 = "Hello world" must endWith("world")
  }

谁知道,有一天,人们甚至可能会使用字符串插值(或其他东西)以及额外的解析例程来结束使用更具可读性的DSL的多个文件:

HelloTest.specs2

  s"
  This is a specification to check the 'Hello world' string
  =========================================================

  The 'Hello world' string should
  -------------------------------
  - $e1 contain 11 characters
  - $e2 && $e3 start with 'Hello' and end with 'world'
  - $todo do something cool
  - $todo do something cooler
  "

MyAppSpec2.scala

 import org.specs2._

  class HelloWorldSpec extends Specification { def is = HelloTest.specs2

    def e1 = "Hello world" must have size(11)
    def e2 = "Hello world" must startWith("Hello")
    def e3 = "Hello world" must endWith("world")
  }

1 个答案:

答案 0 :(得分:3)

没有技术上的理由说明为什么你不能使用“Acceptance”样式来编写单元测试,反过来使用“Unit”样式来编写验收测试(因为你可以使用带代码折叠的编辑器来显示文本,或者您可以使用plan参数执行规范并获取规范的全文而不执行示例。)

您需要注意两件“技术”事项:

  • “unit”规范使用变量来注册示例,因此如果您尝试使用不同的线程构建此类规范,则会遇到并发问题

  • “接受”规范使用示例的最后一个值作为结果。因此,默认情况下,如果要在示例中为每行写一个期望值,则不太方便。要解决此问题,您需要混合使用ThrownExpectation特征或在期望之间使用and运算符

最后,我一定会研究在Scala 2.10出来时使用字符串插值来接受规范的可能性。