ScalaTest en sbt: existe-t-il un moyen d'exécuter un seul test sans balises?

150

Je sais qu'un seul test peut être exécuté en exécutant, dans sbt,

testOnly *class -- -n Tag

Existe-t-il un moyen de dire à sbt / scalatest d'exécuter un seul test sans balises? Par exemple:

testOnly *class -- -X 2

cela signifierait "exécuter le deuxième test de la classe. Quoi qu'il en soit". Nous avons un tas de tests et personne n'a pris la peine de les étiqueter, alors y a-t-il un moyen d'exécuter un seul test sans qu'il ait une étiquette?

Nacht
la source
1
Votre sujet dit "Scalatest-sbt". Quand sbt est coupé, les gens pensent normalement à un plugin. Mais, juste pour clarifier, vous parlez d'utiliser ScalaTest à partir d'une version moderne de sbt comme sbt 0.12, pas joshcough / scalatest-sbt un plugin pour sbt 0.5.2-p3 écrit il y a 4 ans. Correct?
Eugene Yokota
Correct. C'est une vieille question et j'ai depuis lors compris que non, ce n'est pas possible (pour autant que je sache). Je ne l'ai pas fermé au cas où quelqu'un aurait réussi à trouver un moyen, mais je n'ai plus besoin de réponse.
Nacht
Il y a un fil à ce sujet (avec la participation de Bill Venners et Mark Harrah) à groups.google.com/forum/#!topic/scalatest-users/1oRMkudFAXM , mais pas encore de solution
Seth Tisue
1
Il existe également un cas de support général pour l'exécution d'un seul test sbt # 911 ( github.com/sbt/sbt/issues/911 ).
Eugene Yokota
14
Notez que si vous exécutez à partir de la ligne de commande, vous devez tout mettre sbtentre guillemets , par exemplesbt "test-only *SingleTestSuite"
Chris Martin

Réponses:

202

Ceci est désormais pris en charge (depuis ScalaTest 2.1.3) en mode interactif:

testOnly *MySuite -- -z foo

pour exécuter uniquement les tests dont le nom inclut la sous-chaîne "foo".

Pour une correspondance exacte plutôt qu'une sous-chaîne, utilisez à la -tplace de -z.

Seth Tisue
la source
@SethTisue Seriez-vous en mesure de publier un exemple de travail qui utilise -tpour la correspondance exacte? Je suis incapable de le faire fonctionner.
rmin
@rmin gist.github.com/SethTisue/f75cd8b72128ba0a0a81 . (si cela vous aide à résoudre votre problème, dites-moi comment je dois mettre à jour ma réponse.)
Seth Tisue
10
Juste pour clarifier, si vous l'exécutez à partir de la ligne de commande, il devrait être comme argument unique: sbt "testOnly * MySuite - -z foo"
Sogartar
2
Dans le cas où quelqu'un veut lancer un test d'intégration spécifique (soi - disant placé sous src/it), ils doivent précédez ità testOnly. Par exemple, sur la ligne de commande: sbt "it:testOnly *MyIntegrationTestSuite".
laylaylom
2
Comment puis-je filtrer sur plusieurs sous-chaînes? Les tests peuvent être regroupés dans une hiérarchie (WordSpec), et les parties de nom séparées par whenet should peuvent se répéter entre les tests. Pour choisir un test spécifique, je dois dire "le nom contient ceci ET cela".
Vituel
98

Je voulais ajouter un exemple concret pour accompagner les autres réponses

Vous devez spécifier le nom de la classe que vous souhaitez tester, donc si vous avez le projet suivant (il s'agit d'un projet Play):

Jouer au projet

Vous pouvez tester uniquement les Logintests en exécutant la commande suivante à partir de la console SBT:

test:testOnly *LoginServiceSpec

Si vous exécutez la commande depuis l'extérieur de la console SBT, procédez comme suit:

sbt "test:testOnly *LoginServiceSpec"
Tyler
la source
27
Vote positif car apparemment les doubles guillemets sont nécessaires:sbt "test:testOnly *LoginServiceSpec"
Jason Wheeler
5
Réponse la plus utile pour moi ici. 👍 Mais les commandes peuvent être légèrement simplifiées; dans la console SBT testOnly *LoginServiceSpecsbt "testOnly *LoginServiceSpec"
:,
49

Je ne vois pas de moyen d'exécuter un seul test non étiqueté dans une classe de test, mais je fournis mon flux de travail car il semble être utile pour quiconque se heurte à cette question.

Depuis une session sbt:

test:testOnly *YourTestClass

(L'astérisque est un caractère générique, vous pouvez spécifier le chemin complet com.example.specs.YourTestClass.)

Tous les tests de cette classe de test seront exécutés. Vous êtes probablement plus préoccupé par les tests échoués, alors corrigez toutes les implémentations défaillantes, puis exécutez:

test:testQuick

... qui n'exécutera que les tests qui ont échoué. (La répétition de la test:testOnlycommande la plus récemment exécutée sera la même que test:testQuickdans ce cas, mais si vous divisez vos méthodes de test en classes de test appropriées, vous pouvez utiliser un caractère générique pour rendre test:testQuickplus efficace la manière de réexécuter les tests qui ont échoué.)

Notez que la nomenclature des tests dans ScalaTest est une classe de test, pas une méthode de test spécifique, donc toutes les méthodes non marquées sont exécutées.

Si vous avez trop de méthodes de test dans une classe de test, divisez-les en classes séparées ou étiquetez-les de manière appropriée. (Cela pourrait indiquer que la classe testée est en violation du principe de responsabilité unique et pourrait utiliser une refactorisation.)

cfeduke
la source
10
pour ceux qui font face à "Aucun test n'a été exécuté": *YourTestClassdoit être le nom de la classe. Pas le nom du fichier.
MKatleast3
1
c'était testOnly au lieu de test uniquement pour moi.
Jan Clemens Stoffregen
11

Juste pour simplifier l'exemple de Tyler.

test:-prefix n'est pas nécessaire.

Donc selon son exemple:

Dans la sbt-console:

testOnly *LoginServiceSpec

Et dans le terminal:

sbt "testOnly *LoginServiceSpec"
pme
la source
0

Voici la page Scalatest sur l' utilisation du runner et la discussion approfondie sur les options -tet-z .

Cet article montre quelles commandes fonctionnent pour un fichier de test qui utilise FunSpec.

Voici le fichier de test:

package com.github.mrpowers.scalatest.example

import org.scalatest.FunSpec

class CardiBSpec extends FunSpec {

  describe("realName") {

    it("returns her birth name") {
      assert(CardiB.realName() === "Belcalis Almanzar")
    }

  }

  describe("iLike") {

    it("works with a single argument") {
      assert(CardiB.iLike("dollars") === "I like dollars")
    }

    it("works with multiple arguments") {
      assert(CardiB.iLike("dollars", "diamonds") === "I like dollars, diamonds")
    }

    it("throws an error if an integer argument is supplied") {
      assertThrows[java.lang.IllegalArgumentException]{
        CardiB.iLike()
      }
    }

    it("does not compile with integer arguments") {
      assertDoesNotCompile("""CardiB.iLike(1, 2, 3)""")
    }

  }

}

Cette commande exécute les quatre tests du iLikebloc describe (à partir de la ligne de commande SBT):

testOnly *CardiBSpec -- -z iLike

Vous pouvez également utiliser des guillemets, cela fonctionnera donc également:

testOnly *CardiBSpec -- -z "iLike"

Cela exécutera un seul test:

testOnly *CardiBSpec -- -z "works with multiple arguments"

Cela exécutera les deux tests qui commencent par "fonctionne avec":

testOnly *CardiBSpec -- -z "works with"

Je ne peux pas avoir la -tpossibilité d'exécuter des tests dans le CardiBSpecfichier. Cette commande n'exécute aucun test:

testOnly *CardiBSpec -- -t "works with multiple arguments"

Il semble que l' -toption fonctionne lorsque les tests ne sont pas imbriqués dans des describeblocs. Jetons un œil à un autre fichier de test:

class CalculatorSpec extends FunSpec {
  it("adds two numbers") {
    assert(Calculator.addNumbers(3, 4) === 7)
  }
}

-t peut être utilisé pour exécuter le test unique:

testOnly *CalculatorSpec -- -t "adds two numbers"

-z peut également être utilisé pour exécuter le test unique:

testOnly *CalculatorSpec -- -z "adds two numbers"

Consultez ce dépôt si vous souhaitez exécuter ces exemples.

Pouvoirs
la source