From 8dc1b0cddc731b83161f316556ce426f042e8238 Mon Sep 17 00:00:00 2001
From: Chua Chee Seng Selecting testing styles for your project
-The style you choose dictates only how the declarations of your tests will look. Everything else in ScalaTest—assertions, matchers, +The style you choose dictates only how the declarations of your tests will look. Everything else in ScalaTest—assertions, expectations, matchers, mixin traits, etc.—works consistently the same way no matter what style you chose.
@@ -93,6 +93,30 @@libraryDependencies += "org.scalatest" %% "scalatest-funsuite" % "@{latestVersion}" % "test"+ +
If you would like to use expectations
instead of assertions
, you may use the pure style:
+import org.scalatest.funsuite.FunSuite +import org.scalatest.expectations.Expectations._ ++ +
class SetSuite extends FunSuite { +
test("An empty Set should have size 0") { + expect(Set.empty.size == 0) + } +
test("Invoking head on an empty Set should produce NoSuchElementException") { + expectThrows[NoSuchElementException] { + Set.empty.head + } + } +} +
In order to use expectations
you'll need add the following line in sbt build:
+libraryDependencies += "org.scalatest" %% "scalatest-expectations" % "@{latestVersion}" % "test" ++ @@ -103,6 +127,7 @@
import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.expectations.Expectations._+
class SetSpec extends AnyFlatSpec {
"An empty Set" should "have size 0" in { assert(Set.empty.size == 0) @@ -120,6 +145,29 @@The FlatSpec style
libraryDependencies += "org.scalatest" %% "scalatest-flatspec" % "@{latestVersion}" % "test"
If you would like to use expectations
instead of assertions
, you may use the pure style:
+import org.scalatest.flatspec.FlatSpec +import org.scalatest.expectations.Expectations._ ++ +
class SetSpec extends FlatSpec { +
"An empty Set" should "have size 0" in { + expect(Set.empty.size == 0) + } +
it should "produce NoSuchElementException when head is invoked" in { + expectThrows[NoSuchElementException] { + Set.empty.head + } + } +} +
In order to use expectations
you'll need add the following line in sbt build:
+libraryDependencies += "org.scalatest" %% "scalatest-expectations" % "@{latestVersion}" % "test" ++ @@ -154,6 +202,33 @@
If you would like to use expectations
instead of assertions
, you may use the pure style:
+import org.scalatest.funspec.FunSpec +import org.scalatest.expectations.Expectations._ ++ +
class SetSpec extends FunSpec { +
describe("A Set") { + describe("when empty") { + it("should have size 0") { + assert(Set.empty.size == 0) + } +
it("should produce NoSuchElementException when head is invoked") { + assertThrows[NoSuchElementException] { + Set.empty.head + } + } + } + } +} +
In order to use expectations
you'll need add the following line in sbt build:
+libraryDependencies += "org.scalatest" %% "scalatest-expectations" % "@{latestVersion}" % "test" ++ @@ -185,6 +260,34 @@
libraryDependencies += "org.scalatest" %% "scalatest-wordspec" % "@{latestVersion}" % "test"+ +
If you would like to use expectations
instead of assertions
, you may use the pure style:
+import org.scalatest.wordspec.WordSpec +import org.scalatest.expectations.Expectations._ ++ +
class SetSpec extends WordSpec { +
"A Set" when { + "empty" should { + "have size 0" in { + expect(Set.empty.size == 0) + } +
"produce NoSuchElementException when head is invoked" in { + expectThrows[NoSuchElementException] { + Set.empty.head + } + } + } + } +} +
In order to use expectations
you'll need add the following line in sbt build:
+libraryDependencies += "org.scalatest" %% "scalatest-expectations" % "@{latestVersion}" % "test" ++ @@ -216,6 +319,33 @@
If you would like to use expectations
instead of assertions
, you may use the pure style:
+import org.scalatest.freespec.FreeSpec +import org.scalatest.expectations.Expectations._ ++ +
class SetSpec extends FreeSpec { +
"A Set" - { + "when empty" - { + "should have size 0" in { + expect(Set.empty.size == 0) + } +
"should produce NoSuchElementException when head is invoked" in { + expectThrows[NoSuchElementException] { + Set.empty.head + } + } + } + } +} +
In order to use expectations
you'll need add the following line in sbt build:
+libraryDependencies += "org.scalatest" %% "scalatest-expectations" % "@{latestVersion}" % "test" ++ @@ -229,10 +359,11 @@
import org.scalatest._ +import featurespec.AnyFeatureSpec+
class TVSet { private var on: Boolean = false def isOn: Boolean = on @@ -301,12 +433,59 @@The FeatureSpec style
} }
To select just the FeatureSpec
style in an sbt build, include this line:
libraryDependencies += "org.scalatest" %% "scalatest-featurespec" % "@{latestVersion}" % "test"+
If you would like to use expectations
instead of assertions
, you may use the pure style:
+import org.scalatest._ +import featurespec.FeatureSpec +import expectations.Expectations._ ++ +
class TVSet { + private var on: Boolean = false + def isOn: Boolean = on + def pressPowerButton() { + on = !on + } +} +
class TVSetSpec extends FeatureSpec with GivenWhenThen { +
info("As a TV set owner") + info("I want to be able to turn the TV on and off") + info("So I can watch TV when I want") + info("And save energy when I'm not watching TV") +
feature("TV power button") { + scenario("User presses power button when TV is off") { +
Given("a TV set that is switched off") + val tv = new TVSet +
When("the power button is pressed") + tv.pressPowerButton() +
Then("the TV should switch on") + expect(tv.isOn) + } +
scenario("User presses power button when TV is on") { +
Given("a TV set that is switched on") + val tv = new TVSet + tv.pressPowerButton() +
When("the power button is pressed") + tv.pressPowerButton() +
Then("the TV should switch off") + expect(!tv.isOn) + } + } +} +
In order to use expectations
you'll need add the following line in sbt build:
+libraryDependencies += "org.scalatest" %% "scalatest-expectations" % "@{latestVersion}" % "test" ++ @@ -344,6 +523,8 @@
RefSpec
does not support expectations
.
If you would like to use expectations
instead of assertions
, you may use the pure style:
+import org.scalatest._ +import prop._ +import propspec.PropSpec +import org.scalatest.expectations.Expectations._ +import scala.collection.immutable._ ++ +
class SetSpec extends PropSpec with TableDrivenPropertyChecks { +
val examples = + Table[Set[Int]]( + "set", + BitSet.empty, + HashSet.empty[Int], + TreeSet.empty[Int] + ) +
property("an empty Set should have size 0") { + forAll(examples) { set => + expect(set.size == 0) + } + } +
property("invoking head on an empty set should produce NoSuchElementException") { + forAll(examples) { set => + expectThrows[NoSuchElementException] { set.head } + } + } +} +
In order to use expectations
you'll need add the following line in sbt build:
+libraryDependencies += "org.scalatest" %% "scalatest-expectations" % "@{latestVersion}" % "test" ++ From 0475be7b34b92e9df032f96c392082e05f8ebe75 Mon Sep 17 00:00:00 2001 From: Chua Chee Seng
-You may also refer to Property-based testing for detailed usage documentation. +You may also refer to Property-based testing using ScalaCheck for detailed usage documentation.
diff --git a/app/views/userGuide/generatorDrivenPropertyChecks.scala.html b/app/views/userGuide/generatorDrivenPropertyChecks.scala.html index 0fcdfdeb16..639aeea145 100644 --- a/app/views/userGuide/generatorDrivenPropertyChecks.scala.html +++ b/app/views/userGuide/generatorDrivenPropertyChecks.scala.html @@ -22,25 +22,23 @@
-To use generator-driven property checks, you must mix in trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
- (previously known as org.scalatest.props.PropertyChecks
). If you are also using table-driven property checks, you can mix in
-trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
,
-which extends both ScalaCheckDrivenPropertyChecks
and
+To use generator-driven property checks, you must mix in trait org.scalatest.prop.GeneratorDrivenPropertyChecks
.
+If you are also using table-driven property checks, you can mix in
+trait org.scalatestplus.prop.PropertyChecks
,
+which extends both GeneratorDrivenPropertyChecks
and
TableDrivenPropertyChecks
.
-Generator-driven property checks uses ScalaCheck and
-ScalaTest + ScalaCheck, so you must also include both jars on your classpath when
-you compile and run your tests.
+Starting ScalaTest 3.3 release, generator-driven property checks uses ScalaTest generators.
-Trait ScalaCheckDrivenPropertyChecks
contains forAll
methods that provide various ways to check properties using
+Trait GeneratorDrivenPropertyChecks
contains forAll
methods that provide various ways to check properties using
generated data.
It also contains a wherever
method that can be used to indicate a property need only hold whenever
some condition is true.
-For an example of trait ScalaCheckDrivenPropertyChecks
in action, imagine you want to test this Fraction
class:
+For an example of trait GeneratorDrivenPropertyChecks
in action, imagine you want to test this Fraction
class:
@@ -55,7 +53,7 @@Generator-driven property checks
-To test the behavior of Fraction
, you could mix in or import the members of ScalaCheckDrivenPropertyChecks
+To test the behavior of Fraction
, you could mix in or import the members of GeneratorDrivenPropertyChecks
(and should.Matchers
) and check a property using a forAll
method, like this:
-Trait ScalaCheckDrivenPropertyChecks
provides overloaded forAll
methods
-that allow you to check properties using the data provided by a ScalaCheck generator. The simplest form
+Trait GeneratorDrivenPropertyChecks
provides overloaded forAll
methods
+that allow you to check properties using the data provided by a ScalaTest generator. The simplest form
of forAll
method takes two parameter lists, the second of which is implicit. The first parameter list
-is a "property" function with one to six parameters. An implicit Arbitrary
generator and Shrink
object needs to be supplied for
+is a "property" function with one to six parameters. An implicit PropertyCheckConfiguration
, one to six org.scalatest.prop.Generator
, org.scalatest.enablers.PropCheckerAsserting
, org.scalactic.Prettifier
and org.scalactic.source.Position
object needs to be supplied for
The forAll
method will pass each row of data to
-each parameter type. ScalaCheck provides many implicit Arbitrary
generators for common types such as
-Int
, String
, List[Float]
, etc., in its org.scalacheck.Arbitrary
companion
-object. So long as you use types for which ScalaCheck already provides implicit Arbitrary
generators, you needn't
-worry about them. Same for Shrink
objects, which are provided by ScalaCheck's org.scalacheck.Shrink
companion
-object. Most often you can simply pass a property function to forAll
, and the compiler will grab the implicit
-values provided by ScalaCheck.
+each parameter type. ScalaTest provides many implicit org.scalatest.prop.Generator
generators for common types such as
+Int
, String
, List[Float]
, PosInt
etc., in its org.scalatest.prop.CommonGenerators
companion
+object. So long as you use types for which ScalaTest generators already provides implicit org.scalatest.prop.Generator
, you needn't
+worry about them. Most often you can simply pass a property function to forAll
, and the compiler will grab the implicit
+values provided by ScalaTest.
-The forAll
methods use the supplied Arbitrary
generators to generate example
+The forAll
methods use the supplied org.scalatest.prop.Generator
s to generate example
arguments and pass them to the property function, and
generate a GeneratorDrivenPropertyCheckFailedException
if the function
completes abruptly for any exception that would normally cause a test to
@@ -152,7 +149,7 @@
-ScalaCheck provides a nice library of compositors that makes it easy to create your own custom generators. If you
+ScalaTest provides a nice library of compositors that makes it easy to create your own custom generators. If you
want to supply custom generators to a property check, place them in parentheses after forAll
, before
the property check function (a curried form of forAll
).
-import org.scalacheck.Gen -
val evenInts = for (n <- Gen.choose(-1000, 1000)) yield 2 * n +import org.scalatest.prop.CommonGenerators +
val evenInts = for (n <- CommonGenerators.between(-1000, 1000)) yield 2 * n
@@ -175,7 +172,7 @@
-Custom generators are necessary when you want to pass data types not supported by ScalaCheck's arbitrary generators,
+Custom generators are necessary when you want to pass data types not supported by ScalaTest's generators,
but are also useful when some of the values in the full range for the passed types are not valid. For such values you
would use a whenever
clause. In the Fraction
class shown above, neither the passed numerator or
denominator can be Integer.MIN_VALUE
, and the passed denominator cannot be zero. This shows up in the
@@ -193,7 +190,7 @@
val validNumers = - for (n <- Gen.choose(Integer.MIN_VALUE + 1, Integer.MAX_VALUE)) yield n + for (n <- CommonGenerators.between(Integer.MIN_VALUE + 1, Integer.MAX_VALUE)) yield n val validDenoms = for (d <- validNumers if d != 0) yield d@@ -220,8 +217,8 @@
Note that even if you are use generators that don't produce the invalid values, you still need the
-whenever
clause. The reason is that once a property fails, ScalaCheck will try and shrink
-the values to the smallest values that still cause the property to fail. During this shrinking process ScalaCheck
+whenever
clause. The reason is that once a property fails, ScalaTest will try and shrink
+the values to the smallest values that still cause the property to fail. During this shrinking process ScalaTest
may pass invalid values. The whenever
clause is still needed to guard against those values. (The
whenever
clause also clarifies to readers of the code exactly what the property is in a succinct
way, without requiring that they find and understand the generator definitions.)
@@ -294,13 +291,13 @@
-forAll (minSuccessful(500), maxDiscarded(300)) { (n: Int, d: Int) => ... +forAll (minSuccessful(500), maxDiscardedFactor(2.5)) { (n: Int, d: Int) => ...
@@ -391,13 +388,13 @@
// If providing argument names -forAll ("n", "d", minSuccessful(500), maxDiscarded(300)) { +forAll ("n", "d", minSuccessful(500), maxDiscardedFactor(2.5)) { (n: Int, d: Int) => ...diff --git a/app/views/userGuide/propertyBasedTesting.scala.html b/app/views/userGuide/propertyBasedTesting.scala.html index add61e2ed2..ff8fcba7e2 100644 --- a/app/views/userGuide/propertyBasedTesting.scala.html +++ b/app/views/userGuide/propertyBasedTesting.scala.html @@ -37,34 +37,17 @@
// If providing generators -forAll (validNumers, validDenoms, minSuccessful(500), maxDiscarded(300)) { +forAll (validNumers, validDenoms, minSuccessful(500), maxDiscardedFactor(2.5)) { (n: Int, d: Int) => ...
// If providing (<generators>, <name>) pairs -forAll ((validNumers, "n"), (validDenoms, "d"), minSuccessful(500), maxDiscarded(300)) { +forAll ((validNumers, "n"), (validDenoms, "d"), minSuccessful(500), maxDiscardedFactor(2.5)) { (n: Int, d: Int) => ...
In ScalaTest, properties are specified as functions and the data points used to check properties can be supplied by either tables -or generators. Generator-driven property checks are performed via integration with ScalaCheck through -ScalaTest + ScalaCheck library, by including: +or generators. Starting from ScalaTest 3.3, generator-driven property checks are performed via ScalaTest generators. +If you are using ScalaCheck, you may want to refer to ScalaCheck-driven property checks.
--libraryDependencies += "org.scalatestplus" %% "scalacheck-@{latestScalaCheckVersion}" % "@{latestScalaCheckPlusVersion}" % "test" -- -
-in your SBT file, or if you use Maven: -
- --<dependency> - <groupId>org.scalatestplus</groupId> - <artifactId>scalacheck-@{latestScalaCheckVersion}_2.13</artifactId> - <version>@latestScalaCheckPlusVersion</version> - <scope>test</scope> -</dependency> --
-To use this style of testing, mix in trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
(previously known as org.scalatest.props.PropertyChecks
, deprecated in 3.0.6), or import the
+To use this style of testing, mix in trait org.scalatest.prop.PropertyChecks
, or import the
members of its companion object.
-As an example property-based testing using both table- and generator-driven properties, imagine you want to test this Fraction
class:
+As an example property-based testing using both table and generator-driven properties, imagine you want to test this Fraction
class:
@@ -79,7 +62,7 @@Property-based testing
-If you mix in ScalaCheckPropertyChecks
, you could use a generator-driven property check to test that the passed values for numerator and
+If you mix in PropertyChecks
, you could use a generator-driven property check to test that the passed values for numerator and
denominator are properly normalized, like this:
n
and d
. (This property specifies how the numerator and denominator passed to the Fraction
constructor should be normalized.) The whenever
clause indicates invalid
values for n
and d
.
-Any other values are valid. When run, ScalaCheck generators will be passed implicitly to forAll
and supply integer values for
-n
and d
. By default the property will be checked against 10 valid pairs of n
and d
. Note that this is different from ScalaCheck's default of 100.
+Any other values are valid. When run, ScalaTest generators will be passed implicitly to forAll
and supply integer values for
+n
and d
. By default the property will be checked against 10 valid pairs of n
and d
.
@@ -166,7 +149,6 @@
diff --git a/app/views/userGuide/scalacheckDrivenPropertyChecks.scala.html b/app/views/userGuide/scalacheckDrivenPropertyChecks.scala.html new file mode 100644 index 0000000000..13ec3dff6a --- /dev/null +++ b/app/views/userGuide/scalacheckDrivenPropertyChecks.scala.html @@ -0,0 +1,414 @@ +@* +* Copyright 2010-2017 Artima, Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*@ + +@import controllers.Application.scaladocsPageUrl + +@userGuidePage("Generator-driven property checks") { +
+ To use generator-driven property checks, you must mix in trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
+ (previously known as org.scalatest.props.PropertyChecks
). If you are also using table-driven property checks, you can mix in
+ trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
,
+ which extends both ScalaCheckDrivenPropertyChecks
and
+ TableDrivenPropertyChecks
.
+ Generator-driven property checks uses ScalaCheck and
+ ScalaTest + ScalaCheck, so you must also include both jars on your classpath when
+ you compile and run your tests.
+
+ Trait ScalaCheckDrivenPropertyChecks
contains forAll
methods that provide various ways to check properties using
+ generated data.
+ It also contains a wherever
method that can be used to indicate a property need only hold whenever
+ some condition is true.
+
+ For an example of trait ScalaCheckDrivenPropertyChecks
in action, imagine you want to test this Fraction
class:
+
+class Fraction(n: Int, d: Int) { ++ +
require(d != 0) + require(d != Integer.MIN_VALUE) + require(n != Integer.MIN_VALUE) +
val numer = if (d < 0) -1 * n else n + val denom = d.abs +
override def toString = numer + " / " + denom +} +
+ To test the behavior of Fraction
, you could mix in or import the members of ScalaCheckDrivenPropertyChecks
+ (and should.Matchers
) and check a property using a forAll
method, like this:
+
+forAll { (n: Int, d: Int) => ++ +
whenever (d != 0 && d != Integer.MIN_VALUE + && n != Integer.MIN_VALUE) { +
val f = new Fraction(n, d) +
if (n < 0 && d < 0 || n > 0 && d > 0) + f.numer should be > 0 + else if (n != 0) + f.numer should be < 0 + else + f.numer should be === 0 +
f.denom should be > 0 + } +} +
+ Trait ScalaCheckDrivenPropertyChecks
provides overloaded forAll
methods
+ that allow you to check properties using the data provided by a ScalaCheck generator. The simplest form
+ of forAll
method takes two parameter lists, the second of which is implicit. The first parameter list
+ is a "property" function with one to six parameters. An implicit Arbitrary
generator and Shrink
object needs to be supplied for
+ The forAll
method will pass each row of data to
+ each parameter type. ScalaCheck provides many implicit Arbitrary
generators for common types such as
+ Int
, String
, List[Float]
, etc., in its org.scalacheck.Arbitrary
companion
+ object. So long as you use types for which ScalaCheck already provides implicit Arbitrary
generators, you needn't
+ worry about them. Same for Shrink
objects, which are provided by ScalaCheck's org.scalacheck.Shrink
companion
+ object. Most often you can simply pass a property function to forAll
, and the compiler will grab the implicit
+ values provided by ScalaCheck.
+
+ The forAll
methods use the supplied Arbitrary
generators to generate example
+ arguments and pass them to the property function, and
+ generate a GeneratorDrivenPropertyCheckFailedException
if the function
+ completes abruptly for any exception that would normally cause a test to
+ fail in ScalaTest other than DiscardedEvaluationException
. An
+ DiscardedEvaluationException
,
+ which is thrown by the whenever
method (defined in trait Whenever
, which this trait extends) to indicate
+ a condition required by the property function is not met by a row
+ of passed data, will simply cause forAll
to discard that row of data.
+
+ You can optionally specify string names for the arguments passed to a property function, which will be used
+ in any error message when describing the argument values that caused the failure. To supply the names, place them in a comma separated list
+ in parentheses after forAll
before the property function (a curried form of forAll
). Here's
+ an example:
+
+forAll ("a", "b") { (a: String, b: String) => + a.length + b.length should equal ((a + b).length + 1) // Should fail +} ++ +
+ When this fails, you'll see an error message that includes this: +
+ ++Occurred when passed generated values ( + a = "", + b = "" +) ++ +
+ When you don't supply argument names, the error message will say arg0
, arg1
, etc..
+ For example, this property check:
+
+forAll { (a: String, b: String) => + a.length + b.length should equal ((a + b).length + 1) // Should fail +} ++ +
+ Will fail with an error message that includes: +
+ ++Occurred when passed generated values ( + arg0 = "", + arg1 = "" +) ++ +
+ ScalaCheck provides a nice library of compositors that makes it easy to create your own custom generators. If you
+ want to supply custom generators to a property check, place them in parentheses after forAll
, before
+ the property check function (a curried form of forAll
).
+
+ For example, to create a generator of even integers between (and including) -2000 and 2000, you could write this: +
+ ++import org.scalacheck.Gen ++ +
val evenInts = for (n <- Gen.choose(-1000, 1000)) yield 2 * n +
+ Given this generator, you could use it on a property check like this: +
+ ++forAll (evenInts) { (n) => n % 2 should equal (0) } ++ +
+ Custom generators are necessary when you want to pass data types not supported by ScalaCheck's arbitrary generators,
+ but are also useful when some of the values in the full range for the passed types are not valid. For such values you
+ would use a whenever
clause. In the Fraction
class shown above, neither the passed numerator or
+ denominator can be Integer.MIN_VALUE
, and the passed denominator cannot be zero. This shows up in the
+ whenever
clause like this:
+
+whenever (d != 0 && d != Integer.MIN_VALUE
+ && n != Integer.MIN_VALUE) { ...
+
+
+ + You could in addition define generators for the numerator and denominator that only produce valid values, like this: +
+ ++val validNumers = + for (n <- Gen.choose(Integer.MIN_VALUE + 1, Integer.MAX_VALUE)) yield n +val validDenoms = + for (d <- validNumers if d != 0) yield d ++ +
+ You could then use them in the property check like this: +
+ ++forAll (validNumers, validDenoms) { (n: Int, d: Int) => ++ +
whenever (d != 0 && d != Integer.MIN_VALUE + && n != Integer.MIN_VALUE) { +
val f = new Fraction(n, d) +
if (n < 0 && d < 0 || n > 0 && d > 0) + f.numer should be > 0 + else if (n != 0) + f.numer should be < 0 + else + f.numer should be === 0 +
f.denom should be > 0 + } +} +
+ Note that even if you are use generators that don't produce the invalid values, you still need the
+ whenever
clause. The reason is that once a property fails, ScalaCheck will try and shrink
+ the values to the smallest values that still cause the property to fail. During this shrinking process ScalaCheck
+ may pass invalid values. The whenever
clause is still needed to guard against those values. (The
+ whenever
clause also clarifies to readers of the code exactly what the property is in a succinct
+ way, without requiring that they find and understand the generator definitions.)
+
+ If you want to supply both generators and named arguments, you can do so by providing a list of (<generator>, <name>)
pairs
+ in parentheses after forAll
, before the property function. Here's an example:
+
+forAll ((validNumers, "n"), (validDenoms, "d")) { (n: Int, d: Int) => ++ +
whenever (d != 0 && d != Integer.MIN_VALUE + && n != Integer.MIN_VALUE) { +
val f = new Fraction(n, d) +
if (n < 0 && d < 0 || n > 0 && d > 0) + f.numer should be > 0 + else if (n != 0) + f.numer should be < 0 + else + f.numer should be === 0 +
f.denom should be > 0 + } +} +
+ Were this property check to fail, it would mention the names n and d in the error message, like this: +
+ ++Occurred when passed generated values ( + n = 17, + d = 21 +) ++ +
+ The property checks performed by the forAll
methods of this trait can be flexibly configured via the services
+ provided by supertrait Configuration
. The five configuration parameters for property checks along with their
+ default values and meanings are described in the following table:
+
+ Configuration Parameter + | ++ Default Value + | ++ Meaning + | +
---|---|---|
+ minSuccessful + | ++ 10 + | ++ the minimum number of successful property evaluations required for the property to pass (Note that this is different from ScalaCheck's default of 100.) + | +
+ maxDiscardedFactor + | ++ 5.0 + | ++ the factor of discarded property evaluations allowed during property evaluation. + | +
+ minSize + | ++ 0 + | ++ the minimum size parameter to provide to ScalaCheck, which it will use when generating objects for which size matters (such as strings or lists) + | +
+ maxSize + | ++ 100 + | ++ the maximum size parameter to provide to ScalaCheck, which it will use when generating objects for which size matters (such as strings or lists) + | +
+ workers + | ++ 1 + | ++ specifies the number of worker threads to use during property evaluation + | +
+ The forAll
methods of trait GeneratorDrivenPropertyChecks
each take a PropertyCheckConfiguration
+ object as an implicit parameter. This object provides values for each of the five configuration parameters. Trait Configuration
+ provides an implicit val
named generatorDrivenConfig
with each configuration parameter set to its default value.
+ If you want to set one or more configuration parameters to a different value for all property checks in a suite you can override this
+ val (or hide it, for example, if you are importing the members of the GeneratorDrivenPropertyChecks
companion object rather
+ than mixing in the trait.) For example, if
+ you want all parameters at their defaults except for minSize
and maxSize
, you can override
+ generatorDrivenConfig
, like this:
+
+
+implicit override val generatorDrivenConfig = + PropertyCheckConfiguration(minSize = 10, maxSize = 20) ++ +
+ Or, if hide it by declaring a variable of the same name in whatever scope you want the changed values to be in effect: +
+ ++implicit val generatorDrivenConfig = + PropertyCheckConfiguration(minSize = 10, maxSize = 20) ++ +
+ In addition to taking a PropertyCheckConfiguration
object as an implicit parameter, the forAll
methods of trait
+ GeneratorDrivenPropertyChecks
also take a variable length argument list of PropertyCheckConfigParam
+ objects that you can use to override the values provided by the implicit PropertyCheckConfiguration
for a single forAll
+ invocation. For example, if you want to set minSuccessful
to 500 for just one particular forAll
invocation,
+ you can do so like this:
+
+forAll (minSuccessful(500)) { (n: Int, d: Int) => ... ++ +
+ This invocation of forAll
will use 500 for minSuccessful
and whatever values are specified by the
+ implicitly passed PropertyCheckConfiguration
object for the other configuration parameters.
+ If you want to set multiple configuration parameters in this way, just list them separated by commas:
+
+forAll (minSuccessful(500), maxDiscardedFactor(30)) { (n: Int, d: Int) => ... ++ +
+ If you are using an overloaded form of forAll
that already takes an initial parameter list, just
+ add the configuration parameters after the list of generators, names, or generator/name pairs, as in:
+
+// If providing argument names +forAll ("n", "d", minSuccessful(500), maxDiscardedFactor(30)) { + (n: Int, d: Int) => ... ++ +
// If providing generators +forAll (validNumers, validDenoms, minSuccessful(500), maxDiscardedFactor(30)) { + (n: Int, d: Int) => ... +
// If providing (<generators>, <name>) pairs +forAll ((validNumers, "n"), (validDenoms, "d"), minSuccessful(500), maxDiscardedFactor(30)) { + (n: Int, d: Int) => ... +
+ For more information, see the documentation for trait Configuration
,
+ a supertrait of GeneratorDrivenPropertyChecks
.
+
+ Next, learn about ScalaTest's philosophy and design. +
+ ++ ScalaTest supports property-based testing, where + a property is a high-level specification of behavior that should hold for a range of data points. For example, a property might + state that the size of a list returned from a method should always be greater than or equal to the size of the list passed to + that method. This property should hold no matter what list is passed. +
+ ++ The difference between a traditional test and a property is that tests traditionally verify behavior based on specific data points checked + by the test. A test might pass three or four specific lists of different sizes to a method under test that takes a list, for example, and check the results + are as expected. A property, by contrast, would describe at a high level the preconditions of the method under test and specify some aspect of the + result that should hold no matter what valid list is passed. +
+ ++ In ScalaTest, properties are specified as functions and the data points used to check properties can be supplied by either tables + or generators. Generator-driven property checks are performed via integration with ScalaCheck through + ScalaTest + ScalaCheck library, by including: +
+ ++libraryDependencies += "org.scalatestplus" %% "scalacheck-@{latestScalaCheckVersion}" % "@{latestScalaCheckPlusVersion}" % "test" ++ +
+ in your SBT file, or if you use Maven: +
+ ++<dependency> + <groupId>org.scalatestplus</groupId> + <artifactId>scalacheck-@{latestScalaCheckVersion}_2.13</artifactId> + <version>@latestScalaCheckPlusVersion</version> + <scope>test</scope> +</dependency> ++ +
+ To use this style of testing, mix in trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
(previously known as org.scalatest.props.PropertyChecks
, deprecated in 3.0.6), or import the
+ members of its companion object.
+
+ As an example property-based testing using both table- and generator-driven properties, imagine you want to test this Fraction
class:
+
+class Fraction(n: Int, d: Int) { ++ +
require(d != 0) + require(d != Integer.MIN_VALUE) + require(n != Integer.MIN_VALUE) +
val numer = if (d < 0) -1 * n else n + val denom = d.abs +
override def toString = numer + " / " + denom +} +
+ If you mix in ScalaCheckPropertyChecks
, you could use a generator-driven property check to test that the passed values for numerator and
+ denominator are properly normalized, like this:
+
+forAll { (n: Int, d: Int) => ++ +
whenever (d != 0 && d != Integer.MIN_VALUE + && n != Integer.MIN_VALUE) { +
val f = new Fraction(n, d) +
if (n < 0 && d < 0 || n > 0 && d > 0) + f.numer should be > 0 + else if (n != 0) + f.numer should be < 0 + else + f.numer should be === 0 +
f.denom should be > 0 + } +} +
+ The forAll
method takes a function that expresses a property of Fraction
that should hold for any valid values
+ passed as n
and d
. (This property specifies how the numerator and denominator passed to the Fraction
+ constructor should be normalized.) The whenever
clause indicates invalid
+ values for n
and d
.
+ Any other values are valid. When run, ScalaCheck generators will be passed implicitly to forAll
and supply integer values for
+ n
and d
. By default the property will be checked against 10 valid pairs of n
and d
. Note that this is different from ScalaCheck's default of 100.
+
+ You might place the previous property check in its own test whose name describes the property at a high level, such as
+ "Fractions should be normalized"
.
+ In another test you might use a table-driven property check to test that all combinations of invalid values passed to the Fraction
constructor
+ produce the expected IllegalArgumentException
, like this:
+
+val invalidCombos = + Table( + ("n", "d"), + (Integer.MIN_VALUE, Integer.MIN_VALUE), + (1, Integer.MIN_VALUE), + (Integer.MIN_VALUE, 1), + (Integer.MIN_VALUE, 0), + (1, 0) + ) ++ +
forAll (invalidCombos) { (n: Int, d: Int) => + evaluating { + new Fraction(n, d) + } should produce [IllegalArgumentException] +} +
+ In this example, invalidCombos
is a table of two columns, produced by the Table
factory method, which takes
+ a comma-separated list of tuples. The first tuple contains the headings (the names of the columns, "n"
and "d"
). The remaining
+ tuples represent the rows of data. In this example, each row is one example of how invalid data that could be passed to the Fraction
+ constructor.
+
+ After the declaration of the table, forAll
is invoked. This forAll
method takes the table, invalidCombos
, and
+ a property. forAll
checks to make sure the property holds for each row of the table.
+
+ When you get a failed property check, ScalaTest will report the failure with initial seed so that you can reproduce the failure. You'll need to pass the initial seed value through -S
argument,
+ here's an example you pass it through build.sbt:
+
+testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-S", "123456789") ++ + or if you are using testOnly you can do: + +
+sbt> testOnly MyTest -- -S 123456879 ++ +
+ For more information check out the user guide pages for: +
+ ++ Next, learn about Asynchronous testing. +
+ +
+ To use table-driven property checks, you must mix in trait TableDrivenPropertyChecks
(or import the
+ members of its companion object). If you are also using ScalaCheck generator-driven property checks, you can mix in
+ trait ScalaCheckPropertyChecks
,
+ which extends both TableDrivenPropertyChecks
and ScalaCheckDrivenPropertyChecks
.
+
+ Trait TableDrivenPropertyChecks
contains one forAll
method for each TableForN
+ class, TableFor1
+ through TableFor22
, which allow properties to be checked against the
+ rows of a table. It also contains a wherever
method that can be used to indicate a property need only hold whenever some
+ condition is true.
+
+ For an example of trait TableDrivenPropertyChecks
in action, imagine you want to test this Fraction
class:
+
+class Fraction(n: Int, d: Int) { ++ +
require(d != 0) + require(d != Integer.MIN_VALUE) + require(n != Integer.MIN_VALUE) +
val numer = if (d < 0) -1 * n else n + val denom = d.abs +
override def toString = numer + " / " + denom +} +
+ TableDrivenPropertyChecks
allows you to create tables with
+ between 1 and 22 columns and any number of rows. You create a table by passing
+ tuples to one of the factory methods of object Table
. Each tuple must have the
+ same arity (number of members). The first tuple you pass must all be strings, because
+ it define names for the columns. Subsequent tuples define the data. After the initial tuple
+ that contains string column names, all tuples must have the same type. For example,
+ if the first tuple after the column names contains two Int
s, all subsequent
+ tuples must contain two Int
(i.e., have type
+ Tuple2[Int, Int]
).
+
+ To test the behavior of Fraction
, you could create a table
+ of numerators and denominators to pass to the constructor of the
+ Fraction
class using one of the apply
factory methods declared
+ in Table
, like this:
+
+import org.scalatest.prop.TableDrivenPropertyChecks._ ++ +
val fractions = + Table( + ("n", "d"), // First tuple defines column names + ( 1, 2), // Subsequent tuples define the data + ( -1, 2), + ( 1, -2), + ( -1, -2), + ( 3, 1), + ( -3, 1), + ( -3, 0), + ( 3, -1), + ( 3, Integer.MIN_VALUE), + (Integer.MIN_VALUE, 3), + ( -3, -1) + ) +
+ You could then check a property against each row of the table using a forAll
method, like this:
+
+import org.scalatest.matchers.should.Matchers._ ++ +
forAll (fractions) { (n: Int, d: Int) => +
whenever (d != 0 && d != Integer.MIN_VALUE + && n != Integer.MIN_VALUE) { +
val f = new Fraction(n, d) +
if (n < 0 && d < 0 || n > 0 && d > 0) + f.numer should be > 0 + else if (n != 0) + f.numer should be < 0 + else + f.numer should be === 0 +
f.denom should be > 0 + } +} +
+ Trait TableDrivenPropertyChecks
provides 22 overloaded forAll
methods
+ that allow you to check properties using the data provided by a table. Each forAll
+ method takes two parameter lists. The first parameter list is a table. The second parameter list
+ is a function whose argument types and number matches that of the tuples in the table. For
+ example, if the tuples in the table supplied to forAll
each contain an
+ Int
, a String
, and a List[Char]
, then the function supplied
+ to forAll
must take 3 parameters, an Int
, a String
,
+ and a List[Char]
. The forAll
method will pass each row of data to
+ the function, and generate a TableDrivenPropertyCheckFailedException
if the function
+ completes abruptly for any row of data with any exception that would normally cause a test to
+ fail in ScalaTest other than DiscardedEvaluationException
. An
+ DiscardedEvaluationException
,
+ which is thrown by the whenever
method (also defined in this trait) to indicate
+ a condition required by the property function is not met by a row
+ of passed data, will simply cause forAll
to skip that row of data.
+
+ One way to use a table with one column is to test subsequent return values
+ of a stateful function. Imagine, for example, you had an object named FiboGen
+ whose next
method returned the next fibonacci number, where next
+ means the next number in the series following the number previously returned by next
.
+ So the first time next
was called, it would return 0. The next time it was called
+ it would return 1. Then 1. Then 2. Then 3, and so on. FiboGen
would need to
+ maintain state, because it has to remember where it is in the series. In such a situation,
+ you could create a TableFor1
(a table with one column, which you could alternatively
+ think of as one row), in which each row represents
+ the next value you expect.
+
+val first14FiboNums = + Table("n", 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233) ++ +
+ Then in your forAll
simply call the function and compare it with the
+ expected return value, like this:
+
+forAll (first14FiboNums) { n => + FiboGen.next should equal (n) +} ++ +
+ If you need to test a mutable object, one way you can use tables is to specify
+ state transitions in a table. For example, imagine you wanted to test this mutable
+ Counter
class:
+
+
+class Counter { + private var c = 0 + def reset() { c = 0 } + def click() { c += 1 } + def enter(n: Int) { c = n } + def count = c +} ++ +
+ A Counter
keeps track of how many times its click
method
+ is called. The count starts out at zero and increments with each click
+ invocation. You can also set the count to a specific value by calling enter
+ and passing the value in. And the reset
method returns the count back to
+ zero. You could define the actions that initiate state transitions with case classes, like this:
+
+abstract class Action +case object Start extends Action +case object Click extends Action +case class Enter(n: Int) extends Action ++ +
+ Given these actions, you could define a state-transition table like this: +
+ ++val stateTransitions = + Table( + ("action", "expectedCount"), + (Start, 0), + (Click, 1), + (Click, 2), + (Click, 3), + (Enter(5), 5), + (Click, 6), + (Enter(1), 1), + (Click, 2), + (Click, 3) + ) ++ +
+ To use this in a test, simply do a pattern match inside the function you pass
+ to forAll
. Make a pattern for each action, and have the body perform that
+ action when there's a match. Then check that the actual value equals the expected value:
+
+val counter = new Counter +forAll (stateTransitions) { (action, expectedCount) => + action match { + case Start => counter.reset() + case Click => counter.click() + case Enter(n) => counter.enter(n) + } + counter.count should equal (expectedCount) +} ++ +
+ A table-driven property check can also be helpful to ensure that the proper exception is thrown when invalid data is
+ passed to a method or constructor. For example, the Fraction
constructor shown above should throw IllegalArgumentException
+ if Integer.MIN_VALUE
is passed for either the numerator or denominator, or zero is passed for the denominator. This yields the
+ following five combinations of invalid data:
+
n | d |
---|---|
Integer.MIN_VALUE | Integer.MIN_VALUE |
a valid value | Integer.MIN_VALUE |
Integer.MIN_VALUE | a valid value |
Integer.MIN_VALUE | zero |
a valid value | zero |
+ You can express these combinations in a table: +
+ ++val invalidCombos = + Table( + ("n", "d"), + (Integer.MIN_VALUE, Integer.MIN_VALUE), + (1, Integer.MIN_VALUE), + (Integer.MIN_VALUE, 1), + (Integer.MIN_VALUE, 0), + (1, 0) + ) ++ +
+ Given this table, you could check that all invalid combinations produce IllegalArgumentException
, like this:
+
+forAll (invalidCombos) { (n: Int, d: Int) => + an [IllegalArgumentException] should be thrownBy { + new Fraction(n, d) + } +} ++ +
+ Next, learn about generator-driven property checks. +
+ +
To use table-driven property checks, you must mix in trait TableDrivenPropertyChecks
(or import the
-members of its companion object). If you are also using ScalaCheck generator-driven property checks, you can mix in
-trait ScalaCheckPropertyChecks
,
-which extends both TableDrivenPropertyChecks
and ScalaCheckDrivenPropertyChecks
.
+members of its companion object). If you are also using ScalaTest generator-driven property checks, you can mix in
+trait PropertyChecks
,
+which extends both TableDrivenPropertyChecks
and GeneratorDrivenPropertyChecks
.
diff --git a/conf/routes b/conf/routes
index b3a1552fd6..3932842589 100644
--- a/conf/routes
+++ b/conf/routes
@@ -97,6 +97,7 @@ GET /user_guide/using_matchers controll
GET /user_guide/testing_with_mock_objects controllers.UserGuide.testingWithMockObjects
GET /user_guide/tests_as_specifications controllers.UserGuide.testsAsSpecifications
GET /user_guide/property_based_testing controllers.UserGuide.propertyBasedTesting()
+GET /user_guide/scalacheck_property_based_testing controllers.UserGuide.scalacheckPropertyBasedTesting()
GET /user_guide/other_goodies controllers.UserGuide.otherGoodies
GET /user_guide/using_inside controllers.UserGuide.usingInside
GET /user_guide/using_OptionValues controllers.UserGuide.usingOptionValues
@@ -110,7 +111,9 @@ GET /user_guide/selecting_a_style controll
GET /user_guide/defining_base_classes controllers.UserGuide.definingBaseClasses()
GET /user_guide/using_junit_runner controllers.UserGuide.usingJunitRunner
GET /user_guide/table_driven_property_checks controllers.UserGuide.tableDrivenPropertyChecks
+GET /user_guide/scalacheck_table_driven_property_checks controllers.UserGuide.scalacheckTableDrivenPropertyChecks
GET /user_guide/generator_driven_property_checks controllers.UserGuide.generatorDrivenPropertyChecks
+GET /user_guide/scalacheck_driven_property_checks controllers.UserGuide.scalacheckDrivenPropertyChecks
GET /user_guide/writing_scalacheck_style_properties controllers.UserGuide.writingScalacheckStyleProperties
GET /user_guide/using_the_runner controllers.UserGuide.usingTheRunner
GET /user_guide/invoking_execute controllers.UserGuide.invokingExecute
From 963d89b048821c0c13854d73fa9b6464d27d1cc5 Mon Sep 17 00:00:00 2001
From: Chua Chee Seng
- To use generator-driven property checks, you must mix in trait
- The
In addition to taking a
For more information, see the documentation for trait
- Next, learn about ScalaTest's philosophy and design.
+ If you want to do table driven property check using ScalaCheck, learn about Table-driven property checks using ScalaCheck.
- ScalaTest supports property-based testing, where
+ ScalaTest supports property-based testing using ScalaCheck, where
a property is a high-level specification of behavior that should hold for a range of data points. For example, a property might
state that the size of a list returned from a method should always be greater than or equal to the size of the list passed to
that method. This property should hold no matter what list is passed.
@@ -59,7 +59,7 @@
- To use this style of testing, mix in trait ScalaCheck-driven property checks
+ Generator-driven property checks using ScalaCheck
org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
- (previously known as org.scalatest.props.PropertyChecks
). If you are also using table-driven property checks, you can mix in
+ To use generator-driven property checks, you must mix in trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
.
+ If you are also using table-driven property checks, you can mix in
trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
,
which extends both ScalaCheckDrivenPropertyChecks
and
TableDrivenPropertyChecks
.
@@ -339,11 +339,11 @@ ScalaCheck-driven property checks
forAll
methods of trait GeneratorDrivenPropertyChecks
each take a PropertyCheckConfiguration
+ The forAll
methods of trait ScalaCheckDrivenPropertyChecks
each take a PropertyCheckConfiguration
object as an implicit parameter. This object provides values for each of the five configuration parameters. Trait Configuration
provides an implicit val
named generatorDrivenConfig
with each configuration parameter set to its default value.
If you want to set one or more configuration parameters to a different value for all property checks in a suite you can override this
- val (or hide it, for example, if you are importing the members of the GeneratorDrivenPropertyChecks
companion object rather
+ val (or hide it, for example, if you are importing the members of the ScalaCheckDrivenPropertyChecks
companion object rather
than mixing in the trait.) For example, if
you want all parameters at their defaults except for minSize
and maxSize
, you can override
generatorDrivenConfig
, like this:
@@ -364,7 +364,7 @@ ScalaCheck-driven property checks
PropertyCheckConfiguration
object as an implicit parameter, the forAll
methods of trait
- GeneratorDrivenPropertyChecks
also take a variable length argument list of PropertyCheckConfigParam
+ ScalaCheckDrivenPropertyChecks
also take a variable length argument list of PropertyCheckConfigParam
objects that you can use to override the values provided by the implicit PropertyCheckConfiguration
for a single forAll
invocation. For example, if you want to set minSuccessful
to 500 for just one particular forAll
invocation,
you can do so like this:
@@ -403,11 +403,11 @@ ScalaCheck-driven property checks
Configuration
,
- a supertrait of GeneratorDrivenPropertyChecks
.
+ a supertrait of ScalaCheckDrivenPropertyChecks
.
Property-based testing using ScalaCheck
Property-based testing using ScalaCheck
org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
(previously known as org.scalatest.props.PropertyChecks
, deprecated in 3.0.6), or import the
+ To use this style of testing, mix in trait org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
, or import the
members of its companion object.
Property-based testing using ScalaCheck
To use table-driven property checks, you must mix in trait TableDrivenPropertyChecks
(or import the
@@ -276,7 +276,7 @@
- Next, learn about generator-driven property checks. + If you want to do ScalaCheck generator driven property check, learn about Generator-driven property checks using ScalaCheck.
assert
macroAppendedClues
.
-@*
--Next, learn about Using expectations. -
-*@ --Next, learn about tagging your tests. +Next, learn about using expectations.
From acfcf119c10222b4ab8cec53a5eb9b426624bf46 Mon Sep 17 00:00:00 2001 From: Chua Chee Seng-Latest Release - ScalaTest and Scalactic @latestVersion! +Latest Release - ScalaTest and Scalactic @latestVersion!
} diff --git a/app/views/plus/easymockVersions.scala.html b/app/views/plus/easymockVersions.scala.html index a4d024f7fc..ef44e2ebf5 100644 --- a/app/views/plus/easymockVersions.scala.html +++ b/app/views/plus/easymockVersions.scala.html @@ -31,6 +31,12 @@ScalaTest + EasyMock Version | ScalaTest Version | EasyMock Versions | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3.3.0.0 | +3.3.0 | +5.3 | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||
3.2.19.0 | 3.2.19 | diff --git a/app/views/plus/jmockVersions.scala.html b/app/views/plus/jmockVersions.scala.html index d77648f684..f57d77dc1c 100644 --- a/app/views/plus/jmockVersions.scala.html +++ b/app/views/plus/jmockVersions.scala.html @@ -31,6 +31,12 @@
ScalaTest + JMock Version | ScalaTest Version | JMock Versions | |||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3.3.0.0 | +3.3.0 | +2.13.x | +|||||||||||||||||||||||||||||||||||||||||||||||
3.2.19.0 | 3.2.19 | diff --git a/app/views/plus/junit4Versions.scala.html b/app/views/plus/junit4Versions.scala.html index dc44a2c3ad..e02f3b7989 100644 --- a/app/views/plus/junit4Versions.scala.html +++ b/app/views/plus/junit4Versions.scala.html @@ -31,6 +31,12 @@
ScalaTest + JUnit 4 Version | ScalaTest Version | JUnit 4 Versions | |||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3.3.0.0 | +3.3.0 | +4.13 | +|||||||||||||||||||||||||||||||||||||||
3.2.19.0 | 3.2.19 | diff --git a/app/views/plus/junit5Versions.scala.html b/app/views/plus/junit5Versions.scala.html index ef14c844be..9734d337f5 100644 --- a/app/views/plus/junit5Versions.scala.html +++ b/app/views/plus/junit5Versions.scala.html @@ -31,6 +31,12 @@
ScalaTest + JUnit 5 Version | ScalaTest Version | JUnit 5 Versions | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3.3.0.0 | +3.3.0 | +5.10 | +|||||||||||||||||||||||||||||||
3.2.19.0 | 3.2.19 | diff --git a/app/views/plus/mockitoVersions.scala.html b/app/views/plus/mockitoVersions.scala.html index 10b224edd8..bf9e1617c3 100644 --- a/app/views/plus/mockitoVersions.scala.html +++ b/app/views/plus/mockitoVersions.scala.html @@ -31,6 +31,12 @@
ScalaTest + Mockito Version | ScalaTest Version | Mockito Versions | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3.3.0.0 | +3.3.0 | +5.12 | +|||||||||||||||||||||||
3.2.19.0 | 3.2.19 | diff --git a/app/views/plus/scalacheckVersions.scala.html b/app/views/plus/scalacheckVersions.scala.html index ffa709b6b2..70c5e22841 100644 --- a/app/views/plus/scalacheckVersions.scala.html +++ b/app/views/plus/scalacheckVersions.scala.html @@ -31,6 +31,11 @@
ScalaTest + ScalaCheck Version | ScalaTest Version | ScalaCheck Versions | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3.3.0.0 | +3.3.0 | +1.18.x | +/tr>|||||||||||||||
3.2.19.0 | 3.2.19 | diff --git a/app/views/plus/seleniumVersions.scala.html b/app/views/plus/seleniumVersions.scala.html index 4eb63b7b86..d4edff8ae9 100644 --- a/app/views/plus/seleniumVersions.scala.html +++ b/app/views/plus/seleniumVersions.scala.html @@ -31,6 +31,12 @@
ScalaTest + Selenium Version | ScalaTest Version | Selenium Versions | |||||||
---|---|---|---|---|---|---|---|---|---|
3.3.0.0 | +3.3.0 | +4.21 | +|||||||
3.2.19.0 | 3.2.19 | diff --git a/app/views/plus/testngVersions.scala.html b/app/views/plus/testngVersions.scala.html index 83afc6af13..75040d773d 100644 --- a/app/views/plus/testngVersions.scala.html +++ b/app/views/plus/testngVersions.scala.html @@ -31,6 +31,12 @@
ScalaTest + TestNG Version | ScalaTest Version | TestNG Versions |
---|---|---|
3.3.0.0 | +3.3.0 | +7.10 | +
3.2.19.0 | 3.2.19 | diff --git a/app/views/quickStart.scala.html b/app/views/quickStart.scala.html index 2044c590ba..043a3ce917 100644 --- a/app/views/quickStart.scala.html +++ b/app/views/quickStart.scala.html @@ -69,14 +69,11 @@