For historians, this page preserves the relevant sections of the individual release notes for major 2.0 milestones and release candidates. For a quicker to read and more understandable overview, see the Highlights section of the 2.0 release notes.
2.0.RC3 Highlights:
update
method in style traits to note
, Updater
to Notifier
,
Updating
to Notifying
.markup
text.2.0.RC2 Highlights:
Waiter
(contributed by Nick Wade)TestWildcardSelector
s weren't being handled, which will be needed for
sbt 0.13.1.left
to leftSide
in
Equalizer
and")'
CheckingEqualizer
so that it")'
doesn't conflict with a left
method added by an implicit conversion in scalaz.toString
s to the Equality
's")'
produced by TolerantNumerics
SuiteMixin
, to")'
enable the stackable trait pattern for those methodsscan
methods on Every
.assume
to use similar macros as assert
for better error messages
in Assertions
assert
and assume
methods of
Assertions
when a string "clue" message")'
is provided to match that of AppendedClues
2.0.RC1 Highlights:
assert
macros, made TripleEquals
(whose ===
and !==
operators
return Boolean
) and deprecated the Legacy
variants whose ===
and !==
operator return Option[String]
contain
oneOf
, allOf
, noneOf
,
atLeastOneOf
, atMostOneOf
, inOrderOnly
, and inOrder
SpanSugar
scala-reflect
library to ScalaTest pom, now that we're using assert macrostrap
method to Assertions
to make it easier to work with assertions and matcher expressions
in the Scala interpreter2.0.M8 Highlights:
ScalaTest/ScalaUtils 2.0.M8 mostly contains Scaladoc documentation, but also contains some adjustments to Or
in in ScalaUtils,
the addition of a OneArgTest
factory method, and one important bug fix.
Here is the list of changes in 2.0.M8 compared to 2.0.M7:
BeforeAndAfterAll
so that it no longer blocks waiting for")'
nested suites to complete before executing afterAll
. This approach was taken originally to ensure that afterAll
ran on the
same thread as beforeAll
, and worked fine with ScalaTest prior to adding support for the new sbt Framework API. With the new Framework API,
ScalaTest by default will allow sbt to run nested suites on its thread pool rather than making a separate thread pool when parallel execution is enabled
in an sbt build. This caused a deadlock when nested suites were used with an sbt build with BeforeAndAfterAll
, so in 2.0.M8, we have removed
the guarantee that afterAll
will execute on the same thread as beforeAll
. This removes the potential for deadlock, but means
that users will need to synchronize access to any shared data in beforeAll
and afterAll
.OneArgTest
factory method to support the use")'
case of needing to do further fixture set and teardown work with a FixtureParam
.orElse
method to Or
that takes a by-name.getOrElse
method of Or
take a by-name.asOr
method to Or
and")'
asEvery
method to Every
to provide an easy")'
way to widen more specific sub-type types to the supertypes.Interval
,")'
Timeout
,")'
and PatienceConfigParam
types out of")'
trait PatienceConfiguration
and put them instead in its companion object. This way their names won't be in scope in tests unless imported, and won't conflict
with like-named classes, such as the Interval
from Joda Time.Or
such that all methods that accumulate are actually")'
on an Accumulatable
class available through an implicit")'
conversion defined in trait Validations
, which ensures that")'
the accumulated result type is the least upper bound of the two input accumulated types.transform
method on Or
in favor of a")'
new one similar in spirit to the transform
method on scala.util.Try
.2.0.M7 Highlights:
ScalaTest 2.0.M7 mostly contains Scaladoc documentation, but also contains one new feature in ScalaUtils:
Or
, an "either with attitude," and")'
Every
, an ordered data structure that can have one-to-many elements,")'
but never be empty. An Or
can be either Good
or")'
Bad
. If the Bad
type is an Every
, you can")'
use various means to accumulate errors during data validations. I (Bill Venners) will attempt to get a blog post introducing Or
out within the next few days.
In the meantime, your best bet if you want to know more is to scan the tests in
OrSpec
,
EverySpec
, and
ValidationsSpec
.
And feel free to ask questions on scalatest-users. Here is the list of changes in 2.0.M7 compared to 2.0.M6:
TestPendingException
from a case class back")'
into a class.Composifier
class in the implicit conversion provided by MatcherProducers
.AMatcher
and AnMatcher
in the org.scalatest.matchers
package. Although included in 2.0.M6, these turned out to
be inconsistent with the rest of the matcher enhancements, thus incomplete. We will bring them back 2.0 once they are fully finished.TypeConstraint
to
Constraint
in the org.scalautils
package.legacyEqual
matcher syntax from Matchers
.sbt.log.noformat
in both the old and new sbt Framework API implementation.toString
implementations.2.0.M6 Highlights:
The first big change is ScalaTest 2.0.M6 includes a package named org.scalautils
.")'
This package is focused on aspects of equality, normalization, and tolerance that may make sense to use in your production code as well as your tests. The
org.scalautils
package is included in the ScalaTest jar, but is also available separately in a ScalaUtils jar. The idea is you can add a dependency
on ScalaUtils in your production classpath, so you can use it in your production code without having ScalaTest on the classpath. You should never
include ScalaTest in your production classpath, because when ScalaTest doesn't like something it tends to throw a TestFailedException
. ScalaUtils will
always be released alongside ScalaTest, with version numbers that match exactly. So when ScalaTest 2.1 is released, for example, ScalaUtils 2.1 will also be released.
ScalaUtils 2.0.M6 allows you to customize what equality means for a type T
by defining an
Equality[T]
typeclass. This can be used with the ===
operator in")'
production code and in tests, with assertions, the should
equal
, shouldEqual
, and the new-in-2.0.M6
should
===
matcher syntax.
ScalaUtils defines a default Equality
that will be used by default for any")'
type T
for which a more specific implicit Equality[T]
is not available. The default equality will first call the deep
method
on an array on either the left or right side (or both sides), then use ==
to determine equality. This default is compatible with ScalaTest's existing
===
operator and equal
and be
matchers, so existing test code will continue to work as before.
ScalaUtils 2.0.M6 also provides a way to get a compile-time type error if two types being compared with ===
don't adhere to a tunable
TypeConstraint. By default you can compare any type with any type (which means")'
all existing uses of ScalaTest's ===
continue to compile and work as before). But you can use traits such as
TypeCheckedTripleEquals
,")'
ConversionCheckedTripleEquals
,")'
and TraversableEqualityConstraints
to get a")'
compile error when comparing, for example, an Option[String]
with a String
for equality. (Equality
and
TypeConstraint
are inspired in part by the Equal
typeclass in scalaz.)
ScalaUtils 2.0.M6 also includes a Tolerance trait that facilitates checking tolerances of numeric types with a +-
symbolic operator. The plusOrMinus
operator used with matchers previously in ScalaTest has been deprecated in 2.0 in favor of the +-
symbol, which is also now more broadly usable. In addition to:")'
result should be (2.0 +- 0.1)
You can now also use the syntax with should equal
, shouldEqual
, and shouldBe
syntax:
result should equal (2.0 +- 0.1) result shouldEqual 2.0 +- 0.1 result shouldBe 2.0 +- 0.1 result should === (2.0 +- 0.1)
Or just with plain-old ===
, in an assertion in tests or just as part of a Boolean expression in production code:
// In tests: assert(result === (3.0 +- 0.2)) // In production code: if (result === (2.0 +- 0.1)) "close enough" else "sorry"
ScalaUtils 2.0.M6 also contains a Normalization
trait that allows you to")'
define strategies for normalizing types. The NormalizingEquality
trait")'
allows you to define an Equality[T]
in terms of a normalization of that type T
by first normalizing the left and, if
also a T
, the right hand side, then using a specified "after-normalization Equality
" to compare the normalized values.
ScalaUtils 2.0.M6 also includes an Explicitly
DSL for defining an")'
implicit Equality
parameter explicitly. If you want to customize equality for a type in general, you would usually want to place an
implicit Equality[T]
for that type in scope (or in T
's companion object). That implicit equality definition will then be picked
up and used when that type is compared for equality with the equal
matcher in tests and with ===
in both tests and production code.
If you just want to use a custom equality for a single comparison, however, you may prefer to pass it explicitly. For example, if you have an implicit
Equality[String]
in scope, you can force a comparison to use the default equality with this syntax:
// In production code: if ((result === "hello")(decided by defaultEquality)) true else false // In tests: result should equal ("hello") (decided by defaultEquality)
The explicitly DSL also provides support for specifying a one-off equality that is based on a normalization. For example, ScalaUtils has a
StringNormalizations
trait that provides trimmed
and lowerCased
methods that return Normalization[String]
s that normalize by trimming and lower-casing, respectively. If you bring those into scope by mixing in or importing the members of StringNormalizations
, you could use the explicitly DSL like this:")'
// In production code: if ((result === "hello")(after being lowerCased)) true else false // In tests: result should equal ("hello") (after being lowerCased and trimmed)
ScalaUtils 2.0.M6 also includes a few other items, such as Catcher
, an extractor factory;")'
Prettifier
")'
and PrettyMethods
, for defining alternate toString
implementations;")'
and TimesOnInt
, a counting loop moved from org.scalatest
.")'
Back in ScalaTest proper (i.e. not ScalaUtils), ScalaTest 2.0.M6 includes an
Inspectors
trait that allows you to make assertions about (to")'
inspect) collections, including deeply nested collections:
forAll
- succeeds if the assertion holds true for every elementforAtLeast
- succeeds if the assertion holds true for at least the specified number of elementsforAtMost
- succeeds if the assertion holds true for at most the specified number of elementsforBetween
- succeeds if the assertion holds true for between the specified minimum and maximum number of elements, inclusiveforEvery
- same as forAll
, but lists all failing elements if it fails (whereas forAll
just reports the first failing element)forExactly
- succeeds if the assertion holds true for exactly the specified number of elementsWe worked hard to craft error messages that will help you understand what went wrong when an inspection against a nested collection fails. For example, given this nested collection:
val xss = List( List(1, 2, 3), List(1, 2, 3), List(1, 2, 3) )
And this inspection:
forAll (xss) { xs => forAll (xs) { y => y should be < 2 } }
Your error message will be:
TestFailedException: forAll failed, because: at index 0, forAll failed, because: at index 1, 2 was not less than 2 (<console>:20) in List(1, 2, 3) (<console>:20) in List(List(1, 2, 3), List(1, 2, 3), List(1, 2, 3)) at ...
If you are using Matchers
, you can use "inspector shorthands" for inspecting top-level (i.e., non-nested) collections:")'
all
- succeeds if the assertion holds true for every elementatLeast
- succeeds if the assertion holds true for at least the specified number of elementsatMost
- succeeds if the assertion holds true for at most the specified number of elementsbetween
- succeeds if the assertion holds true for between the specified minimum and maximum number of elements, inclusiveevery
- same as forAll
, but lists all failing elements if it fails (whereas forAll
just reports the first failing element)exactly
- succeeds if the assertion holds true for exactly the specified number of elementsHere are some examples:
all (xs) should be > 0 atMost (2, xs) should be >= 4 atLeast (3, xs) should be < 5 between (2, 3, xs) should (be > 1 and be < 5) exactly (2, xs) should be <= 2 every (xs) should be < 10
Speaking of matchers, in ScalaTest 2.0.M6 ShouldMatchers
and MustMatchers
, both members of package org.scalatest.matchers
have been deprecated in favor of Matchers
, which resides in package org.scalatest
. (MustMatchers
was")'")'
actually already deprecated in ScalaTest 1.9.2.) For folks using ShouldMatchers
, getting rid of the deprecation warning should be as simple as replacing org.scalatest.matchers.ShouldMatchers
with org.scalatest.Matchers
. For folks using MustMatchers
, however, it will unfortnately be slightly more trouble, because the new Matchers
trait only supports should
not must
. So you will need to search and replace your uses of must
with should
. MustMatchers
and must
will continue to work for a good long deprecation period, but eventually it will be removed to make way for must
possibly coming back later to serve a different purpose. Apologies for this rather large deprecation.
The contain
matcher syntax has been greatly enhanced in 2.0.M6, in part inspired by similar syntax in specs2. In addition to simple assertions about containership, like:
xs should contain ("hi")
You can also make assertions such as:
xs should contain oneOf (1, 2, 3) xs should contain noneOf (1, 2, 3) xs should contain atLeastOneOf (1, 2, 3) xs should contain allOf (1, 2, 3) xs should contain only (1, 2, 3) xs should contain inOrderOnly (1, 2, 3) xs should contain inOrder (1, 2, 3) xs should contain theSameElementsAs List(1, 2, 3) xs should contain theSameElementsInOrderAs List(1, 2, 3)
In the new contain
syntax, "containership" is determined by Equality
, so you can customize how containership is determined for a
type T
by via an implicit Equality[T]
or the explicitly DSL. Here's an example:
(result should contain oneOf ("hi", "he", "ho")) (after being trimmed)
ScalaTest 2.0.M6 includes a major refactor of how matchers are implemented. Since ScalaTest 1.0 matchers have been implemented primarily with implicit conversions, and as of 2.0.M6 they are mostly implemented with implicit parameters instead. This will make it simpler to enable the syntax on your own types, because you will be able to enable syntax by defining the typeclass "enablers" for that syntax for your own types.
For example, the contain
(<value>)
syntax is enabled for type T
by an implicit
Containing[T]
. ScalaTest 2.0.M6 provides implementations for")'
GenTraversable
, java.util.Collection
, java.util.Map
, Array
, Option
, and String
in
the Containing
companion object. These enable the contain
syntax")'
to be used on more types than in previous versions of ScalaTest, such as strings and options:
Some("hi") should contain ("hi") "hello" should contain ('e')
You can enable the contain (<value>)
syntax for one of your own types, U
, simply by providing an implicit Containing[U]
for that type. The enabling implicit parameter traits are gathered in the org.scalatest.enablers
package.")'
ScalaTest 2.0 matchers enable syntax based on the left-hand type, i.e., the type on which should
is invoked. As a result, many expressions
that resulted in a matcher in ScalaTest 1.x result instead in a matcher factory in ScalaTest 2.0. The factory can produce a matcher given an implicit
enabler. For example, in ScalaTest 1.x, the expression have length 3
produced a Matcher[Any]
that threw an exception if the left-hand
object did not have a length
or getLength
method. In ScalaTest 2.0, it returns a
MatcherFactory1[Any, Length]
:
scala> have length 3 res7: org.scalatest.matchers.MatcherFactory1[Any,org.scalatest.enablers.Length] = have length 3
This matcher factory can produce a matcher for Any
type T
given an implicit Length[T]
. If no Length[T]
is
available for the left-hand type, you'll get a compiler error:
scala> 2.0 should have length 3 <console>:21: error: could not find implicit value for parameter len: org.scalatest.enablers.Length[Double] 2.0 should have length 3 ^
Because the Length
companion object provides an implicit Length[String]
, the compiler will be happy when the type
to the left of should
is a String
:
scala> "2.0" should have length 3
Despite the major reorganization of matchers implementation, existing matchers user code should continue to work fine in all but very rare cases.")'
ScalaTest 2.0.M6 also includes other new matcher syntax, for the most part enabled with implicit parameters, including:
option shouldBe defined partialFunction should be definedAt 8 file should exist otherFile shouldNot exist file shouldBe readable file shouldBe writable "abbccxxx" should startWith regex ("a(b*)(c*)" withGroups ("bb", "cc")) result1 shouldBe a [String] tummy should not be empty list shouldBe sorted val ex = the [ArithmeticException] thrownBy { 1 / 0 } ex should have message "/ by zero" noException should be thrownBy { "hi" } an [ArithmeticException] should be thrownBy { 1 / 0 } the [StringIndexOutOfBoundsException] thrownBy { "hi".charAt(-1) } should have message "String index out of range: -1" javaMap should contain oneOf (Entry(2, 3), Entry(3, 4))
The last example illustrates that you can now use contain
syntax on Java Maps using java.util.Entry
instances. ScalaTest provides an implementation, org.scalatest.Entry
, to make this more convenient.")'
Try
values
ScalaTest 2.0.M6 also includes a LoneElement
trait, that adds a loneElement
method to types with a
“Collecting
” nature")'
classes. The loneElement
method will throw TestFailedException
if the collection on which it
is invoked contains other than a single element. You can use it like this:
set.loneElement should be <= 10
ScalaTest 2.0.M6 also includes a TryValues
trait, that offers syntax that allows you to state that you expect")'
a Try
to be a success or a failure, and something else about the contained value. Here are some examples:
try1.success.value shouldEqual 3 try2.failure.exception shouldBe an [ArithmeticException]
In 2.0.M5, MatchResult
has undergone a")'
backwards-compatible refactor that will both improve runtime performance, enable better
Matcher
composition, and")'
eventually (though not yet in 2.0) allow objects involved in assertion failures to be inspected in IDEs.
Profiling of ScalaTest 1.x tests that used Matchers indicated that a significant amount of time was spent constructing error message
strings for MatchResult
s, even though the vast majority of those strings ultimately where never used in a failure message.
This was especially noticeable when testing with very large collections, because calling toString
on very large collections
creates very large strings, which in turn creates even larger error message strings.
ScalaTest's error messages were created by combining localized "raw" strings with arguments.
For example, for 22 should be < 20
, the raw string would be "{0} was not less than {1}"
and
the arguments Array(22, 21)
.
To eliminate the unnecessary string creations MatchResult
now carries an args
field containing
those arguments along with the raw strings. The actual final strings, such as 22 was not less than 21
, are computed
from the raw strings and args only if and when they are needed.
ScalaTest Matchers, being Function1
s, were always composable via the standard methods in Scala for function composition: compose
and andThen
. For example, in ScalaTest 1.x you could transform a matcher for one type into a matcher for another with compose
.
Here's an example:
scala> import org.scalatest._ import org.scalatest._ scala> import Matchers._ import Matchers._ scala> import java.io.File import java.io.File scala> def endWithExtension(ext: String) = endWith(ext) compose { (f: File) => f.getPath } endWithExtension: (ext: String)org.scalatest.matchers.Matcher[java.io.File] scala> new File("output.txt") should endWithExtension("txt")
In addition, by composing twice, you could in ScalaTest 1.x modify the type of both sides of a match statement with the same function, like this:
scala> val f = be > (_: Int) f: Int => org.scalatest.matchers.Matcher[Int] = <function1> scala> val g = (_: String).toInt g: String => Int = <function1> scala> val beAsIntsGreaterThan = (f compose g) andThen (_ compose g) beAsIntsGreaterThan: String => org.scalatest.matchers.Matcher[String] = <function1> scala> "8" should beAsIntsGreaterThan ("7")
What you could not do in ScalaTest 1.x is modify
the error messages when you performed matcher composition. For example, the error message for the beAsIntsGreaterThan
gives no hint that the Int
s being compared were parsed from String
s:
scala> "7" should beAsIntsGreaterThan ("8") org.scalatest.exceptions.TestFailedException: 7 was not greater than 8
This inability to modify error messages when composing matchers was first brought to my attention in
an offhand tweet by Nat Pryce several years ago. Although no other user ever complained about it, I ultimatedly decided
to address it once MatchResult
s were computing their error messages lazily,
since the original arguments would still be available, waiting patiently to have their toString
called.
I placed the functionality in a trait named MatcherProducers
.")'
Since we needed implicit conversions anyway, I also added a shorthand for composing twice:
scala> import matchers._ import matchers._ scala> import MatcherProducers._ import MatcherProducers._ scala> val beAsIntsGreaterThan = f composeTwice g // means: (f compose g) andThen (_ compose g) beAsIntsGreaterThan: String => org.scalatest.matchers.Matcher[String] = <function1> scala> "8" should beAsIntsGreaterThan ("7")
Of course, the error messages are still the original ones:
scala> "7" should beAsIntsGreaterThan ("8") org.scalatest.exceptions.TestFailedException: 7 was not greater than 8
To modify the error messages, you can use mapResult
from MatcherProducers
. Here's an example:
scala> val beAsIntsGreaterThan = f composeTwice g mapResult { mr => | mr.copy( | failureMessageArgs = mr.failureMessageArgs.map((LazyArg(_) { _.toString + ".toInt"})), | negatedFailureMessageArgs = mr.negatedFailureMessageArgs.map((LazyArg(_) { _.toString + ".toInt"})), | midSentenceFailureMessageArgs = | mr.midSentenceFailureMessageArgs.map((LazyArg(_) { _.toString + ".toInt"})), | midSentenceNegatedFailureMessageArgs = | mr.midSentenceNegatedFailureMessageArgs.map((LazyArg(_) { _.toString + ".toInt"})) | ) | } beAsIntsGreaterThan: String => org.scalatest.matchers.Matcher[String] = <function1>
Now the error message is clearer:
scala> "7" should beAsIntsGreaterThan ("8") org.scalatest.exceptions.TestFailedException: 7.toInt was not greater than 8.toInt
Voila!
Outcome
s and OutcomeOf
One breaking change in 2.0.M6 is that the withFixture
life-cycle methods, and the test functions passed to them, now
return an Outcome
. Because they previously")'
returned Unit
, this will likely require users to insert an =
before the open curly brace, or in some cases,
:Outcome =
. That will most often be all that's required, but if you were catching exceptions in a
withFixture
implementation, you will likely need to change your catch clauses to a corresponding pattern match
on Outcome
types.
Also added OutcomeOf
, deprecating FailureOf
, to transform")'")'
the outcome of evaluating an expression to
an Outcome
. For example, thrown TestFailedException
s are transformed into a")'
Failed
")'
outcome; thrown TestPendingException
s are transformed into a Pending
outcome;")'")'
the lack of a thrown exception is transformed into a Succeeded
outcome.")'
Note: We had to drop support of 2.9 recently because implicit lookup of contravariant type classes did not behave well, and this was required to keep all existing ScalaTest matcher code compiling. If you're on Scala 2.9, please continue with ScalaTest 1.9.2 or ScalaTest 2.0.M5b until the day comes when you can upgrade to Scala 2.10 and ScalaTest 2.0.M6.
Checkpoints
, which allows you to accumulate and report multiple assertions in a single testInforming
, a trait that contains the info
method, which was previously provided via an implicit that has been removed in 2.0.M6Documenting
, a trait that contains the markup
method, which was previously provided via an implicit that has been removed in 2.0.M6Sequential
, a combinator for nested suites that you want executed completely sequentiallyStepwise
, a combinator for nested suites that you want executed one after another, but with parallel execution still enabled for the individual nested suitesTryValues
for making assertions when you expect a Try
to be a Success
ScalaFutures
to help write tests involving Scala futuresorg.scalatest.tags
, added new tags CPU
, Disk
, Network
, and Slow
Like
appended, for speedier compiles. For example: FlatSpecLike
, FunSpecLike
, etc. (Done in ScalaTest 1.9.2 also.)org.scalatest.tools.Framework
.")'
ScopePending
event.BeforeAndAfterEachTestData
and deprecated the beforeEach
and afterEach
")'
methods of trait BeforeAndAfterEach
take take a config map.beforeAll
and afterAll
methods")'
of trait BeforeAndAfterAll
that take a config map.they
(in addition to it
) to FunSpec
and FlatSpec
.toString
to style classes that makes them look prettier in the interpreter.DiscoveryStarting
and DiscoveryCompleted
events.whenCompleted
method to Status
, enabling callbacks to be registered with a Status
.-z
<test name wildcard>
or -t
<test name>
-s
to take a glob in addition to a complete, fully-qualified suite class name.AlertProvided
, Alerting
, and Alerter
(containing the alert
method you can call
from tests) and UpdateProvided
, Updating
, and Updater
(containing the update
method you can call
from tests.AlertProvided
events periodically listing")'
tests that have been running longer than a specified time limit.cancelAfter
method to Timeouts
.Catcher
.Runner
.TestCanceledException
.rerunner
to TestCanceled
.Length
, Size
, Definition
, Emptiness
, Readability
,
and Writability
enablersPrettifier
and PrettyMethods
to org.scalautils
.Retries
.suiteId
to NameInfo
have length
and have size
error messages to include the actual length or size.Matchers
into the org.scalatest.words
package, and moved members
of verbs
package to words
. These were "implementation" classes anyway, so likely no one referred to them in user code,
but just in case, left deprecated type aliases in verbs
.JUnitXmlReporter
to output files based on suiteId
, instead of the fully qualified name of the class.BeforeAndAfterAll
such that it only calls beforeAll
and afterAll
in the outer")'
instance of a OneInstancePerTest
or ParallelTestExecution
.BeforeAndAfterAll
and BeforeAndAfterAllConfigMap
to")'")'
take expectedTestCount
into consideration whether to invoke beforeAll
and afterAll
.Suite.diffStrings
to display brackets only when there is difference in the passed strings.Ordering
instead of Ordered
for be </>/<=/>=
."WrappedArray"
in error messages.withPayloads
to infer and return the same type as the passed in function; changed payload: Any
parameter
to => Any
to be lazy.-h
arguments.JUnitXmlReporter
when it xmlified failure messages.WordSpec
and fixture.WordSpec
's scope")'")'
is used with after word.HTMLReporter
's race condition for suites that mixed in ParallelTestExecution
by ensuring SuiteCompleted
is fired")'")'
after the suite is actually completed.2.0.M5b Highlights:
-h
command of Runner
.
Status
return type to the four “run methods” of trait
Suite
: run
, runNestedSuites
,
runTests
, and runTest
. The Status
can be queried to determine whether all the tests and/or nested suites started by
the “run method” have completed and, if completed, whether any failure occurred. Created four subclasses of this trait for convenience: objects
FailedStatus
and SucceededStatus
, useful when the “run” has already completed (such as when it
was run on the same thread),
class StatefulStatus
, useful when a “run” has not yet completed (such
as when multiple threads are involved), and
CompositeStatus
, useful for composing multiple Status
objects into
one Status
. Status
was added primarily to enable BeforeAndAfterAll
to wait until any parallel events started by invoking
run
complete before executing the “after all” code. This will break any subclass that overrode one of the four run
methods,
but those are also already broken because of the change to the method's arguments. To fix it, you'll need to declare Status
as the return type
of your overloaded method, and return a Status
.
BeforeAndAfterAll
so that it uses the Status
object returned
by run
to wait until any parallel execution
of tests and nested suites has completed before executing the “after all” code.
getSize
method). In its place created Length
and Size
type class traits. This will be a breaking change for
anyone who was relying on those structural implicits. This should affect very little code, but if it hits you, you'll need to create a type class
as described in the Scaladoc for Length
and Size
.
GivenWhenThen
in favor of capitalized forms, Given/When/Then/And, because then
has been deprecated as an identifier in Scala 2.10.
Traversable
to GenTraversable
, Seq
to GenSeq
, etc.,
to make it easier to test with parallel collections. Spec
and
fixture.Spec
to serve as the new style trait
in which tests are methods.Suite
as a style trait.SuiteMixin
to serve as the new base class
for stackable traits that can be mixed into Suite
, and deprecated trait
AbstractSuite
.TimesOnInt
, which allows you to repeatedly
execute a block of code an integer number of times via syntax such as, 3 times println
.Runner
a way to specify tests to run by full or partial ("wildcard")') name.@Ignore
.@DoNotDiscover
annotation that prevents discovery of an otherwise discoverable Suite
class.Suite
's run
method signatures, to make them more pleasant to override.Suite
in favor of
`test: ...`
style.Suite
's execute
method, including treating a given test name as a wildcard.TestData
trait that offers information about a test, some of which was already being
passed into withFixture
. In addition to
the config map and test name, TestData
also offers test text, scopes, and tags. In addition to being mixed into NoArgTest
and OneArgTest
,
which are passed to withFixture
, new forms of beforeEach
and afterEach
were added to BeforeAndafterEach
that take
a TestData
(and the old forms that took only a config map were deprecated). This gives beforeEach
and afterEach
methods to
the same information enjoyed by withFixture
methods.Enhancements in 2.0.M5b:
Spec
and
fixture.Spec
to serve as the new style trait
in which tests are methods.Suite
as a style trait.SuiteMixin
to serve as the new base class
for stackable traits that can be mixed into Suite
, and deprecated trait
AbstractSuite
.TimesOnInt
, which allows you to repeatedly
execute a block of code an integer number of times via syntax such as, 3 times println
.org.scalatest.selenium
package, which provides the ScalaTest Selenium DSL.Args
, to hold the arguments passed
into Suite
's run
, runNestedSuites
, runTests
, and runTest
methods. The purpose of Args
is to simplify the signatures of these four "run")' lifecycle methods, making the signatures easier to remember and the methods more pleasant to override.chosenStyles
to Args
, to hold the (possibly empty) set of styles chosen for the project. Previously this was passed around via the config map.
run
method to AbstractSuite
that takes an optional test name string and a Args
. Deprecated the old (and now overloaded) run
method that takes seven args
and added a final implementation of it to AbstractSuite
that calls the new, two-arg form of run
.runNestedSuites
method so instead of taking six parameters it takes a single
Args
parameter. This will be a breaking change to any subtrait or subclass that overrode or invoked this method. See the breaking changes section for info on how to fix it.runTests
method so instead of taking an optional test name string plus six parameters it takes the optional test name string and
a single Args
parameter. This will be a breaking change to any subtrait or subclass that overrode or invoked this method. See the breaking changes section for info on how to fix it.runTest
method so instead of taking a test name string and six parameters it takes the test name string and a single
Args
parameter. This will be a breaking change to any subtrait or subclass that overrode or invoked this method. See the breaking changes section for info on how to fix it.newInstance
in OneInstancePerTest
and ParallelTestExecution
to include the trait type. I.e., previously the result type of newInstance
was just Suite
. Now in OneInstancePerTest
the result type is Suite with OneInstancePerTest
, and in ParallelTestExecution
is Suite with ParallelTestExecution
.assume
methods to trait Assertions
. For symmetry, each assume
method corresponds to
an overloaded assert
method with an identical signature. The assume
methods behave similarly to the corresponding assert
methods, except instead of throwing TestFailedException
the assume
methods throw TestCanceledException
.cancel
methods to trait Assertions
. For symmetry, each cancel
method corresponds to
an overloaded fail
method with an identical signature. The cancel
methods behave similarly to the corresponding fail
methods, except instead of throwing TestFailedException
the cancel
methods throw TestCanceledException
.TestCanceled
event to indicate a test has been canceled.TestCanceledException
that indicates a test has been canceled. (This is thrown by the cancel
and assume
methods added in this release to trait Assertions
.)ScopeOpened
and ScopeClosed
events to indicate "scopes," such as the scope of a describe
clause in a FunSpec
. Previously a "scope opened" event was indiciated via an InfoProvided
events with IndentedText
.MarkupProvided
event to indicate some markup text has been provided. markup()
method to style traits in which tests are functions (I.e., the same style traits that already offered an info()
method.) to allow markup text to be sent to the reporter from those traits. Added trait Documenter
, the result type of markup
.testText
field to all test events (TestStarting
, TestIgnored
, TestPending
, TestCanceled
, TestFailed
, and TestSucceeded
), primarily for integration with IntelliJ IDEA. The "test text" is either the complete test name or a suffix of it. In a FunSpec
, for example, the test text will be the string passed to the it
method, whereas the full test name will be the test text prefixed by the strings passed to enclosing describe
method calls.Location
, three case subclasses LineInFile
, TopOfMethod
, and TopOfClass
, and singleton object SeeStackDepthException
. (For the time being there's also a ToDoLocation
we're using to mark places that aren't yet firing proper locations, but this will be removed before 2.0.final is released.)location
, an Option[Location]
field, to class Event
.Ordinal
nicer toString
output, for example: "Ordinal(99, 1, 0)"
.excludeNestedSuites
field to the primary constructor of class Filter
. This field supports rerunning selected (such as previously failed) tests.DynaTags
to support the dynamic tagging of tests. The dynamic tagging feature (new in 2.0) can be used, for example, to select a subset of tests to run (such as tests that previously failed), by tagging them with "Selected"
and only including tests tagged "Selected")'
. dynaTags
field to the primary constructor of class Filter
. This field supports the dynamic tagging of tests.suiteId
lifecycle method to trait AbstractSuite
and its subtraits. This new lifecycle method is intended to provide a unique ID for each suite that executes in a suite of tests, so that tests can be dynamically tagged. (A dynamic tag identifies tests by suiteId
and testName
.)suiteId
to relevant events: TestStarting
, TestSucceeded
, TestFailed
, TestFailed
, TestPending
, TestCanceled
, SuiteStarting
, SuiteCompleted
, SuiteAborted
. This enables tests run previously to be dynamically tagged in future runs (because a dynamic tag requires both the testName
and suiteId
).apply
methods on Filter
, and added two new ones that take an additional suiteId
parameter.rerunner
lifecycle method to AbstractSuite
and its subtraits, which provides an optional fully qualified name of a suite (with a public, no-arg constructor) that can be used create to rerun its tests. If class has a public, no-arg constructor, then that class's fully qualified name can be returned from rerunner
. If it does not have a public, no-arg constructor, but rather is created as a nested suite of a class that does have a public, no-arg constructor, then the nested class can return from rerunner
the fully qualified name of that outer, nesting class. To rerun a test in the nested class, ScalaTest can create the nesting class via its public, no-arg constructor, and run it. The nesting class will create the actual class in which the test resides, and run it as a nested suite, thereby rerunning the test.-k
argument to Runner
. decodedTestName
, an Option[String]
, to test-related events. If defined, it means that the test was named using Scala's backtick notation, such as a test method in a Suite
named `test: an empty stack should complain on pop`
. The real test name will be encoded as test$colon$u0020an$u0020empty$u0020stack$u0020should$u0020complain$u0020on$u0020pop
, whereas the decoded name will be test: an empty stack should complain on pop
. This enables test names to be defined with backtick notation and still be presented to users in the more human-friendly, decoded form. If the decoded name would be identical to the encoded name (which will be the case if the name was not expressed in backticks and therefore never encoded in the first place), decodedTestName
will be None
. The events to which decodedTestName
was added are: TestStarting
, TestSucceeded
, TestFailed
, TestIgnored
, TestPending
, TestCanceled
.decodedSuiteName
, an Option[String]
, to suite-related events. If defined, it means that the suite was named using Scala's backtick notation, such as `Stack Spec`
. The real suite name will, by default, be encoded as Stack$u0020Spec
, whereas the decoded name will be Stack Spec
. This enables suite names to be defined with backtick notation and still be presented to users in the more human-friendly, decoded form. If the decoded name would be identical to the encoded name (which will be the case if the name was not expressed in backticks and therefore never encoded in the first place), decodedSuiteName
will be None
. The events to which decodedSuiteName
was added are: TestStarting
, TestSucceeded
, TestFailed
, TestIgnored
, TestPending
, TestCanceled
, SuiteStarting
, SuiteCompleted
, SuiteAborted
.DoNotDiscover
annotation that can be used to tell Runner
not to discover a suite class that it would otherwise discover.Finders
annotation that specifies one or more Finders
that can
be used to determine selected tests from an AST in IDEs.DoNotDiscover
annotation to prevent Suite
classes that would otherwise be discoverable (because they extend Suite
and have a public, no-arg constructor) from being discovered by Runner
.-i
command line argument to Runner
to provide a way to specify a suite by suite ID. This complements the -s
command, which allows you to identify a suite by fully qualified name. The -i
command was added primarily to allow IDEs and other tools to rerun failed (or otherwise selected) tests.-t
to Runner
, a way to specify a specific test name. A -t
clauses must follow -s
or -i
. All -t
's immediately following a -s
or -i
will be considered tests of the suite specified by that -s
or -i
.-z
argument to Runner
, a means to specify test names via a wildcard: any test whose string name includes the string specified with -z
will be selected. -z
clauses must follow -s
or -i
clauses. All -z
's immediately following a -s
or -i
will be considered wildcards selecting tests of the suite by that -s
or -i
. (Note: This approach to wildcard test names was suggested by Mathias Doenitz.)nestedSuites
from List
to immutable.IndexedSeq
. (Under the covers we currently return a Vector
.) When ScalaTest 1.0 was initially released, Vector
did not yet exist in the Scala library and List
was considered by many to be the default Seq
type to use. In practice, it was discovered that it is too easy to use List
(and other LinearSeq
's) in a non-performant way. In 2.0 we wanted to take the opportunity to make the potentially breaking change of replacing List
result types with immutable.IndexedSeq
. This potentially breaking change is expected to affect very little, if any, user code.apply
method to Distributor
that takes a Args
, and deprecated the old form. During the deprecation period, the old form will call the new form with default args. The purpose of this change was to make more information available to Distributor
implementations.recordedEvents
field to test completion events: TestPending
, TestSucceeded
, TestFailed
, and TestCanceled
. Added sealed trait RecordedEvent
, which extends Event
and has two subtraits: InfoProvided
and MarkupProvided
. Prior to 2.0, InfoProvided
events were recorded during tests and played back after, so that they could appear
after the test text in the standard out reporter, and in a color that matched that of the test text. The color of the test text (green if passed, red if failed, yellow
if pending, etc.) could not be known until after the test had completed. By sending recorded events along with the test completion event, rather than playing them
back afterwords, it is easier for Reporters to figure out when the last event for a test has been received. Enhanced filtering so that recorded events would be filtered
out if the user asked for that.Tracker
.tagsToInclude
and tagsToExclude
in Filter
.suiteId
.ParallelTestExecution
, with a timeout if something takes too long. This balances the desire to have sorted output while you are watching with the desire to see stuff happening while you are watching. Added sortingTimeout
to ParallelTestExecution
, the default of which is to use the timeout specified to Runner
via -T (or 15 seconds if no -T given), but you can override the method. Added trait DistributedTestSorter
to support this featuren, and a field holding one in Args
-T
plus one second is used for suite sorting.-PS
argument to Runner
.suiteId
of DiscoverySuite
unique in a run.info()
invocations in fixture.Suite
are recorded and reported in the completion event.OneInstancePerTest
so that it calls super.runTests
which emits events for scopes (such as describe
clauses in FunSpec
).ParallelTestExecution
so that it calls super.runTests
which emits events for scopes (such as describe
clauses in FunSpec
).TestPending
event.apply
factory methods in Filter
to one apply
method with default args.Filter
, in favor of just using the apply
method in the Filter
companion object.org.scalatest
package object for ShouldMatchers
and MustMatchers
to save an import when using matchers.Suite
and deprecated the old-style names.ConfigMapFixture
so that it calls withFixture(test.toNoArgTest(...))
in its withFixture(OneArgTest)
implementation. Previously it was just calling the test function directly. This enhancement enables trait stacking.expectResult
to Assertions
, and deprecated expect
. expect
will be used for a different purpose in a future version of ScalaTest.Runner
.@Ignore
to ignore all tests in the suite.@DoNotDiscover
, @Ignore
, @Style
, @TagAnnotation
, and @WrapWith
), which must be implemented in Java, to appear in ScalaTest's Scaladoc. This was done by pretending they are traits that extend java.lang.annotation.Annotation
, and explaining at the top of the documentation that they are really Java @interface
s.Matchers
in package org.scalatest.matchers
to ClassicMatchers and deprecated Matchers
.
Bug fixes in 2.0.M5b:
JUnitRunner
.should
/can
/must
from WordSpec
and fixture.WordSpec
in the standard out reporter for failed, canceled, and ignored tests.skipped
attribute in the JUnit XML output for ignored, pending, and canceled tests.
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.