Version 3.0.0 is a major upgrade to ScalaTest and Scalactic, the culmination of over a year of effort. Although it includes many enhancements, we kept a close eye on compatibility with existing ScalaTest/Scalactic 2.x code. We also tried hard to preserve what people liked about both ScalaTest and Scalactic: that it is simple, the code is clean and clear, it's fully documented, and because of very thorough testing, it “just works.”
For information on how to include ScalaTest in your project, see the Install page. For information on how to use Scalactic in your production code, see its Install page.
The most significant enhancement to ScalaTest and Scalactic in the 3.0.0 release is that they now fully support Scala.js. The advent of Scala.js represented a major, completely unforeseen change in requirements for ScalaTest. As a result, Scala.js support required a very large number of changes to the ScalaTest's eight-year old codebase. Fortunately, the changes were mostly internal to ScalaTest, so little existing ScalaTest user code (i.e., for Scala on the JVM) should break because of the addition of Scala.js support.
ScalaTest and Scalactic 3.0.0 include a few changes that could in theory break 2.2.x user code, but we expect the number of users and amount of code affected to be small in practice. However, because features that have been deprecated for at least a year (primarily features that were deprecated in October 2013, when 2.0.0 was released) have been removed, we recommend you clear any deprecation warnings given by ScalaTest and Scalactic version 2.2.6 prior to upgrading. For many users, upgrading to ScalaTest and/or Scalactic 3.0.0 should require only a clean build with the new version. ScalaTest 3.0.0 does include several new deprecations as well as the deprecation expirations. For more detail, see the breaking changes, new deprecations, and the expired deprecations sections below.
Here's a list of the main enhancements in Scalactic 3.0.0:
org.scalactic.exceptions.NullArgumentException
, and changed all places in ScalaTest
and Scalactic that threw NullPointerException
in earlier releases to throw NullArgumentException
.
Although throwing NullPointerException
is the tradition in Java APIs, Scala.js does not support a
NullPointerException
. To make the behavior
consistent on both the JVM and Scala.js, the change to throwing NullArgumentException
was made throughout
the ScalaTest and Scalactic, including the requireNonNull
method of trait Requirements
.PosInt
, PosZInt
, PosFloat
, etc., have been
added in package org.scalactic.anyvals
along with CompileTimeAssertions
, which you can help you
create your own restricted value AnyVal
types.Constraint
to CanEqual
and made a deprecated type alias for any user code currently
referring to Constraint
.Chain
an AnyVal
that wraps List
instead of an AnyRef
.
Dropped its inheritance relationship with PartialFunction
.Good
and Bad
, specifying Nothing
for that now missing type parameter
when extending Or
. This is a breaking change, but one which hopefully won't affect much client code in practice.validating
method to TrySugar
, and added FutureSugar
also with a validating
method. Also added ValidationFailedException
to support these validating
methods as well.Position
that supports capturing of caller's source code position through macro.Or
, Every
, and Validation
extended both Product
and Serializable
to improve type inference.Here's a list of the main enhancements in ScalaTest 3.0.0:
org.scalatest.compatible.Assertion
to serve
as the actual type required by test bodies in the new async styles. Eventually this will be released as a separate Java artifact, just a simple
marker interface, so third-party libraries can provide assertions that ScalaTest will recognize as valid assertions without requiring the
third party libraries depend on a version of ScalaTest. They will only need to depend on a version of the scalatest-compat.jar Java artifact, which
will be very stable.org.scalatest.Assertion
as a type alias for the newly added marker interface, org.scalatest.compatible.Assertion
.Unit
to Assertion
.org.scalatest
styles from Unit
to Any
so that users who
compile with -Ywarn-value-discard
will not get warnings for tests that end in an assertion or matcher expression,
which no longer has a Unit
result type.AsyncFunSuite
,
AsyncFunSpec
,
AsyncFlatSpec
,
AsyncFreeSpec
,
AsyncWordspec
, and
AsyncFeatureSpec
—in which
the result type of tests is Future[Assertion]
. All asynchronous style traits mixed in RecoverMethods
that contains recoverToExceptionIf
for asynchronous use case for intercept
and recoverToSucceededIf
for asynchronous use case for assertThrows
.
exists
and forEvery
methods to TableDrivenPropertyChecks
. exists
succeeds if at
least one row of the table satisfies the assertion block. forEvery
requires that all rows of the table satisfy the assertion
block, like forAll
, but reports information about all rows that fail the assertion block (where forAll
just reports the first row that fails and short circuits).Matchers
with oneElementOf
, noElementsOf
, atLeastOneElementOf
, atMostOneElementOf
, allElementsOf
, inOrderElementsOf
syntax, all of which must follow contain
.BeforeAndAfterEach
and BeforeAndAfter
so that it will interact properly and
consistently when mixed in either before and after OneInstancePerTest
.Prettifier
to Assertions
, Matchers
, and other classes that produce error messages. This makes it easy to customize the string representation of a type in an error message, for example, to reduce the size of string representations of large collections.source.Position
to
Assertions
, Matchers
, and other classes that produce error messages. This allowed us to replace the JVM-specific technique we used previously to determine the file name and line number of the offending line of test code prior to 3.0, which involved inspecting the stack. This technique did not work at all when running Scala.js tests on Node.js or Phantom.js, and allows us on the JVM to access an additional piece of information that wasn't available when inspecting the stack: the full path to the source file. The full path was desired for Ensime and will eventually make it out to the reporters (we didn't have time to get it to the reporters in 3.0.0). This also makes it very simple for users to define custom assertions and get the right stack depth (really, the right filename and line number). We've wanted to solve that problem for a very long time, and users have occasionally requested it. For example, it was requested for the scalaz-scalatest library that created custom ScalaTest assertions for Scalaz.failedCodeFilePathname
field to StackDepth
, which is mixed into "stack depth exceptions." Changed
all stack depth exceptions (subclasses of StackDepthException
and JUnitTestFailedError
) so that the constructor takes
either a Position
or a stack depth function: Either[Position, StackDepthException => Int]
. In most situations a
Position
will now be available, and it will be passed to the constructor. But in some situations a Position
cannot
be used and the old approach of using a stack depth function to find the failing line of source code will still be used.
be used instead of a filePathname
field to LineInFile
to allow the full path name of the source file
that is provided by Position
to be passed to reporters.Outcome
, PatienceConfigParam
, Event
, Formatter
, Location
, PropertyCheckConfigParam
, Query
, and >>>>>>Units
extended both Product
and Serializable
to improve type inference.1) 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
.
2) 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
.
3) 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
).
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 = { // ... } }
5) 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.
6) 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.
ConversionCheckedTripleEquals
, because code that is using it can still compile but mean something quite different
if it is removed.
execute
method on Suite
. Please use the empty parens version instead: execute()
.
withGood
method on the org.scalactic.Accumulation
object that takes one Or
and one transformation function. Please call map
on the Or
and pass in the same function instead.asOr
method on Or
, because its main use case is now obsolete, since
Good(value).orBad[Type]
and Good[Type].orBad(value)
now return Or
. You can simply remove asOr
invocation from such expressions, or if used elsewhere, replace it with a widening type annotation, such as:
(hasTypeGood: Int Or ErrorMessage)
.
org.scalactic.Constraint
. Please change any occurrences to its new name, CanEqual
. (Constraint
should appear explicitly in user code only very rarely if at all, as normally it will be used only implicitly.)Filter
companion object because the inheritance relationship between Filter
and Function2[Set[String], Map[String, Set[String]], List[(String, Boolean)]]
was removed.
PropertyCheckConfig
in
favor of PropertyCheckConfiguration
in
object org.scalatest.prop.Configuration
. The new class uses org.scalactic.anyvals
and instead of an absolute
maxDiscarded
value, calculates that value by multiplying a maxDiscardFactor
by the minSuccessful
value.
before
/afterEach(TestData)
methods in BeforeAndAfterEach
(deprecated in ScalaTest 2.0) in favor of BeforeAndAfterEachTestData
.org.scalatest.FailureOf
(deprecated in ScalaTest 2.0) in favor of OutcomeOf
.expect
and expectResult
(deprecated in ScalaTest 2.0) in Assertions
in favor of assertResult
.Suite
as a style trait (deprecated in ScalaTest 2.0) in favor of Spec
(which itself was deprecated in 3.0.0
and renamed org.scalatest.refspec.RefSpec
.)assert
and assume
methods whose ===
and !==
operator return Option[String]
(deprecated in ScalaTest 2.0) in favor of assert
and assume
macros that return Boolean
.
plusOrMinus
(deprecated in ScalaTest 2.0) operator used with Matchers
in
favor of the +-
symbol.ShouldMatchers
(deprecated in ScalaTest 2.0)
and MustMatchers
(deprecated in ScalaTest 1.9.2), both members of package
org.scalatest.matchers
, in favor of Matchers
,
and MustMatchers
,
which resides in package org.scalatest
.
beforeAll
and afterAll
methods of trait
BeforeAndAfterAll
that take a config map (deprecated in ScalaTest 2.0)
in favor of BeforeAndAfterAllConfigMap
.
given
/when
/then
/and
methods of trait
GivenWhenThen
(deprecated in ScalaTest 2.0) in favor of capitalized forms,
Given
/When
/Then
/And
, because then
was deprecated as an identifier in Scala 2.10.
apply
methods on Filter
(deprecated in ScalaTest 2.0), in favor of
two new ones added in ScalaTest 2.0 that take an additional suiteId
parameter.AbstractSuite
(deprecated in ScalaTest 2.0)
in favor of trait SuiteMixin
, which since 2.0 has served as the base class
for stackable traits that can be mixed into Suite
.apply
method on Distributor
(deprecated in ScalaTest 2.0) in favor of the apply
method added in 2.0 that takes a Args
.
Visit ScalaTest Release Notes for links to the release notes of all previous versions, or step back in time by visiting the release notes for the previous version.
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.