161

I know that a single test can be ran by running, in sbt,

testOnly *class -- -n Tag

Is there a way of telling sbt/scalatest to run a single test without tags? For example:

testOnly *class -- -X 2

it would mean "run the second test in the class. Whatever it is". We have a bunch of tests and no one bothered to tag them, so is there a way to run a single test without it having a tag?

pme
  • 11,442
  • 2
  • 35
  • 62
Nacht
  • 8,550
  • 6
  • 26
  • 39
  • 1
    Your subject says "Scalatest-sbt". When sbt is hyphenated people would normally think of a plugin. But, just to clarify, you're talking about using [ScalaTest](http://www.scalatest.org/) from a modern version of sbt like sbt 0.12, not [joshcough/scalatest-sbt](https://github.com/joshcough/scalatest-sbt) a plugin for sbt 0.5.2-p3 written 4 years ago. Correct? – Eugene Yokota Aug 22 '13 at 15:15
  • Correct. This is an old question and I have since then figured out that no, it is not possible (as far as I know). I haven't closed it in case someone did in fact managed to figure out a way, but I no longer need this to be answered. – Nacht Aug 22 '13 at 18:19
  • There is a thread on this (with participation from both Bill Venners and Mark Harrah) at https://groups.google.com/forum/#!topic/scalatest-users/1oRMkudFAXM , but no solution yet – Seth Tisue Jan 09 '14 at 23:02
  • 1
    There's also a case for general support on running a single test sbt#911 (https://github.com/sbt/sbt/issues/911). – Eugene Yokota Apr 21 '14 at 02:40
  • 14
    Note that if you're running from the command line, [you have to enclose everything after `sbt` in quotes](https://github.com/harrah/xsbt/issues/357), e.g. `sbt "test-only *SingleTestSuite"` – Chris Martin Feb 04 '16 at 12:03

5 Answers5

218

This is now supported (since ScalaTest 2.1.3) within interactive mode:

testOnly *MySuite -- -z foo

to run only the tests whose name includes the substring "foo".

For exact match rather than substring, use -t instead of -z.

Seth Tisue
  • 28,052
  • 11
  • 78
  • 142
  • @SethTisue Would you be able to post a working example which uses `-t` for exact matching? I am unable to get it to work. – rmin Dec 16 '15 at 06:02
  • @rmin https://gist.github.com/SethTisue/f75cd8b72128ba0a0a81. (if this helps you fix your problem, let me know how I should update my answer.) – Seth Tisue Dec 16 '15 at 14:24
  • @SethTisue Thanks for the link. I tried this and it doesn't work on my particular project even though `-z` does. Not a big deal. Mine is a play app using `org.scalatestplus` version 1.1.0 so maybe it's related to that. – rmin Dec 20 '15 at 00:45
  • For JUnitSuite in Scala, it doesn't work. Do you know what kind of options should I use? – Hoang-Mai Dinh Apr 20 '16 at 07:44
  • 12
    Just to clarify, if you run it from the command line, it should be as single argument: sbt "testOnly *MySuite -- -z foo" – Sogartar Jan 11 '17 at 17:17
  • 2
    In case anyone wants to run a specific integration test (supposedly placed under `src/it`), they need to prepend `it` to `testOnly`. For instance, on the command line: `sbt "it:testOnly *MyIntegrationTestSuite"`. – laylaylom Jul 26 '17 at 18:46
  • 2
    How can I filter on multiple substrings? Tests may be grouped in a hierarchy (WordSpec), and the name parts separated by `when` and `should` can repeat between tests. To chose one specific test I need to say "name contains this AND that". – Vituel Jun 07 '18 at 09:19
115

I wanted to add a concrete example to accompany the other answers

You need to specify the name of the class that you want to test, so if you have the following project (this is a Play project):

Play Project

You can test just the Login tests by running the following command from the SBT console:

test:testOnly *LoginServiceSpec

If you are running the command from outside the SBT console, you would do the following:

sbt "test:testOnly *LoginServiceSpec"
Tyler
  • 15,509
  • 9
  • 45
  • 81
  • 30
    Upvote because apparently the double quotes are necessary: ```sbt "test:testOnly *LoginServiceSpec"``` – Jason Wheeler May 02 '17 at 19:35
  • 6
    Most useful answer for me here. But the commands can be slightly simplified; in SBT console: `testOnly *LoginServiceSpec`, and outside: `sbt "testOnly *LoginServiceSpec"` – Jonik Oct 17 '18 at 21:03
51

I don't see a way to run a single untagged test within a test class but I am providing my workflow since it seems to be useful for anyone who runs into this question.

From within a sbt session:

test:testOnly *YourTestClass

(The asterisk is a wildcard, you could specify the full path com.example.specs.YourTestClass.)

All tests within that test class will be executed. Presumably you're most concerned with failing tests, so correct any failing implementations and then run:

test:testQuick

... which will only execute tests that failed. (Repeating the most recently executed test:testOnly command will be the same as test:testQuick in this case, but if you break up your test methods into appropriate test classes you can use a wildcard to make test:testQuick a more efficient way to re-run failing tests.)

Note that the nomenclature for test in ScalaTest is a test class, not a specific test method, so all untagged methods are executed.

If you have too many test methods in a test class break them up into separate classes or tag them appropriately. (This could be a signal that the class under test is in violation of single responsibility principle and could use a refactoring.)

Seth Tisue
  • 28,052
  • 11
  • 78
  • 142
cfeduke
  • 22,322
  • 10
  • 59
  • 64
15

Just to simplify the example of Tyler.

test:-prefix is not needed.

So according to his example:

In the sbt-console:

testOnly *LoginServiceSpec

And in the terminal:

sbt "testOnly *LoginServiceSpec"
pme
  • 11,442
  • 2
  • 35
  • 62
5

Here's the Scalatest page on using the runner and the extended discussion on the -t and -z options.

This post shows what commands work for a test file that uses FunSpec.

Here's the test file:

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

  }

}

This command runs the four tests in the iLike describe block (from the SBT command line):

testOnly *CardiBSpec -- -z iLike

You can also use quotation marks, so this will also work:

testOnly *CardiBSpec -- -z "iLike"

This will run a single test:

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

This will run the two tests that start with "works with":

testOnly *CardiBSpec -- -z "works with"

I can't get the -t option to run any tests in the CardiBSpec file. This command doesn't run any tests:

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

Looks like the -t option works when tests aren't nested in describe blocks. Let's take a look at another test file:

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

-t can be used to run the single test:

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

-z can also be used to run the single test:

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

See this repo if you'd like to run these examples. You can find more info on running tests here.

Powers
  • 12,561
  • 7
  • 60
  • 82