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 TestNGSuite
s 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.