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:
Good and Bad type parameters
Prettifier changes
TimeLimitedTests
- Mixin traits that override
withFixture
- Signature of
Status.whenCompleted
- The fragile base class problem
- 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.