2016-06-17 3 views
2

Я пишу блок-тесты с использованием specs2, и мое приложение запускается и останавливается для каждого экземпляра теста.Альтернатива OneAppPerSuite в тестах scas specs2

import org.specs2.mutable._ 

class HelloWorldSpec extends Specification { 

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

Как указано в документации для каждого тестового примера, приложение запускается и останавливается.

Я нашел обходное решение от link. Приложение инициализируется только один раз (я еще не тестировал его) для каждого тестового класса.

import org.specs2.mutable._ 

class HelloWorldSpec extends Specification {sequential 

    step(Play.start(App)) //supposedly App is iniatilized 

    "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") 
    } 
    } 
    step(Play.stop()) 
} 

Но что делать, если у нас есть несколько классов, и мы хотим, чтобы один запуск и остановка приложения.

import org.specs2.mutable._ 

class HelloWorldSpec extends Specification {sequential 

    step(Play.start(App)) //supposedly App is iniatilized 

    "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") 
    } 
    } 
    step(Play.stop()) 
} 

import org.specs2.mutable._ 

class HitchHikerSpec extends Specification {sequential 

    step(Play.start(App)) //supposedly App is iniatilized 

    "The 'Hitch Hiker' string" should { 
    "contain 11 characters" in { 
     "Hitch Hiker" must have size(11) 
    } 
    "start with 'Hitch'" in { 
     "Hitch Hiker" must startWith("Hitch") 
    } 
    "end with 'Hiker'" in { 
     "Hitch Hiker" must endWith("Hiker") 
    } 
    } 
    step(Play.stop()) 
} 

Как я могу начать и остановить приложение за один раз?

Существует аналогичное решение, реализованное в scalatest с использованием OneAppPerSuite. Вот link и пример.

import play.api.test._ 
import org.scalatest._ 
import org.scalatestplus.play._ 
import play.api.{Play, Application} 
import play.api.inject.guice._ 

// This is the "master" suite 
class NestedExampleSpec extends Suites(
    new OneSpec, 
    new TwoSpec, 
    new RedSpec, 
    new BlueSpec 
) with OneAppPerSuite { 
    // Override app if you need an Application with other than non-default parameters. 
    implicit override lazy val app: Application = 
    new GuiceApplicationBuilder().configure(Map("ehcacheplugin" -> "disabled")).build() 
} 

// These are the nested suites 
@DoNotDiscover class OneSpec extends PlaySpec with ConfiguredApp 
@DoNotDiscover class TwoSpec extends PlaySpec with ConfiguredApp 
@DoNotDiscover class RedSpec extends PlaySpec with ConfiguredApp 

@DoNotDiscover 
class BlueSpec extends PlaySpec with ConfiguredApp { 

    "The OneAppPerSuite trait" must { 
    "provide an Application" in { 
     app.configuration.getString("ehcacheplugin") mustBe Some("disabled") 
    } 
    "make the Application available implicitly" in { 
     def getConfig(key: String)(implicit app: Application) = app.configuration.getString(key) 
     getConfig("ehcacheplugin") mustBe Some("disabled") 
    } 
    "start the Application" in { 
     Play.maybeApplication mustBe Some(app) 
    } 
    } 
} 

Может что-то подобное будет реализовано в specs2?

ответ

1

С specs2 вы можете сделать что-то подобное с specification references:

class SuiteSpec extends Specification { def is = s2""" 
    ${link(StartSpec).hide} 
    ${ "first spec" ~ new Spec1Spec } 
    ${ "second spec" ~ new Spec2Spec } 
    ${link(StopSpec).hide} 
    """ 
} 

object StartSpec extends Specification { def is = s2""" 
    ${step(println("start"))} 
    """ 
} 

class Spec1Spec extends Specification { def is = s2""" 
    example1 $e1 
    """ 

    def e1 = { println("example1"); ok } 
} 

class Spec2Spec extends Specification { def is = s2""" 
    example2 $e2 
    """ 

    def e2 = { println("example2"); ok } 
} 

object StopSpec extends Specification { def is = s2""" 
    ${step(println("stop"))} 
    """ 
} 

Тогда при запуске:

testOnly *Suite* -- all 

Вы должны увидеть следующие строки распечатываются:

start 
example1 
example2 
stop 
+0

Спасибо для ответа я пытался реализовать аналогичное решение, но используя BeforeAfterA ll для запуска и остановки приложения. Но возникла проблема, связанная с тем, что связанные классы выполняются сначала до того, как приложение может начать – perfectus