ScalaTest in sbt: Gibt es eine Möglichkeit, einen einzelnen Test ohne Tags auszuführen?

150

Ich weiß, dass ein einzelner Test ausgeführt werden kann, indem in sbt,

testOnly *class -- -n Tag

Gibt es eine Möglichkeit, sbt / scalatest anzuweisen, einen einzelnen Test ohne Tags auszuführen? Beispielsweise:

testOnly *class -- -X 2

es würde bedeuten "den zweiten Test in der Klasse durchführen. Was auch immer es ist". Wir haben eine Reihe von Tests, und niemand hat sich die Mühe gemacht, sie zu markieren. Gibt es also eine Möglichkeit, einen einzelnen Test ohne Tag durchzuführen?

Nacht
quelle
1
Ihr Betreff sagt "Scalatest-sbt". Wenn sbt getrennt ist, denken die Leute normalerweise an ein Plugin. Um dies zu verdeutlichen, sprechen Sie über die Verwendung von ScalaTest aus einer modernen Version von sbt wie sbt 0.12 und nicht von joshcough / scalatest-sbt, einem Plugin für sbt 0.5.2-p3, das vor 4 Jahren geschrieben wurde. Richtig?
Eugene Yokota
Richtig. Dies ist eine alte Frage und ich habe seitdem herausgefunden, dass nein, es ist nicht möglich (soweit ich weiß). Ich habe es nicht geschlossen, falls es tatsächlich jemandem gelungen ist, einen Weg zu finden, aber ich brauche dies nicht mehr, um beantwortet zu werden.
Nacht
Es gibt einen Thread dazu (unter Beteiligung von Bill Venners und Mark Harrah) unter groups.google.com/forum/#!topic/scalatest-users/1oRMkudFAXM , aber noch keine Lösung
Seth Tisue
1
Es gibt auch Gründe für allgemeine Unterstützung beim Ausführen eines einzelnen Tests sbt # 911 ( github.com/sbt/sbt/issues/911 ).
Eugene Yokota
14
Beachten Sie, dass Sie, wenn Sie von der Befehlszeile aus laufen, alles nachher sbtin Anführungszeichen setzen müssen , z. B.sbt "test-only *SingleTestSuite"
Chris Martin

Antworten:

202

Dies wird jetzt (seit ScalaTest 2.1.3) im interaktiven Modus unterstützt:

testOnly *MySuite -- -z foo

um nur die Tests auszuführen, deren Name den Teilstring "foo" enthält.

Verwenden Sie -tanstelle von Teilzeichenfolge anstelle von Teilzeichenfolge anstelle von -z.

Seth Tisue
quelle
@SethTisue Könnten Sie ein Arbeitsbeispiel veröffentlichen, das -tfür eine genaue Übereinstimmung verwendet wird? Ich kann es nicht zum Laufen bringen.
Rmin
@rmin gist.github.com/SethTisue/f75cd8b72128ba0a0a81 . (Wenn dies Ihnen hilft, Ihr Problem zu beheben, lassen Sie mich wissen, wie ich meine Antwort aktualisieren soll.)
Seth Tisue
10
Nur um zu verdeutlichen, wenn Sie es über die Befehlszeile ausführen, sollte es als einzelnes Argument sein: sbt "testOnly * MySuite - -z foo"
Sogartar
2
Falls jemand will eine spezifische Integrationstest (angeblich platziert unter laufen src/itmüssen sie) zu prepend itzu testOnly. Zum Beispiel in der Kommandozeile : sbt "it:testOnly *MyIntegrationTestSuite".
Laylaylom
2
Wie kann ich nach mehreren Teilzeichenfolgen filtern? Tests können in einer Hierarchie (WordSpec) gruppiert werden, und die Namensteile werden durch Tests getrennt whenund shouldkönnen zwischen diesen wiederholt werden. Um einen bestimmten Test auszuwählen, muss ich sagen "Name enthält dies UND das".
Vituel
97

Ich wollte ein konkretes Beispiel hinzufügen, um die anderen Antworten zu begleiten

Sie müssen den Namen der Klasse angeben, die Sie testen möchten. Wenn Sie also das folgende Projekt haben (dies ist ein Play-Projekt):

Projekt abspielen

Sie können nur die LoginTests testen , indem Sie den folgenden Befehl über die SBT-Konsole ausführen:

test:testOnly *LoginServiceSpec

Wenn Sie den Befehl von außerhalb der SBT-Konsole ausführen, gehen Sie wie folgt vor:

sbt "test:testOnly *LoginServiceSpec"
Tyler
quelle
27
Upvote, weil anscheinend die doppelten Anführungszeichen notwendig sind:sbt "test:testOnly *LoginServiceSpec"
Jason Wheeler
5
Die nützlichste Antwort für mich hier. 👍 Die Befehle können jedoch leicht vereinfacht werden. in der SBT-Konsole: testOnly *LoginServiceSpecund außerhalb:sbt "testOnly *LoginServiceSpec"
Jonik
49

Ich sehe keine Möglichkeit, einen einzelnen Test ohne Tags innerhalb einer Testklasse auszuführen, aber ich biete meinen Workflow an, da er für jeden nützlich zu sein scheint, der auf diese Frage stößt.

Aus einer sbt-Sitzung heraus:

test:testOnly *YourTestClass

(Das Sternchen ist ein Platzhalter. Sie können den vollständigen Pfad angeben com.example.specs.YourTestClass.)

Alle Tests innerhalb dieser Testklasse werden ausgeführt. Vermutlich sind Sie am meisten mit fehlgeschlagenen Tests beschäftigt. Korrigieren Sie daher alle fehlgeschlagenen Implementierungen und führen Sie dann Folgendes aus:

test:testQuick

... die nur fehlgeschlagene Tests ausführen. (Das Wiederholen des zuletzt ausgeführten test:testOnlyBefehls ist dasselbe wie test:testQuickin diesem Fall. Wenn Sie Ihre Testmethoden jedoch in geeignete Testklassen aufteilen, können Sie einen Platzhalter verwenden, um test:testQuickfehlerhafte Tests effizienter erneut auszuführen.)

Beachten Sie, dass die Nomenklatur für den Test in ScalaTest eine Testklasse und keine bestimmte Testmethode ist, sodass alle Methoden ohne Tags ausgeführt werden.

Wenn Sie zu viele Testmethoden in einer Testklasse haben, teilen Sie diese in separate Klassen auf oder kennzeichnen Sie sie entsprechend. (Dies könnte ein Signal dafür sein, dass die getestete Klasse gegen das Prinzip der Einzelverantwortung verstößt und ein Refactoring verwenden könnte.)

cfeduke
quelle
10
für diejenigen, die vor "Keine Tests wurden ausgeführt" stehen: *YourTestClassmuss Klassenname sein. Kein Dateiname.
MKatleast3
1
es war testOnly statt test-only für mich.
Jan Clemens Stoffregen
11

Nur um das Beispiel von Tyler zu vereinfachen.

test:-prefix wird nicht benötigt.

Also nach seinem Beispiel:

In der sbtKonsole:

testOnly *LoginServiceSpec

Und im Terminal:

sbt "testOnly *LoginServiceSpec"
pme
quelle
0

Hier ist die Scalatest-Seite zur Verwendung des Läufers und die ausführliche Diskussion über die -tund -zOptionen .

Dieser Beitrag zeigt, welche Befehle für eine verwendete Testdatei funktionieren FunSpec.

Hier ist die Testdatei:

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)""")
    }

  }

}

Dieser Befehl führt die vier Tests im iLikeBeschreibungsblock aus (über die SBT-Befehlszeile):

testOnly *CardiBSpec -- -z iLike

Sie können auch Anführungszeichen verwenden, damit dies auch funktioniert:

testOnly *CardiBSpec -- -z "iLike"

Dadurch wird ein einzelner Test ausgeführt:

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

Dadurch werden die beiden Tests ausgeführt, die mit "funktioniert mit" beginnen:

testOnly *CardiBSpec -- -z "works with"

Ich kann -tkeine Tests in der CardiBSpecDatei ausführen . Dieser Befehl führt keine Tests aus:

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

Die -tOption funktioniert anscheinend, wenn Tests nicht in describeBlöcken verschachtelt sind. Schauen wir uns eine andere Testdatei an:

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

-t kann verwendet werden, um den einzelnen Test auszuführen:

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

-z kann auch verwendet werden, um den einzelnen Test auszuführen:

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

Sehen Sie sich dieses Repo an, wenn Sie diese Beispiele ausführen möchten.

Befugnisse
quelle