【问题标题】:Play Famework 2 - Scala - Start one application for test-suitePlay Framework 2 - Scala - 为测试套件启动一个应用程序
【发布时间】:2015-07-08 19:24:16
【问题描述】:

我一直在使用 Play 官方文档中的 Specs2 跟踪 Scala 测试示例。我注意到他们使用WithApplication 来启动一个伪造的应用程序来进行测试,代码如下:

"something" should {
    "do X" in new WithApplication { /* ... */ }
    "do Y" in new WithApplication { /* ... */ }
    "do Z" in new WithApplication { /* ... */ }
}

这很好,但我遇到的问题是每次发生这种情况时我都会承担启动应用程序的成本。一旦您的测试套件增长到合理的大小,这不一定是“快”或至少不够快。我试过做这样的事情:

val app = FakeApplication()
"something" should {
    "do X" in new WithApplication(app) { /* ... */ }
    "do Y" in new WithApplication(app) { /* ... */ }
    "do Z" in new WithApplication(app) { /* ... */ }
}

"something" should {
    val app = FakeApplication()
    Helpers.running(app) {
        "do X" in { /* ... */ }
        "do Y" in { /* ... */ }
        "do Z" in { /* ... */ }
    }
}

第一个似乎适用于第一个测试,然后在以后的测试中抱怨数据库连接问题。我猜这里有什么东西正在关闭或什么东西(不确定是什么)。

第二个根本不起作用,因为它抱怨没有正在运行的应用程序,我也不确定。

非常感谢任何帮助。谢谢!

【问题讨论】:

    标签: scala playframework specs2


    【解决方案1】:

    嗯,这取决于你想测试什么。如果您只是对没有外部依赖项或可以模拟或存根的依赖项的单元测试代码(并且以允许这样做的方式构造代码是一个好主意),那么您不需要使用WithApplication。这可能是最好的方法。

    您提供的第一个解决方案不起作用,因为应用程序只能使用一次。是 WithApplication 启动和停止您的应用程序,因此即使这样做有效,您也不会获得任何性能优势。

    您提供的第二个解决方案不起作用,因为当Helpers.running(app) { } 代码块运行时,这只是声明规范。 Specs 将所有这些都放在一个列表中,然后您退出运行块并关闭应用程序。然后在某个时间点,specs 运行测试,然后当然没有应用程序。

    因此,如果您无法独立于应用程序的其余部分来测试您的代码,那么您需要有一个正在运行的应用程序,对此您无能为力,这就是集成测试的现实。而且您可能希望它在每次测试之间启动和关闭,否则您的测试不会彼此隔离运行。

    【讨论】:

      【解决方案2】:

      它已经过时了,但我会给出我的答案。因为我面临同样的问题,并且有类似的想法。 spec2中有AfterAll&BeforeAll特性,可能发帖的时候还没有,所以我的解决方案基本上是:

      package com.equipx.spec.util
      
      import org.specs2.specification.{AfterAll, BeforeAll}
      import play.Application
      import play.api.Play
      import play.test.{Helpers, FakeApplication}
      
      /**
       * @author Anton Oparin (antono@clemble.com)
       */
      trait WithGlobalApplication extends BeforeAll with AfterAll {
      
        protected var app: Application = null
      
        /**
         * Override this method to setup the application to use.
         *
         * By default this will call the old {@link #provideFakeApplication() provideFakeApplication} method.
         *
         * @return The application to use
         */
        protected def provideApplication: Application = {
          return provideFakeApplication
        }
      
        /**
         * Old method - use the new {@link #provideApplication() provideApplication} method instead.
         *
         * Override this method to setup the fake application to use.
         *
         * @return The fake application to use
         */
        protected def provideFakeApplication: FakeApplication = {
          return Helpers.fakeApplication
        }
      
        override def beforeAll {
          app = provideApplication
          Helpers.start(app)
          Play.current
        }
      
        override def afterAll {
          if (app != null) {
            Helpers.stop(app)
            app = null
          }
        }
      
      }
      

      基本上,我采用了 WithApplication 实现,并使其成为全球性的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-14
        • 2017-08-25
        • 2017-05-06
        • 2018-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多