Alexey Romanov
Alexey Romanov

Reputation: 170831

Override or hide tests inherited from a parent suite

Say I have several tests in an abstract class which are intended to be run on several implementations of a trait:

trait Foo {
  def method1
  def method2
  // etc.
}

class Foo1 extends Foo { ... }

class Foo2 extends Foo { ... }

class Foo3 extends Foo { ... }

abstract class FooTest extends FunSuite with Matchers {
  val foo: Foo

  test("method1") { foo.method1 should equal(...) }

  test("method2") { ... }
}

class Foo1Tests extends FooTests { val foo = new Foo1 }
...

Unfortunately, there are a few tests which don't pass for Foo2 yet and other tests which don't pass for Foo3. Think of them as specification for Foo where incomplete implementations can already be useful. I'd like a way to mark some inherited tests as pending (or hiding them completely).

Breaking FooTests into traits based on what subclasses tests work for isn't a solution: new subclasses may be added in the future, including in external projects.

Using JUnitSuite would help, since tests would just be methods and could be overridden normally, but it's probably too late to do.

Upvotes: 3

Views: 711

Answers (1)

Wojciech Ptak
Wojciech Ptak

Reputation: 683

Any code that you put in the abstract class body will get executed, period. If you wish to be able to exclude some tests, you need a custom solution. One of them is to exclude tests based on their names:

abstract class FooTest extends FunSuite with Matchers {
  def excluded: Seq[String] = Seq.empty

  override def test(testName: String, testTags: Tag*)(testFun: => Unit) =
    if (excluded.contains(testName)) ()
      else super.test(testName, testTags: _*)(testFun)

  test("method1") { ... }
  test("method2") { ... }

Then in the subclass you can exclude some tests as follows:

class Foo1Test extends FooTest {
  override def excluded = Seq("method2")
}

You can of course come up with some more syntax sugar, but I don't think it's worth much more time if it's only meant to hide tests until they are implemented.

Also note that with this approach hides the tests completely, but you might as well mark them, tag them, or do whatever you want before calling test.

Upvotes: 1

Related Questions