daydreamer
daydreamer

Reputation: 91999

sbt testOnly exclusion list with tag does not work

I have a test class as

import org.scalatest.FlatSpec

import scala.collection.mutable

class Tags101Spec extends FlatSpec {
  "A Stack" should "pop values in last-in-first-out order" in {
    val stack = new mutable.Stack[Int]
    stack.push(1)
    stack.push(2)
    assert(stack.pop() === 2)
    assert(stack.pop() === 1)
  }

  it should "throw NoSuchElementException if an empty stack is popped" in {
    val emptyStack = new mutable.Stack[String]
    intercept[NoSuchElementException] {
      emptyStack.pop()
    }
  }

  "A String" should "return 0 size when empty" taggedAs (Fast) in {
    assert("".size === 0)
  }

  "A Sorted List of 10 numbers" must "return 10 as the first element when reversed" taggedAs (Slow) in {
    assert(10 === (1 to 10).toList.reverse.head)
  }

}

In the same directory, I have a class called Tags which looks like

import org.scalatest.Tag

object Slow extends Tag("Slow Tests")
object Fast extends Tag("Fast Tests")

I run my tests using sbt by including a tag using -n flag and it works

sbt:Unit Testing in Scala> testOnly -- -n Fast
[info] Tags101Spec:
[info] A Stack
[info] A String
[info] A Sorted List of 10 numbers
[info] Run completed in 137 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0

Since only 1 test was taggedAs(Fast), the test ran only one test.

Now, I want to do the opposite, exclude the Fast tag and run remaining tests. Here is what I tried

sbt:Unit Testing in Scala> testOnly -- -l Fast
[info] Tags101Spec:
[info] A Stack
[info] - should pop values in last-in-first-out order
[info] - should throw NoSuchElementException if an empty stack is popped
[info] A String
[info] - should return 0 size when empty
[info] A Sorted List of 10 numbers
[info] - must return 10 as the first element when reversed
[info] Run completed in 252 milliseconds.
[info] Total number of tests run: 4
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 4, failed 0, canceled 0, ignored 0, pending 0

And as you see, it ran 4 tests, which is all the tests, including 1 Fast tagged test.

What am I missing here? How can I make exclusion tag work with sbt?

Thanks

Upvotes: 4

Views: 944

Answers (1)

Mario Galic
Mario Galic

Reputation: 48420

The argument to -l or -n should be the name string argument passed to Tags constructor, not the name of the object. For example, given

object Slow extends Tag("SlowTests")
object Fast extends Tag("FastTests")

then exclude with

testOnly -- -l FastTests

instead of

testOnly -- -l Fast

which outputs

[info] Tags101Spec:
[info] A Stack
[info] - should pop values in last-in-first-out order
[info] - should throw NoSuchElementException if an empty stack is popped
[info] A String
[info] A Sorted List of 10 numbers
[info] - must return 10 as the first element when reversed
[info] Run completed in 187 milliseconds.
[info] Total number of tests run: 3
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 3, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.

where we see A string test did not execute.

Personally I would use a fully qualified name as the name argument when constructing Tags like so

package example

import org.scalatest.Tag

object Slow extends Tag("example.Slow")
object Fast extends Tag("example.Fast")

and execute with

testOnly -- -n example.Fast

which outputs

[info] Tags101Spec:
[info] A Stack
[info] A String
[info] - should return 0 size when empty
[info] A Sorted List of 10 numbers
[info] Run completed in 158 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.

Upvotes: 5

Related Questions