ScalaTest User Guide

Getting started

Selecting testing styles

Defining base classes

Writing your first test

Using assertions

Tagging your tests

Running your tests

Sharing fixtures

Sharing tests

Using matchers

Testing with mock objects

Property-based testing

Asynchronous testing

Using Scala-js

Using Inside

Using OptionValues

Using EitherValues

Using PartialFunctionValues

Using PrivateMethodTester

Using WrapWith

Philosophy and design

Migrating to 3.0

Migrating from ScalaTest 2.x to 3.0

We have always worked very hard to maintain source compatibility from one release of ScalaTest to the next. Upgrading is usually simply a matter of bumping the ScalaTest version number in your build doing a full recompile, and over time cleaning up any deprecation warnings. With ScalaTest 3.0, however, we made some improvements for which it was not possible to deprecate, so some of your existing code may not compile. Neverthless, we expect the vast majority of existing ScalaTest user code to just recompile as is.

To ensure the smoothest migration, first please eliminate any deprecation warnings being emitted by your current version of ScalaTest on your existing code. (For best results, upgrade to 2.2.6 first and clear any deprecation warnings, though many of those reported will still be deprecated and working in 3.0.) Then just bump the ScalaTest version number to 3.0 and do a full build. If you encounter compilation errors, check the list below for help in resolving them.

These are the points of potential breakage in ScalaTest 3.0, which are described in the sections that follow:

  1. Good and Bad type parameters
  2. Prettifier changes
  3. TimeLimitedTests
  4. Mixin traits that override withFixture
  5. Signature of Status.whenCompleted
  6. The fragile base class problem
  7. Inferred result types in JUnitSuite, JUnit3Suite, and TestNGSuite

If you have any confusion about how to migrate your ScalaTest 2.x code to ScalaTest 3.0, or encounter other problems, please post your specific issues to scalatest-users and we'll be happy to help.

Good and Bad type parameters

The main breaking change in Scalactic in 3.0.0 is that we dropped an unnecessary type parameter in Good and Bad, specifying Nothing for that now missing type parameter when extending Or. This will only affect code in which the type parameters for Good or Bad were given explicitly, which we expect will be rare in practice. In situations where the type parameters for Good and Bad were being inferred, the code should continue to work as before.

Prettifier changes

Because we started using Prettifier as an implicit type in 3.0, we dropped its inheritance relationship with Any => String (so that an implicit Prettifier won't be usable as in implicit conversion from Any to String). It is unlikely anyone was actually using Prettifier as a Function1, but if so, that will no longer compile and you'll need to convert it to Any => String explicitly.) Furthermore, since Prettifier was now being used as an implicit itself, we changed PrettyMethods to require an implicit Prettifier instead of a PrettifierConfig. Thus if you defined an overridden implicit PrettifierConfig, that will no longer compile, and you'll need to replace it with an implicit Prettifier instead. For a quick fix, we left the old PrettyMethods behavior in under the name DeprecatedPrettyMethods. If you just change PrettyMethods to DeprecatedPrettyMethods, that will get your PrettifierConfig code compiling and working again, but you'll receive a deprecation warning until you replace the PrettifierConfig with Prettifier, and DeprecatedPrettyMethods with PrettyMethods.

TimeLimitedTests

In ScalaTest, one potentially breaking change is in TimeLimitedTests, which now uses an implicit >Signaler instead of an implicit Interruptor. Whereas the default Interruptor in TimeLimitedTests prior to 3.0 was a ThreadInterruptor, the default signaler is >DoNotSignal. This default makes more sense with the advent of ScalaTest 3.0's support for Scala.js and async testing styles. If you were relying on the default behavior of interrupting a thread on the JVM in ScalaTest 2.2.x, you'll need to define an implicit val referring to a ThreadSignaler. If you had alreday overriden the default Interuptor (referenced from defaultInterruptor) you'll need to define a corresponding Signaler instead (unless you had defined the Interruptor to be DoNotInterrupt, in which case you can just remove the defaultInterruptor override entirely and enjoy the default Signaler, DoNotSignal).

Mixin traits that override withFixture

4) In 3.0.0, the withFixture method has been moved from Suite to a new trait, >TestSuite. This was done to make room for a withFixture method with a different signature in AsyncTestSuite. If you factored out a withFixture method into a separate "suite mixin" trait, you'll need to change "Suite" to "TestSuite" and "SuiteMixin" to "TestSuiteMixin". For example, given this trait from 2.2.6:

trait YourMixinTrait extends SuiteMixin { this: Suite =>
 abstract override def withFixture(test: NoArgTest): Outcome = {
   // ...
 }
}

You will need to add the "Test" prefix, like this:

trait YourMixinTrait extends TestSuiteMixin { this: TestSuite =>
 abstract override def withFixture(test: NoArgTest): Outcome = {
   // ...
 }
}

Signature of Status.whenCompleted

In ScalaTest we changed the signature of the whenCompleted method of trait Status changed. Where it previously took a function of type Boolean => Unit, it now takes a function of type Try[Boolean] => Unit. This breaking change should affect very few users.

Inferred result types in JUnitSuite, JUnit3Suite, and TestNGSuite

Lastly, because the result type of assertions and matcher expressions has changed from Unit to Assertion, any tests in JUnitSuite, JUnit3Suite, and TestNGSuites that ended with an assertion or matcher expression, and used neither the (now deprecated) procedure style "...@Test def theTestName() {..." nor an explicit type annotation, "...@Test def theTestName(): Unit = {...", will no longer be recognized by those frameworks. These test frameworks require that the result type of test methods be void in Java, which equates to Unit in Scala.

Only JUnitSuite, which is based on JUnit 4, will indicate with a test failure that a method annotated with @Test did not have result type void. You will get a test failure with an error message like:

java.lang.Exception: Method verifySomething() should be void

By contrast, any such tests in JUnit3Suite and TestNGSuite will be silently ignored by JUnit 3 and TestNG. To get the tests running again in any of these styles, ensure an explicit result type is placed on each test method, like:

@Test def verifySomething(): Unit = {
  val x = 1
  assert(x == 1)
}

If this change has a significant impact on your project, please contact Artima by emailing Bill Venners at bill AT artima.com. We are happy to help you upgrade your JUnitSuite, JUnit3Suite, or TestNGSuite, tests to ScalaTest 3.0.

The fragile base class problem

To our knowledge, the only other source of potential breakage in ScalaTest 2.0 is the fragile base class problem. We have added fields and methods to traits such as Matchers and Suite in 2.0 that may conflict with fields and methods in your existing classes and cause a compiler error. Such issues can usually be easily fixed locally with simple renames or refactors.

ScalaTest is brought to you by Bill Venners and Artima.
ScalaTest is free, open-source software released under the Apache 2.0 license.

If your company loves ScalaTest, please consider sponsoring the project.

Copyright © 2009-2024 Artima, Inc. All Rights Reserved.

artima