web-dev-qa-db-fra.com

Faire quelque chose avant ou après tous les tests Scalatest

J'ai une suite de tests scalatest qui testent différents points de terminaison d'une API RESTful. Je veux vraiment qu'ils soient séparés en différents fichiers pour une meilleure organisation.

Mon problème est de savoir comment démarrer quelque chose (un serveur HTTP dans mon cas, mais peu importe ce qu'il est) avant tous les tests et l'arrêter une fois tous les tests terminés.

Je connais BeforeAndAfterAll, mais cela ne fait qu'avant/après dans un fichier de test. J'ai besoin de quelque chose comme ça, mais pour tous les tests, par exemple:

- démarrer le serveur http avant les tests
- exécutez toutes les suites de tests
- arrêter le serveur http

68
Greg

Pour ce faire, vous devez utiliser des suites imbriquées. Suite a une méthode nestedSuites qui retourne une IndexedSeq [Suite] (en 2.0, en 1.9.1 c'était une List [Suite]). Suite possède également une méthode runNestedSuites qui est responsable de l'exécution des suites imbriquées. Par défaut, runNestedSuites appelle nestedSuites et, sur chaque suite retournée, invoque run directement ou, si un distributeur est transmis, place les suites imbriquées dans le distributeur afin qu'elles puissent être exécutées en parallèle.

Donc, ce que vous voulez vraiment faire, c'est transformer Foo et Bar en classes, et renvoyer leurs instances à partir de la méthode nestedSuites d'EndpointTests. Il y a une classe qui rend cela facile appelé Suites. Voici un exemple de son utilisation:

import org.scalatest._
import matchers.MustMatchers

class Foo extends FunSpec with MustMatchers {
  describe("Message here...") {
    it("Must do something") {  }
    it("Must be ok") {  }
  }
}

class Bar extends FunSpec with MustMatchers {
  describe("Hello you...") {
    it("One more!") {  }
  }
}

class EndpointTests extends Suites(new Foo, new Bar) with BeforeAndAfterAll {

  override def beforeAll(configMap: Map[String, Any]) {
    println("Before!")  // start up your web server or whatever
  }     

  override def afterAll(configMap: Map[String, Any]) {
    println("After!")  // shut down the web server
  }         
}

Un problème potentiel, cependant, est que si vous utilisez la découverte pour trouver des suites à exécuter, les trois EndpointTests, Foo et Bar seront découverts. Dans ScalaTest 2.0, vous pouvez annoter Foo et Bar avec @DoNotDiscover, et Runner de ScalaTest ne les découvrira pas. Mais sbt le fera toujours. Nous améliorons actuellement sbt afin qu'il passe sur les suites autrement découvrables qui sont annotées avec DoNotDiscover, mais ce sera dans sbt 0.13, qui n'est pas encore sorti. En attendant, vous pouvez demander à sbt de les ignorer en ajoutant un paramètre constructeur inutilisé à Foo et Bar.

51
Bill Venners

Alternativement, vous pouvez simplement utiliser un objet.

object TestServer {
  startServer()
}

Lorsque vous accédez à l'objet, il sera initialisé, démarrant le serveur. Créez simplement un trait commun dans le corps duquel vous accédez à l'objet. Mélangez ensuite ce trait dans tous vos tests. Terminé.

Si votre serveur s'exécute en mode démon (par exemple, une application Play! En mode test), il sera automatiquement arrêté une fois tous les tests exécutés.

11
Machisuji

Ok, j'ai trouvé un moyen. Il semble (sauf si quelqu'un ici peut me corriger) que Scalatest n'a pas la possibilité d'une suite "master". Mais ... vous pouvez en construire un peu.

Vous pouvez composer une suite de traits. Donc, en utilisant mon exemple de point de terminaison:

class EndpointTests extends FunSpec with MustMatchers with BeforeAndAfterAll 
      with Foo with Bar {
        override def beforeAll(configMap: Map[String, Any]) {
            println("Before!")  // start up your web server or whatever
        }

        override def afterAll(configMap: Map[String, Any]) {
            println("After!")  // shut down the web server
        }   
}

D'accord, mais qu'en est-il des tests? Notez le avec Foo avec Bar. J'apporte les tests dépendants en tant que traits. Vois ici:

trait Foo extends FunSpec with MustMatchers {
    describe("Message here...") {
        it("Must do something") {  }
        it("Must be ok") {  }
    }
}

trait Bar extends FunSpec with MustMatchers { 
    describe("Hello you...") {
        it("One more!") {  }
    }
}
8
Greg