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 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.
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-2025 Artima, Inc. All Rights Reserved.