Package

org.scalatest

fixture

Permalink

package fixture

Visibility
  1. Public
  2. All

Type Members

  1. trait AsyncConfigMapFixture extends AnyRef

    Permalink

    Trait that when mixed into a fixture.AsyncTestSuite passes the config map passed to runTest as a fixture into each test.

    Trait that when mixed into a fixture.AsyncTestSuite passes the config map passed to runTest as a fixture into each test.

    Here's an example in which tests just check to make sure "hello" and "world" are defined keys in the config map:

    package org.scalatest.examples.fixture.configmapfixture
    
    import org.scalatest._
    
    class ExampleAsyncSpec extends fixture.AsyncFlatSpec with fixture.AsyncConfigMapFixture with Matchers {
    
      "The config map" should "contain hello" in { configMap =>
        // Use the configMap passed to runTest in the test
        configMap should contain key "hello"
      }
    
      it should "contain world" in { configMap =>
        configMap should contain key "world"
      }
    }
    

    If you run this class without defining "hello" and "world" in the confg map, the tests will fail:

    scala> org.scalatest.run(new ExampleSpec)
    ExampleSpec:
    The config map
    - should contain hello *** FAILED ***
      Map() did not contain key "hello" (:20)
    - should contain world *** FAILED ***
      Map() did not contain key "world" (:24)
    

    If you do define "hello" and "world" keys in the confg map, the tests will success:

    scala> org.scalatest.run(new ExampleSpec, configMap = Map("hello" -> "hi", "world" -> "globe"))
    ExampleSpec:
    The config map
    - should contain hello
    - should contain world
    

  2. abstract class AsyncFeatureSpec extends AsyncFeatureSpecLike

    Permalink

    A sister class to org.scalatest.AsyncFeatureSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.AsyncFeatureSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.AsyncFeatureSpec in situations for which AsyncFeatureSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.AsyncFeatureSpec is intended for use in special situations, with class AsyncFeatureSpec used for general needs. For more insight into where fixture.AsyncFeatureSpec fits in the big picture, see the withFixture(OneArgAsyncTest) subsection of the Shared fixtures section in the documentation for class AsyncFeatureSpec.

    Class fixture.AsyncFeatureSpec behaves similarly to class org.scalatest.AsyncFeatureSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgAsyncTest, which is a nested trait defined as a member of this class. OneArgAsyncTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgAsyncTest), passing in the test code to run via the OneArgAsyncTest argument. The withFixture(OneArgAsyncTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.AsyncFeatureSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgAsyncTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgAsyncTest), it is a good idea to let withFixture(NoArgAsyncTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgAsyncTest to a NoArgAsyncTest. You can do that by passing the fixture object to the toNoArgAsyncTest method of OneArgAsyncTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgAsyncTest) method of the same instance by writing:

    withFixture(test.toNoArgAsyncTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.asyncfeaturespec.oneargasynctest
    
    import org.scalatest._
    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext
    
    // Defining actor messages
    sealed abstract class StringOp
    case object Clear extends StringOp
    case class Append(value: String) extends StringOp
    case object GetValue
    
    class StringActor { // Simulating an actor
      private final val sb = new StringBuilder
      def !(op: StringOp): Unit =
        synchronized {
          op match {
            case Append(value) => sb.append(value)
            case Clear => sb.clear()
          }
        }
      def ?(get: GetValue.type)(implicit c: ExecutionContext): Future[String] =
        Future {
          synchronized { sb.toString }
        }
    }
    
    class ExampleSpec extends fixture.AsyncFeatureSpec {
    
      type FixtureParam = StringActor
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
    
        val actor = new StringActor
        complete {
          actor ! Append("ScalaTest is designed to ") // set up the fixture
          withFixture(test.toNoArgAsyncTest(actor))
        } lastly {
          actor ! Clear // ensure the fixture will be cleaned up
        }
      }
    
      Feature("Simplicity") {
        Scenario("User needs to read test code written by others") { actor =>
          actor ! Append("encourage clear code!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s === "ScalaTest is designed to encourage clear code!")
          }
        }
    
        Scenario("User needs to understand what the tests are doing") { actor =>
          actor ! Append("be easy to reason about!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s === "ScalaTest is designed to be easy to reason about!")
          }
        }
      }
    }
    

    If a test fails, the future returned by the OneArgAsyncTest function will result in an org.scalatest.Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function and do the cleanup using complete-lastly, as shown in the previous example. The complete-lastly syntax, defined in CompleteLastly, which is extended by AsyncTestSuite, ensures the second, cleanup block of code is executed, whether the the first block throws an exception or returns a future. If it returns a future, the cleanup will be executed when the future completes.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgAsyncTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

     * package org.scalatest.examples.fixture.asyncfeaturespec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest._
    import DbServer._
    import java.util.UUID.randomUUID
    import scala.concurrent.Future
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.AsyncTestSuite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        complete {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgAsyncTest(db)) // "loan" the fixture to the test
        } lastly {
          removeDb(dbName) // ensure the fixture will be cleaned up
        }
      }
    }
    
    class ExampleSpec extends fixture.AsyncFeatureSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      Feature("Simplicity") {
        Scenario("Testing should be easy to write") { db =>
          Future {
            db.append("easy to write!")
            assert(db.toString === "ScalaTest is easy to write!")
          }
        }
    
        Scenario("Testing should be fun") { db =>
          Future {
            db.append("fun to write!")
            assert(db.toString === "ScalaTest is fun to write!")
          }
        }
    
        // This test doesn't need a Db
        Scenario("Testing code should be clear") { () =>
          Future {
            val buf = new StringBuffer
            buf.append("ScalaTest code is ")
            buf.append("clear!")
            assert(buf.toString === "ScalaTest code is clear!")
          }
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgAsyncTest). It will instead directly invoke withFixture(NoArgAsyncTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

  3. trait AsyncFeatureSpecLike extends AsyncTestSuite with AsyncTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.AsyncFeatureSpec, which is a sister class to org.scalatest.AsyncFeatureSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.AsyncFeatureSpec, which is a sister class to org.scalatest.AsyncFeatureSpec that can pass a fixture object into its tests.

    fixture.AsyncFeatureSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.AsyncFeatureSpec into some other class, you can use this trait instead, because class fixture.AsyncFeatureSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.AsyncFeatureSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  4. abstract class AsyncFlatSpec extends AsyncFlatSpecLike

    Permalink

    A sister class to org.scalatest.AsyncFlatSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.AsyncFlatSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.AsyncFlatSpec in situations for which AsyncFlatSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.AsyncFlatSpec is intended for use in special situations, with class AsyncFlatSpec used for general needs. For more insight into where fixture.AsyncFlatSpec fits in the big picture, see the withFixture(OneArgAsyncTest) subsection of the Shared fixtures section in the documentation for class AsyncFlatSpec.

    Class fixture.AsyncFlatSpec behaves similarly to class org.scalatest.AsyncFlatSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgAsyncTest, which is a nested trait defined as a member of this class. OneArgAsyncTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgAsyncTest), passing in the test code to run via the OneArgAsyncTest argument. The withFixture(OneArgAsyncTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.AsyncFlatSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgAsyncTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgAsyncTest), it is a good idea to let withFixture(NoArgAsyncTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgAsyncTest to a NoArgAsyncTest. You can do that by passing the fixture object to the toNoArgAsyncTest method of OneArgAsyncTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgAsyncTest) method of the same instance by writing:

    withFixture(test.toNoArgAsyncTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.asyncflatspec.oneargasynctest
    
    import org.scalatest._
    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext
    
    // Defining actor messages
    sealed abstract class StringOp
    case object Clear extends StringOp
    case class Append(value: String) extends StringOp
    case object GetValue
    
    class StringActor { // Simulating an actor
      private final val sb = new StringBuilder
      def !(op: StringOp): Unit =
        synchronized {
          op match {
            case Append(value) => sb.append(value)
            case Clear => sb.clear()
          }
        }
      def ?(get: GetValue.type)(implicit c: ExecutionContext): Future[String] =
        Future {
          synchronized { sb.toString }
        }
    }
    
    class ExampleSpec extends fixture.AsyncFlatSpec {
    
      type FixtureParam = StringActor
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
    
        val actor = new StringActor
        complete {
          actor ! Append("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgAsyncTest(actor))
        } lastly {
          actor ! Clear // ensure the fixture will be cleaned up
        }
      }
    
      "Testing" should "be easy" in { actor =>
        actor ! Append("easy!")
        val futureString = actor ? GetValue
        futureString map { s =>
          assert(s == "ScalaTest is easy!")
        }
      }
    
      it should "be fun" in { actor =>
        actor ! Append("fun!")
        val futureString = actor ? GetValue
        futureString map { s =>
          assert(s == "ScalaTest is fun!")
        }
      }
    
    }
    

    If a test fails, the future returned by the OneArgAsyncTest function will result in an org.scalatest.Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function and do the cleanup using complete-lastly, as shown in the previous example. The complete-lastly syntax, defined in CompleteLastly, which is extended by AsyncTestSuite, ensures the second, cleanup block of code is executed, whether the the first block throws an exception or returns a future. If it returns a future, the cleanup will be executed when the future completes.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgAsyncTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.asyncflatspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest._
    import DbServer._
    import java.util.UUID.randomUUID
    import scala.concurrent.Future
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.AsyncTestSuite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        complete {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgAsyncTest(db)) // "loan" the fixture to the test
        } lastly {
          removeDb(dbName) // ensure the fixture will be cleaned up
        }
      }
    }
    
    class ExampleSpec extends fixture.AsyncFlatSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" should "should be easy" in { db =>
        Future {
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
      }
    
      it should "be fun" in { db =>
        Future {
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      "Test code" should "be clear" in { () =>
        Future {
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgAsyncTest). It will instead directly invoke withFixture(NoArgAsyncTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

  5. trait AsyncFlatSpecLike extends AsyncTestSuite with AsyncTestRegistration with ShouldVerb with MustVerb with CanVerb with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.AsyncFlatSpec, which is a sister class to org.scalatest.AsyncFlatSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.AsyncFlatSpec, which is a sister class to org.scalatest.AsyncFlatSpec that can pass a fixture object into its tests.

    fixture.AsyncFlatSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.AsyncFlatSpec into some other class, you can use this trait instead, because class fixture.AsyncFlatSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.AsyncFlatSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  6. abstract class AsyncFreeSpec extends AsyncFreeSpecLike

    Permalink

    A sister class to org.scalatest.AsyncFunSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.AsyncFunSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.AsyncFunSpec in situations for which AsyncFunSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.AsyncFunSpec is intended for use in special situations, with class AsyncFunSpec used for general needs. For more insight into where fixture.AsyncFunSpec fits in the big picture, see the withFixture(OneArgAsyncTest) subsection of the Shared fixtures section in the documentation for class AsyncFunSpec.

    Class fixture.AsyncFunSpec behaves similarly to class org.scalatest.AsyncFunSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgAsyncTest, which is a nested trait defined as a member of this class. OneArgAsyncTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgAsyncTest), passing in the test code to run via the OneArgAsyncTest argument. The withFixture(OneArgAsyncTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.AsyncFunSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgAsyncTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgAsyncTest), it is a good idea to let withFixture(NoArgAsyncTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgAsyncTest to a NoArgAsyncTest. You can do that by passing the fixture object to the toNoArgAsyncTest method of OneArgAsyncTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgAsyncTest) method of the same instance by writing:

    withFixture(test.toNoArgAsyncTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.asyncfreespec.oneargasynctest
    
    import org.scalatest._
    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext
    
    // Defining actor messages
    sealed abstract class StringOp
    case object Clear extends StringOp
    case class Append(value: String) extends StringOp
    case object GetValue
    
    class StringActor { // Simulating an actor
      private final val sb = new StringBuilder
      def !(op: StringOp): Unit =
        synchronized {
          op match {
            case Append(value) => sb.append(value)
            case Clear => sb.clear()
          }
        }
      def ?(get: GetValue.type)(implicit c: ExecutionContext): Future[String] =
        Future {
          synchronized { sb.toString }
        }
    }
    
    class ExampleSpec extends fixture.AsyncFreeSpec {
    
      type FixtureParam = StringActor
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
    
        val actor = new StringActor
        complete {
          actor ! Append("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgAsyncTest(actor))
        } lastly {
          actor ! Clear // ensure the fixture will be cleaned up
        }
      }
    
      "Testing" - {
        "should be easy" in { actor =>
          actor ! Append("easy!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s == "ScalaTest is easy!")
          }
        }
    
        "should be fun" in { actor =>
          actor ! Append("fun!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s == "ScalaTest is fun!")
          }
        }
      }
    }
    

    If a test fails, the future returned by the OneArgAsyncTest function will result in an org.scalatest.Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function and do the cleanup using complete-lastly, as shown in the previous example. The complete-lastly syntax, defined in CompleteLastly, which is extended by AsyncTestSuite, ensures the second, cleanup block of code is executed, whether the the first block throws an exception or returns a future. If it returns a future, the cleanup will be executed when the future completes.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgAsyncTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.asyncfreespec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest._
    import DbServer._
    import java.util.UUID.randomUUID
    import scala.concurrent.Future
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.AsyncTestSuite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        complete {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgAsyncTest(db)) // "loan" the fixture to the test
        } lastly {
          removeDb(dbName) // ensure the fixture will be cleaned up
        }
      }
    }
    
    class ExampleSpec extends fixture.AsyncFreeSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
     "Testing" - {
        "should be easy" in { db =>
          Future {
            db.append("easy!")
            assert(db.toString === "ScalaTest is easy!")
          }
        }
    
        "should be fun" in { db =>
          Future {
            db.append("fun!")
            assert(db.toString === "ScalaTest is fun!")
          }
        }
    
        // This test doesn't need a Db
        "code should be clear" in { () =>
          Future {
            val buf = new StringBuffer
            buf.append("ScalaTest code is ")
            buf.append("clear!")
            assert(buf.toString === "ScalaTest code is clear!")
          }
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgAsyncTest). It will instead directly invoke withFixture(NoArgAsyncTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

  7. trait AsyncFreeSpecLike extends AsyncTestSuite with AsyncTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.AsyncFreeSpec, which is a sister class to org.scalatest.AsyncFreeSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.AsyncFreeSpec, which is a sister class to org.scalatest.AsyncFreeSpec that can pass a fixture object into its tests.

    fixture.AsyncFreeSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.AsyncFreeSpec into some other class, you can use this trait instead, because class fixture.AsyncFreeSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.AsyncFreeSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  8. abstract class AsyncFunSpec extends AsyncFunSpecLike

    Permalink

    A sister class to org.scalatest.AsyncFunSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.AsyncFunSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.AsyncFunSpec in situations for which AsyncFunSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.AsyncFunSpec is intended for use in special situations, with class AsyncFunSpec used for general needs. For more insight into where fixture.AsyncFunSpec fits in the big picture, see the withFixture(OneArgAsyncTest) subsection of the Shared fixtures section in the documentation for class AsyncFunSpec.

    Class fixture.AsyncFunSpec behaves similarly to class org.scalatest.AsyncFunSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgAsyncTest, which is a nested trait defined as a member of this class. OneArgAsyncTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgAsyncTest), passing in the test code to run via the OneArgAsyncTest argument. The withFixture(OneArgAsyncTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.AsyncFunSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgAsyncTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgAsyncTest), it is a good idea to let withFixture(NoArgAsyncTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgAsyncTest to a NoArgAsyncTest. You can do that by passing the fixture object to the toNoArgAsyncTest method of OneArgAsyncTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgAsyncTest) method of the same instance by writing:

    withFixture(test.toNoArgAsyncTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.asyncfunspec.oneargasynctest
    
    import org.scalatest._
    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext
    
    // Defining actor messages
    sealed abstract class StringOp
    case object Clear extends StringOp
    case class Append(value: String) extends StringOp
    case object GetValue
    
    class StringActor { // Simulating an actor
      private final val sb = new StringBuilder
      def !(op: StringOp): Unit =
        synchronized {
          op match {
            case Append(value) => sb.append(value)
            case Clear => sb.clear()
          }
        }
      def ?(get: GetValue.type)(implicit c: ExecutionContext): Future[String] =
        Future {
          synchronized { sb.toString }
        }
    }
    
    class ExampleSpec extends fixture.AsyncFunSpec {
    
      type FixtureParam = StringActor
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
    
        val actor = new StringActor
        complete {
          actor ! Append("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgAsyncTest(actor))
        } lastly {
          actor ! Clear // ensure the fixture will be cleaned up
        }
      }
    
      describe("Testing") {
        it("should be easy") { actor =>
          actor ! Append("easy!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s == "ScalaTest is easy!")
          }
        }
    
        it("should be fun") { actor =>
          actor ! Append("fun!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s == "ScalaTest is fun!")
          }
        }
      }
    }
    

    If a test fails, the future returned by the OneArgAsyncTest function will result in an org.scalatest.Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function and do the cleanup using complete-lastly, as shown in the previous example. The complete-lastly syntax, defined in CompleteLastly, which is extended by AsyncTestSuite, ensures the second, cleanup block of code is executed, whether the the first block throws an exception or returns a future. If it returns a future, the cleanup will be executed when the future completes.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgAsyncTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.asyncfunspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest._
    import DbServer._
    import java.util.UUID.randomUUID
    import scala.concurrent.Future
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.AsyncTestSuite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        complete {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgAsyncTest(db)) // "loan" the fixture to the test
        } lastly {
          removeDb(dbName) // ensure the fixture will be cleaned up
        }
      }
    }
    
    class ExampleSpec extends fixture.AsyncFunSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      describe("testing") {
        it("should be easy") { db =>
          Future {
            db.append("easy!")
            assert(db.toString === "ScalaTest is easy!")
          }
        }
    
        it("should be fun") { db =>
          Future {
            db.append("fun!")
            assert(db.toString === "ScalaTest is fun!")
          }
        }
    
        // This test doesn't need a Db
        it("code should be clear") { () =>
          Future {
            val buf = new StringBuffer
            buf.append("ScalaTest code is ")
            buf.append("clear!")
            assert(buf.toString === "ScalaTest code is clear!")
          }
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgAsyncTest). It will instead directly invoke withFixture(NoArgAsyncTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

  9. trait AsyncFunSpecLike extends AsyncTestSuite with AsyncTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.AsyncFunSpec, which is a sister class to org.scalatest.AsyncFunSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.AsyncFunSpec, which is a sister class to org.scalatest.AsyncFunSpec that can pass a fixture object into its tests.

    fixture.AsyncFunSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.AsyncFunSpec into some other class, you can use this trait instead, because class fixture.AsyncFunSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.AsyncFunSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  10. abstract class AsyncFunSuite extends AsyncFunSuiteLike

    Permalink

    A sister class to org.scalatest.AsyncFunSuite that can pass a fixture object into its tests.

    A sister class to org.scalatest.AsyncFunSuite that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.AsyncFunSuite in situations for which AsyncFunSuite would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.AsyncFunSuite is intended for use in special situations, with class AsyncFunSuite used for general needs. For more insight into where fixture.AsyncFunSuite fits in the big picture, see the withFixture(OneArgAsyncTest) subsection of the Shared fixtures section in the documentation for class AsyncFunSuite.

    Class fixture.AsyncFunSuite behaves similarly to class org.scalatest.AsyncFunSuite, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgAsyncTest, which is a nested trait defined as a member of this class. OneArgAsyncTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgAsyncTest), passing in the test code to run via the OneArgAsyncTest argument. The withFixture(OneArgAsyncTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.AsyncFunSuite:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgAsyncTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgAsyncTest), it is a good idea to let withFixture(NoArgAsyncTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgAsyncTest to a NoArgAsyncTest. You can do that by passing the fixture object to the toNoArgAsyncTest method of OneArgAsyncTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgAsyncTest) method of the same instance by writing:

    withFixture(test.toNoArgAsyncTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.asyncfunsuite.oneargasynctest
    
    import org.scalatest._
    import java.io._
    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext
    
    // Defining actor messages
    sealed abstract class StringOp
    case object Clear extends StringOp
    case class Append(value: String) extends StringOp
    case object GetValue
    
    class StringActor { // Simulating an actor
      private final val sb = new StringBuilder
      def !(op: StringOp): Unit =
        synchronized {
          op match {
            case Append(value) => sb.append(value)
            case Clear => sb.clear()
          }
        }
      def ?(get: GetValue.type)(implicit c: ExecutionContext): Future[String] =
        Future {
          synchronized { sb.toString }
        }
    }
    
    class ExampleSuite extends fixture.AsyncFunSuite {
    
      type FixtureParam = StringActor
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
    
        val actor = new StringActor
        complete {
          actor ! Append("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgAsyncTest(actor))
        } lastly {
          actor ! Clear // ensure the fixture will be cleaned up
        }
      }
    
      test("Testing should be easy") { actor =>
        actor ! Append("easy!")
        val futureString = actor ? GetValue
        futureString map { s =>
          assert(s === "ScalaTest is easy!")
        }
      }
    
      test("Testing should be fun") { actor =>
        actor ! Append("fun!")
        val futureString = actor ? GetValue
        futureString map { s =>
          assert(s === "ScalaTest is fun!")
        }
      }
    }
    

    If a test fails, the future returned by the OneArgAsyncTest function will result in an org.scalatest.Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function and do the cleanup using complete-lastly, as shown in the previous example. The complete-lastly syntax, defined in CompleteLastly, which is extended by AsyncTestSuite, ensures the second, cleanup block of code is executed, whether the the first block throws an exception or returns a future. If it returns a future, the cleanup will be executed when the future completes.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgAsyncTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.asyncfunsuite.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest._
    import DbServer._
    import java.util.UUID.randomUUID
    import scala.concurrent.Future
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.AsyncTestSuite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        complete {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgAsyncTest(db)) // "loan" the fixture to the test
        } lastly {
          removeDb(dbName) // ensure the fixture will be cleaned up
        }
      }
    }
    
    class ExampleSuite extends fixture.AsyncFunSuite with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      test("testing should be easy") { db =>
        Future {
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
      }
    
      test("testing should be fun") { db =>
        Future {
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      test("test code should be clear") { () =>
        Future {
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgAsyncTest). It will instead directly invoke withFixture(NoArgAsyncTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

  11. trait AsyncFunSuiteLike extends AsyncTestSuite with AsyncTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.AsyncFunSuite, which is a sister class to org.scalatest.AsyncFunSuite that can pass a fixture object into its tests.

    Implementation trait for class fixture.AsyncFunSuite, which is a sister class to org.scalatest.AsyncFunSuite that can pass a fixture object into its tests.

    fixture.AsyncFunSuite is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.AsyncFunSuite into some other class, you can use this trait instead, because class fixture.AsyncFunSuite does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.AsyncFunSuite.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  12. trait AsyncTestDataFixture extends AnyRef

    Permalink

    Trait that when mixed into a fixture.AsyncTestSuite passes the TestData passed to withFixture as a fixture into each test.

    Trait that when mixed into a fixture.AsyncTestSuite passes the TestData passed to withFixture as a fixture into each test.

    For example, here's how you could access the test's name in each test using AsyncTestDataFixture:

    package org.scalatest.examples.fixture.testdatafixture
    
    import org.scalatest._
    
    class ExampleAsyncSpec extends fixture.AsyncFlatSpec with fixture.AsyncTestDataFixture {
    
      "Accessing the test data" should "be easy!" in { td =>
        assert(td.name == "Accessing the test data should be easy!")
      }
    
      it should "be fun!" in { td =>
        assert(td.name == "Accessing the test data should be fun!")
      }
    }
    

  13. trait AsyncTestRegistration extends AnyRef

    Permalink

    Trait declaring methods that can be used to register test functions that accept a fixture parameter and have result type Future[Assertion].

    Trait declaring methods that can be used to register test functions that accept a fixture parameter and have result type Future[Assertion].

  14. trait AsyncTestSuite extends Suite with scalatest.AsyncTestSuite

    Permalink

    The base trait of ScalaTest's "fixture" async testing styles, which enable you to pass fixture objects into tests.

    The base trait of ScalaTest's "fixture" async testing styles, which enable you to pass fixture objects into tests.

    This trait provides a final override of withFixture(OneArgTest), declared in supertrait fixture.Suite, because the withFixture(OneArgTest) lifecycle method assumes synchronous testing. Here is its signature:

    def withFixture(test: OneArgTest): Outcome
    

    The test function interface, OneArgTest, offers an apply method that takes a FixtureParam and returns Outcome:

    // In trait OneArgTest:
    def apply(fixture: FixtureParam): Outcome
    

    Because the result of a test is an Outcome, when the test function returns, the test body must have determined an outcome already. It will already be one of Succeeded, Failed, Canceled, or Pending. This is also true when withFixture(OneArgTest) returns: because the result type of withFixture(OneArgTest) is Outcome, the test body has by definition has already finished execution.

    This trait overrides and makes abstract the runTest method. Subtraits must must implement this method to call withFixture(OneArgAsyncTest) instead of withFixture(OneArgTest), where withFixture(OneArgAsyncTest) is a new method declared in this trait with the following signature and implementation:

    def withFixture(test: OneArgAsyncTest): FutureOutcome = {
      test()
    }
    

    Instead of returning Outcome like withFixture, the withFixture method returns a FutureOutcome. Similarly, the apply method of test function interface, OneArgAsyncTest, returns FutureOutcome:

    // In trait OneArgAsyncTest:
    def apply(fixture: FixtureParam): FutureOutcome
    

    The withFixture method supports async testing, because when the test function returns, the test body has not necessarily finished execution.

    The recommended way to ensure cleanup is performed after a test body finishes execution is to use the complete-lastly syntax, defined in supertrait org.scalatest.CompleteLastly, which will ensure that cleanup will occur whether future-producing code completes abruptly by throwing an exception, or returns normally yielding a future. In the latter case, complete-lastly will register the cleanup code to execute asynchronously when the future completes.

    To enable the stacking of traits that define withFixture(NoArgAsyncTest), it is a good idea to let withFixture(NoArgAsyncTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgAsyncTest to a NoArgAsyncTest. You can do that by passing the fixture object to the toNoArgAsyncTest method of OneArgAsyncTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgAsyncTest) method of the same instance by writing:

    withFixture(test.toNoArgAsyncTest(theFixture))
    

    Thus, the recommended structure of a withFixture implementation that performs cleanup looks like this:

    // Your implementation
    override def withFixture(test: OneArgAsyncTest) = {
    
      // Perform setup here
      val theFixture = ...
    
      complete {
        withFixture(test.toNoArgAsyncTest(theFixture)) // Invoke the test function
      } lastly {
        // Perform cleanup here
      }
    }
    

    If you have no cleanup to perform, you can write withFixture like this instead:

    // Your implementation
    override def withFixture(test: OneArgAsyncTest) = {
    
      // Perform setup here
      val theFixture = ...
    
      withFixture(test.toNoArgAsyncTest(theFixture)) // Invoke the test function
    }
    

    If you want to perform an action only for certain outcomes, you'll need to register code performing that action as a callback on the Future using one of Future registration methods: onComplete, onSuccess, or onFailure. Note that if a test fails, that will be treated as a scala.util.Success(org.scalatest.Failure). So if you want to perform an action if a test fails, for example, you'd register the callaback using onSuccess, like this:

    // Your implementation
    override def withFixture(test: OneArgAsyncTest) = {
    
      // Perform setup here
      val theFixture = ...
    
      val futureOutcome =
          withFixture(test.toNoArgAsyncTest(theFixture)) // Invoke the test function
    
      futureOutcome onFailedThen { _ =>
        // perform action that you want to occur
        // only if a test fails here
      }
    }
    

    Lastly, if you want to transform the outcome in some way in withFixture, you'll need to use either the map or transform methods of Future, like this:

    // Your implementation
    override def withFixture(test: OneArgAsyncTest) = {
    
      // Perform setup here
      val theFixture = ...
    
      val futureOutcome =
          withFixture(test.toNoArgAsyncTest(theFixture)) // Invoke the test function
    
      futureOutcome change { outcome =>
        // transform the outcome into a new outcome here
      }
    }
    

    Note that a NoArgAsyncTest's apply method will only return a Failure if the test completes abruptly with an exception (such as OutOfMemoryError) that should cause the suite to abort rather than the test to fail. Thus usually you would use map to transform future outcomes, not transform, so that such suite-aborting exceptions pass through unchanged. The suite will abort asynchronously with any exception returned in a Failure.

  15. abstract class AsyncWordSpec extends AsyncWordSpecLike

    Permalink

    A sister class to org.scalatest.AsyncWordSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.AsyncWordSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.AsyncWordSpec in situations for which AsyncWordSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.AsyncWordSpec is intended for use in special situations, with class AsyncWordSpec used for general needs. For more insight into where fixture.AsyncWordSpec fits in the big picture, see the withFixture(OneArgAsyncTest) subsection of the Shared fixtures section in the documentation for class AsyncWordSpec.

    Class fixture.AsyncWordSpec behaves similarly to class org.scalatest.AsyncWordSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgAsyncTest, which is a nested trait defined as a member of this class. OneArgAsyncTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgAsyncTest), passing in the test code to run via the OneArgAsyncTest argument. The withFixture(OneArgAsyncTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.AsyncWordSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgAsyncTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgAsyncTest), it is a good idea to let withFixture(NoArgAsyncTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgAsyncTest to a NoArgAsyncTest. You can do that by passing the fixture object to the toNoArgAsyncTest method of OneArgAsyncTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgAsyncTest) method of the same instance by writing:

    withFixture(test.toNoArgAsyncTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.asyncwordspec.oneargasynctest
    
    import org.scalatest._
    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext
    
    // Defining actor messages
    sealed abstract class StringOp
    case object Clear extends StringOp
    case class Append(value: String) extends StringOp
    case object GetValue
    
    class StringActor { // Simulating an actor
      private final val sb = new StringBuilder
      def !(op: StringOp): Unit =
        synchronized {
          op match {
            case Append(value) => sb.append(value)
            case Clear => sb.clear()
          }
        }
      def ?(get: GetValue.type)(implicit c: ExecutionContext): Future[String] =
        Future {
          synchronized { sb.toString }
        }
    }
    
    class ExampleSpec extends fixture.AsyncWordSpec {
    
      type FixtureParam = StringActor
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
    
        val actor = new StringActor
        complete {
          actor ! Append("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgAsyncTest(actor))
        } lastly {
          actor ! Clear // ensure the fixture will be cleaned up
        }
      }
    
      "Testing" should {
        "be easy" in { actor =>
          actor ! Append("easy!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s == "ScalaTest is easy!")
          }
        }
    
        "be fun" in { actor =>
          actor ! Append("fun!")
          val futureString = actor ? GetValue
          futureString map { s =>
            assert(s == "ScalaTest is fun!")
          }
        }
      }
    }
    

    If a test fails, the future returned by the OneArgAsyncTest function will result in an org.scalatest.Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function and do the cleanup using complete-lastly, as shown in the previous example. The complete-lastly syntax, defined in CompleteLastly, which is extended by AsyncTestSuite, ensures the second, cleanup block of code is executed, whether the the first block throws an exception or returns a future. If it returns a future, the cleanup will be executed when the future completes.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgAsyncTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.asyncwordspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest._
    import DbServer._
    import java.util.UUID.randomUUID
    import scala.concurrent.Future
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.AsyncTestSuite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgAsyncTest): FutureOutcome = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        complete {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgAsyncTest(db)) // "loan" the fixture to the test
        } lastly {
          removeDb(dbName) // ensure the fixture will be cleaned up
        }
      }
    }
    
    class ExampleSpec extends fixture.AsyncWordSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" should {
        "be easy" in { db =>
          Future {
            db.append("easy!")
            assert(db.toString === "ScalaTest is easy!")
          }
        }
    
        "be fun" in { db =>
          Future {
            db.append("fun!")
            assert(db.toString === "ScalaTest is fun!")
          }
        }
      }
    
      "Testing code" should {
        // This test doesn't need a Db
        "be clear" in { () =>
          Future {
            val buf = new StringBuffer
            buf.append("ScalaTest code is ")
            buf.append("clear!")
            assert(buf.toString === "ScalaTest code is clear!")
          }
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgAsyncTest). It will instead directly invoke withFixture(NoArgAsyncTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

  16. trait AsyncWordSpecLike extends AsyncTestSuite with AsyncTestRegistration with ShouldVerb with MustVerb with CanVerb with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.AsyncWordSpec, which is a sister class to org.scalatest.AsyncWordSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.AsyncWordSpec, which is a sister class to org.scalatest.AsyncWordSpec that can pass a fixture object into its tests.

    fixture.AsyncWordSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.AsyncWordSpec into some other class, you can use this trait instead, because class fixture.AsyncWordSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.AsyncWordSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  17. trait ConfigMapFixture extends AnyRef

    Permalink

    Trait that when mixed into a fixture.Suite passes the config map passed to runTest as a fixture into each test.

    Trait that when mixed into a fixture.Suite passes the config map passed to runTest as a fixture into each test.

    Here's an example in which tests just check to make sure "hello" and "world" are defined keys in the config map:

    package org.scalatest.examples.fixture.configmapfixture
    
    import org.scalatest._
    
    class ExampleSpec extends fixture.FlatSpec with fixture.ConfigMapFixture with Matchers {
    
      "The config map" should "contain hello" in { configMap =>
        // Use the configMap passed to runTest in the test
        configMap should contain key "hello"
      }
    
      it should "contain world" in { configMap =>
        configMap should contain key "world"
      }
    }
    

    If you run this class without defining "hello" and "world" in the confg map, the tests will fail:

    scala> org.scalatest.run(new ExampleSpec)
    ExampleSpec:
    The config map
    - should contain hello *** FAILED ***
      Map() did not contain key "hello" (:20)
    - should contain world *** FAILED ***
      Map() did not contain key "world" (:24)
    

    If you do define "hello" and "world" keys in the confg map, the tests will success:

    scala> org.scalatest.run(new ExampleSpec, configMap = Map("hello" -> "hi", "world" -> "globe"))
    ExampleSpec:
    The config map
    - should contain hello
    - should contain world
    

  18. abstract class FeatureSpec extends FeatureSpecLike

    Permalink

    A sister class to org.scalatest.FeatureSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.FeatureSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.FeatureSpec in situations for which FeatureSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.FeatureSpec is intended for use in special situations, with class FeatureSpec used for general needs. For more insight into where fixture.FeatureSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class FeatureSpec.

    Class fixture.FeatureSpec behaves similarly to class org.scalatest.FeatureSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This trait also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.FeatureSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.featurespec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.FeatureSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is designed to be ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      Feature("Simplicity") {
        Scenario("User needs to read test code written by others") { f =>
          f.writer.write("encourage clear code!")
          f.writer.flush()
          assert(f.file.length === 49)
        }
    
        Scenario("User needs to understand what the tests are doing") { f =>
          f.writer.write("be easy to reason about!")
          f.writer.flush()
          assert(f.file.length === 52)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.featurespec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.FeatureSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is designed to ")
      }
    
      Feature("Simplicity") {
    
        Scenario("User needs to read test code written by others") { db =>
          db.append("encourage clear code!")
          assert(db.toString === "ScalaTest is designed to encourage clear code!")
        }
    
        Scenario("User needs to understand what the tests are doing") { db =>
          db.append("be easy to reason about!")
          assert(db.toString === "ScalaTest is designed to be easy to reason about!")
        }
    
        Scenario("User needs to write tests") { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest is designed to be ")
          buf.append("easy to learn!")
          assert(buf.toString === "ScalaTest is designed to be easy to learn!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  19. trait FeatureSpecLike extends TestSuite with TestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.FeatureSpec, which is a sister class to org.scalatest.FeatureSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.FeatureSpec, which is a sister class to org.scalatest.FeatureSpec that can pass a fixture object into its tests.

    fixture.FeatureSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.FeatureSpec into some other class, you can use this trait instead, because class fixture.FeatureSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.FeatureSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  20. abstract class FlatSpec extends FlatSpecLike

    Permalink

    A sister class to org.scalatest.FlatSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.FlatSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.FlatSpec in situations for which FlatSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.FlatSpec is intended for use in special situations, with class FlatSpec used for general needs. For more insight into where fixture.FlatSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class FlatSpec.

    Class fixture.FlatSpec behaves similarly to class org.scalatest.FlatSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.FlatSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.flatspec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.FlatSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      "Testing" should "be easy" in { f =>
        f.writer.write("easy!")
        f.writer.flush()
        assert(f.file.length === 18)
      }
    
      it should "be fun" in { f =>
        f.writer.write("fun!")
        f.writer.flush()
        assert(f.file.length === 17)
      }
    }
    

    If a test fails because of an exception, the OneArgTest function will result in a Failed wrapping the exception. To ensure clean up happens even if an exception occurs, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.flatspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.FlatSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" should "be easy" in { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
      }
    
      it should "be fun" in { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
      }
    
      // This test doesn't need a Db
      "Test code" should "be clear" in { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  21. trait FlatSpecLike extends TestSuite with TestRegistration with ShouldVerb with MustVerb with CanVerb with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.FlatSpec, which is a sister class to org.scalatest.FlatSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.FlatSpec, which is a sister class to org.scalatest.FlatSpec that can pass a fixture object into its tests.

    fixture.FlatSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.FlatSpec into some other class, you can use this trait instead, because class fixture.FlatSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.FlatSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  22. abstract class FreeSpec extends FreeSpecLike

    Permalink

    A sister class to org.scalatest.FreeSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.FreeSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.FreeSpec in situations for which FreeSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.FreeSpec is intended for use in special situations, with class FreeSpec used for general needs. For more insight into where fixture.FreeSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class FreeSpec.

    Class fixture.FreeSpec behaves similarly to class org.scalatest.FreeSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.FreeSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.freespec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.FreeSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      "Testing" - {
        "should be easy" in { f =>
          f.writer.write("easy!")
          f.writer.flush()
          assert(f.file.length === 18)
        }
    
        "should be fun" in { f =>
          f.writer.write("fun!")
          f.writer.flush()
          assert(f.file.length === 17)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.freespec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.FreeSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" - {
        "should be easy" in { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
    
        "should be fun" in { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      "Test code" - {
        "should be clear" in { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  23. trait FreeSpecLike extends TestSuite with TestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.FreeSpec, which is a sister class to org.scalatest.FreeSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.FreeSpec, which is a sister class to org.scalatest.FreeSpec that can pass a fixture object into its tests.

    fixture.FreeSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.FreeSpec into some other class, you can use this trait instead, because class fixture.FreeSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.FreeSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  24. abstract class FunSpec extends FunSpecLike

    Permalink

    A sister class to org.scalatest.FunSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.FunSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.FunSpec in situations for which FunSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.FunSpec is intended for use in special situations, with class FunSpec used for general needs. For more insight into where fixture.FunSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class FunSpec.

    Class fixture.FunSpec behaves similarly to class org.scalatest.FunSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.FunSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.funspec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.FunSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      describe("Testing") {
        it("should be easy") { f =>
          f.writer.write("easy!")
          f.writer.flush()
          assert(f.file.length === 18)
        }
    
        it("should be fun") { f =>
          f.writer.write("fun!")
          f.writer.flush()
          assert(f.file.length === 17)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.funspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.FunSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      describe("Testing") {
        it("should be easy") { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
    
        it("should be fun") { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      describe("Test code") {
        it("should be clear") { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  25. trait FunSpecLike extends TestSuite with TestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.FunSpec, which is a sister class to org.scalatest.FunSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.FunSpec, which is a sister class to org.scalatest.FunSpec that can pass a fixture object into its tests.

    fixture.FunSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.FunSpec into some other class, you can use this trait instead, because class fixture.FunSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.FunSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  26. abstract class FunSuite extends FunSuiteLike

    Permalink

    A sister class to org.scalatest.FunSuite that can pass a fixture object into its tests.

    A sister class to org.scalatest.FunSuite that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.FunSuite in situations for which FunSuite would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.FunSuite is intended for use in special situations, with class FunSuite used for general needs. For more insight into where fixture.FunSuite fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class FunSuite.

    Class fixture.FunSuite behaves similarly to class org.scalatest.FunSuite, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.FunSuite:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.funsuite.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSuite extends fixture.FunSuite {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      test("testing should be easy") { f =>
        f.writer.write("easy!")
        f.writer.flush()
        assert(f.file.length === 18)
      }
    
      test("testing should be fun") { f =>
        f.writer.write("fun!")
        f.writer.flush()
        assert(f.file.length === 17)
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.funsuite.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSuite extends fixture.FunSuite with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      test("testing should be easy") { db =>
        db.append("easy!")
        assert(db.toString === "ScalaTest is easy!")
      }
    
      test("testing should be fun") { db =>
        db.append("fun!")
        assert(db.toString === "ScalaTest is fun!")
      }
    
      // This test doesn't need a Db
      test("test code should be clear") { () =>
        val buf = new StringBuffer
        buf.append("ScalaTest code is ")
        buf.append("clear!")
        assert(buf.toString === "ScalaTest code is clear!")
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  27. trait FunSuiteLike extends TestSuite with TestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.FunSuite, which is a sister class to org.scalatest.FunSuite that can pass a fixture object into its tests.

    Implementation trait for class fixture.FunSuite, which is a sister class to org.scalatest.FunSuite that can pass a fixture object into its tests.

    fixture.FunSuite is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.FunSuite into some other class, you can use this trait instead, because class fixture.FunSuite does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.FunSuite.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  28. abstract class LogicFeatureSpec extends LogicFeatureSpecLike

    Permalink

    A sister class to org.scalatest.LogicFeatureSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.LogicFeatureSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.LogicFeatureSpec in situations for which LogicFeatureSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.LogicFeatureSpec is intended for use in special situations, with class LogicFeatureSpec used for general needs. For more insight into where fixture.LogicFeatureSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class LogicFeatureSpec.

    Class fixture.LogicFeatureSpec behaves similarly to class org.scalatest.LogicFeatureSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This trait also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.LogicFeatureSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.featurespec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.LogicFeatureSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is designed to be ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      Feature("Simplicity") {
        Scenario("User needs to read test code written by others") { f =>
          f.writer.write("encourage clear code!")
          f.writer.flush()
          assert(f.file.length === 49)
        }
    
        Scenario("User needs to understand what the tests are doing") { f =>
          f.writer.write("be easy to reason about!")
          f.writer.flush()
          assert(f.file.length === 52)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.featurespec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.LogicFeatureSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is designed to ")
      }
    
      Feature("Simplicity") {
    
        Scenario("User needs to read test code written by others") { db =>
          db.append("encourage clear code!")
          assert(db.toString === "ScalaTest is designed to encourage clear code!")
        }
    
        Scenario("User needs to understand what the tests are doing") { db =>
          db.append("be easy to reason about!")
          assert(db.toString === "ScalaTest is designed to be easy to reason about!")
        }
    
        Scenario("User needs to write tests") { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest is designed to be ")
          buf.append("easy to learn!")
          assert(buf.toString === "ScalaTest is designed to be easy to learn!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  29. trait LogicFeatureSpecLike extends TestSuite with LogicTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.LogicFeatureSpec, which is a sister class to org.scalatest.LogicFeatureSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.LogicFeatureSpec, which is a sister class to org.scalatest.LogicFeatureSpec that can pass a fixture object into its tests.

    fixture.LogicFeatureSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.LogicFeatureSpec into some other class, you can use this trait instead, because class fixture.LogicFeatureSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.LogicFeatureSpec.

    Annotations
    @Finders()
  30. abstract class LogicFlatSpec extends LogicFlatSpecLike

    Permalink

    A sister class to org.scalatest.LogicFlatSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.LogicFlatSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.LogicFlatSpec in situations for which LogicFlatSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.LogicFlatSpec is intended for use in special situations, with class LogicFlatSpec used for general needs. For more insight into where fixture.LogicFlatSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class LogicFlatSpec.

    Class fixture.LogicFlatSpec behaves similarly to class org.scalatest.LogicFlatSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.LogicFlatSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.flatspec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.LogicFlatSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      "Testing" should "be easy" in { f =>
        f.writer.write("easy!")
        f.writer.flush()
        assert(f.file.length === 18)
      }
    
      it should "be fun" in { f =>
        f.writer.write("fun!")
        f.writer.flush()
        assert(f.file.length === 17)
      }
    }
    

    If a test fails because of an exception, the OneArgTest function will result in a Failed wrapping the exception. To ensure clean up happens even if an exception occurs, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.flatspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.LogicFlatSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" should "be easy" in { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
      }
    
      it should "be fun" in { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
      }
    
      // This test doesn't need a Db
      "Test code" should "be clear" in { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  31. trait LogicFlatSpecLike extends TestSuite with LogicTestRegistration with ShouldVerb with MustVerb with CanVerb with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.LogicFlatSpec, which is a sister class to org.scalatest.LogicFlatSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.LogicFlatSpec, which is a sister class to org.scalatest.LogicFlatSpec that can pass a fixture object into its tests.

    fixture.LogicFlatSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.LogicFlatSpec into some other class, you can use this trait instead, because class fixture.LogicFlatSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.LogicFlatSpec.

    Annotations
    @Finders()
  32. abstract class LogicFreeSpec extends LogicFreeSpecLike

    Permalink

    A sister class to org.scalatest.LogicFreeSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.LogicFreeSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.LogicFreeSpec in situations for which LogicFreeSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.LogicFreeSpec is intended for use in special situations, with class LogicFreeSpec used for general needs. For more insight into where fixture.LogicFreeSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class LogicFreeSpec.

    Class fixture.LogicFreeSpec behaves similarly to class org.scalatest.LogicFreeSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.LogicFreeSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.freespec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.LogicFreeSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      "Testing" - {
        "should be easy" in { f =>
          f.writer.write("easy!")
          f.writer.flush()
          assert(f.file.length === 18)
        }
    
        "should be fun" in { f =>
          f.writer.write("fun!")
          f.writer.flush()
          assert(f.file.length === 17)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.freespec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.LogicFreeSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" - {
        "should be easy" in { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
    
        "should be fun" in { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      "Test code" - {
        "should be clear" in { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  33. trait LogicFreeSpecLike extends TestSuite with LogicTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.LogicFreeSpec, which is a sister class to org.scalatest.LogicFreeSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.LogicFreeSpec, which is a sister class to org.scalatest.LogicFreeSpec that can pass a fixture object into its tests.

    fixture.LogicFreeSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.LogicFreeSpec into some other class, you can use this trait instead, because class fixture.LogicFreeSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.LogicFreeSpec.

    Annotations
    @Finders()
  34. abstract class LogicFunSpec extends LogicFunSpecLike

    Permalink

    A sister class to org.scalatest.LogicFunSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.LogicFunSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.LogicFunSpec in situations for which LogicFunSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.LogicFunSpec is intended for use in special situations, with class LogicFunSpec used for general needs. For more insight into where fixture.LogicFunSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class LogicFunSpec.

    Class fixture.LogicFunSpec behaves similarly to class org.scalatest.LogicFunSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.LogicFunSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.funspec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.LogicFunSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      describe("Testing") {
        it("should be easy") { f =>
          f.writer.write("easy!")
          f.writer.flush()
          assert(f.file.length === 18)
        }
    
        it("should be fun") { f =>
          f.writer.write("fun!")
          f.writer.flush()
          assert(f.file.length === 17)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.funspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.LogicFunSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      describe("Testing") {
        it("should be easy") { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
    
        it("should be fun") { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      describe("Test code") {
        it("should be clear") { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  35. trait LogicFunSpecLike extends TestSuite with LogicTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.LogicFunSpec, which is a sister class to org.scalatest.LogicFunSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.LogicFunSpec, which is a sister class to org.scalatest.LogicFunSpec that can pass a fixture object into its tests.

    fixture.LogicFunSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.LogicFunSpec into some other class, you can use this trait instead, because class fixture.LogicFunSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.LogicFunSpec.

    Annotations
    @Finders()
  36. abstract class LogicFunSuite extends LogicFunSuiteLike

    Permalink

    A sister class to org.scalatest.LogicFunSuite that can pass a fixture object into its tests.

    A sister class to org.scalatest.LogicFunSuite that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.LogicFunSuite in situations for which LogicFunSuite would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.LogicFunSuite is intended for use in special situations, with class LogicFunSuite used for general needs. For more insight into where fixture.LogicFunSuite fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class LogicFunSuite.

    Class fixture.LogicFunSuite behaves similarly to class org.scalatest.LogicFunSuite, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also contains an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.LogicFunSuite:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.funsuite.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSuite extends fixture.LogicFunSuite {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      test("testing should be easy") { f =>
        f.writer.write("easy!")
        f.writer.flush()
        assert(f.file.length === 18)
      }
    
      test("testing should be fun") { f =>
        f.writer.write("fun!")
        f.writer.flush()
        assert(f.file.length === 17)
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.funsuite.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSuite extends fixture.LogicFunSuite with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      test("testing should be easy") { db =>
        db.append("easy!")
        assert(db.toString === "ScalaTest is easy!")
      }
    
      test("testing should be fun") { db =>
        db.append("fun!")
        assert(db.toString === "ScalaTest is fun!")
      }
    
      // This test doesn't need a Db
      test("test code should be clear") { () =>
        val buf = new StringBuffer
        buf.append("ScalaTest code is ")
        buf.append("clear!")
        assert(buf.toString === "ScalaTest code is clear!")
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSuite.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSuite classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  37. trait LogicFunSuiteLike extends TestSuite with LogicTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.LogicFunSuite, which is a sister class to org.scalatest.LogicFunSuite that can pass a fixture object into its tests.

    Implementation trait for class fixture.LogicFunSuite, which is a sister class to org.scalatest.LogicFunSuite that can pass a fixture object into its tests.

    fixture.LogicFunSuite is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.LogicFunSuite into some other class, you can use this trait instead, because class fixture.LogicFunSuite does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.LogicFunSuite.

    Annotations
    @Finders()
  38. abstract class LogicPropSpec extends LogicPropSpecLike

    Permalink

    A sister class to org.scalatest.LogicPropSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.LogicPropSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.LogicPropSpec in situations for which LogicPropSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.LogicPropSpec is intended for use in special situations, with class LogicPropSpec used for general needs. For more insight into where fixture.LogicPropSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class LogicPropSpec.

    Class fixture.LogicPropSpec behaves similarly to class org.scalatest.LogicPropSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture, passing in the test code to run via the OneArgTest argument. The withFixture method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.LogicPropSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    Here's an example:

    package org.scalatest.examples.fixture.propspec
    
    import org.scalatest._
    import prop.PropertyChecks
    import java.io._
    
    class ExampleSpec extends fixture.LogicPropSpec with PropertyChecks with Matchers {
    
      // 1. define type FixtureParam
      type FixtureParam = FileReader
    
      // 2. define the withFixture method
      def withFixture(test: OneArgTest) = {
    
        val FileName = "TempFile.txt"
    
        // Set up the temp file needed by the test
        val writer = new FileWriter(FileName)
        try {
          writer.write("Hello, test!")
        }
        finally {
          writer.close()
        }
    
        // Create the reader needed by the test
        val reader = new FileReader(FileName)
    
        try {
          // Run the test using the temp file
          test(reader)
        }
        finally {
          // Close and delete the temp file
          reader.close()
          val file = new File(FileName)
          file.delete()
        }
      }
    
      // 3. write property-based tests that take a fixture parameter
      // (Hopefully less contrived than the examples shown here.)
      property("can read from a temp file") { reader =>
        var builder = new StringBuilder
        var c = reader.read()
        while (c != -1) {
          builder.append(c.toChar)
          c = reader.read()
        }
        val fileContents = builder.toString
        forAll { (c: Char) =>
          whenever (c != 'H') {
            fileContents should not startWith c.toString
          }
        }
      }
    
      property("can read the first char of the temp file") { reader =>
        val firstChar = reader.read()
        forAll { (c: Char) =>
          whenever (c != 'H') {
            c should not equal firstChar
          }
        }
      }
    
      // (You can also write tests that don't take a fixture parameter.)
      property("can write tests that don't take the fixture") { () =>
        forAll { (i: Int) => i + i should equal (2 * i) }
      }
    }
    

    Note: to run the examples on this page, you'll need to include ScalaCheck on the classpath in addition to ScalaTest.

    In the previous example, withFixture creates and initializes a temp file, then invokes the test function, passing in a FileReader connected to that file. In addition to setting up the fixture before a test, the withFixture method also cleans it up afterwards. If you need to do some clean up that must happen even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. The reason you must perform cleanup in a finally clause is that in case an exception propagates back through withFixture, the finally clause will ensure the fixture cleanup happens as that exception propagates back up the call stack to runTest.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function. In other words, instead of starting your function literal with something like “reader =>”, you'd start it with “() =>”, as is done in the third test in the above example. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Passing multiple fixture objects

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(builder: StringBuilder, buffer: ListBuffer[String])
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.fixture.propspec.multi
    
    import org.scalatest._
    import prop.PropertyChecks
    import scala.collection.mutable.ListBuffer
    
    class ExampleSpec extends fixture.LogicPropSpec with PropertyChecks with Matchers {
    
      case class FixtureParam(builder: StringBuilder, buffer: ListBuffer[String])
    
      def withFixture(test: OneArgTest) = {
    
        // Create needed mutable objects
        val stringBuilder = new StringBuilder("ScalaTest is ")
        val listBuffer = new ListBuffer[String]
        val theFixture = FixtureParam(stringBuilder, listBuffer)
    
        // Invoke the test function, passing in the mutable objects
        withFixture(test.toNoArgTest(theFixture))
      }
    
      property("testing should be easy") { f =>
        f.builder.append("easy!")
        assert(f.builder.toString === "ScalaTest is easy!")
        assert(f.buffer.isEmpty)
        val firstChar = f.builder(0)
        forAll { (c: Char) =>
          whenever (c != 'S') {
            c should not equal firstChar
          }
        }
        f.buffer += "sweet"
      }
    
      property("testing should be fun") { f =>
        f.builder.append("fun!")
        assert(f.builder.toString === "ScalaTest is fun!")
        assert(f.buffer.isEmpty)
        val firstChar = f.builder(0)
        forAll { (c: Char) =>
          whenever (c != 'S') {
            c should not equal firstChar
          }
        }
      }
    }
    

    Annotations
    @Finders()
  39. trait LogicPropSpecLike extends TestSuite with LogicTestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.LogicPropSpec, which is a sister class to org.scalatest.LogicPropSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.LogicPropSpec, which is a sister class to org.scalatest.LogicPropSpec that can pass a fixture object into its tests.

    fixture.LogicPropSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.LogicPropSpec into some other class, you can use this trait instead, because class fixture.LogicPropSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.LogicPropSpec.

    Annotations
    @Finders()
  40. trait LogicTestRegistration extends AnyRef

    Permalink

    Trait declaring methods that can be used to register test functions that accept a fixture parameter and have any result type.

  41. abstract class LogicWordSpec extends LogicWordSpecLike

    Permalink

    A sister class to org.scalatest.LogicWordSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.LogicWordSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.LogicWordSpec in situations for which LogicWordSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.LogicWordSpec is intended for use in special situations, with class LogicWordSpec used for general needs. For more insight into where fixture.LogicWordSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class LogicWordSpec.

    Class fixture.LogicWordSpec behaves similarly to class org.scalatest.LogicWordSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.LogicWordSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.wordspec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.LogicWordSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      "Testing" should {
        "be easy" in { f =>
          f.writer.write("easy!")
          f.writer.flush()
          assert(f.file.length === 18)
        }
    
        "be fun" in { f =>
          f.writer.write("fun!")
          f.writer.flush()
          assert(f.file.length === 17)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.wordspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.LogicWordSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" should {
        "should be easy" in { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
    
        "should be fun" in { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      "Test code" should {
        "should be clear" in { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  42. trait LogicWordSpecLike extends TestSuite with LogicTestRegistration with ShouldVerb with MustVerb with CanVerb with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.LogicWordSpec, which is a sister class to org.scalatest.LogicWordSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.LogicWordSpec, which is a sister class to org.scalatest.LogicWordSpec that can pass a fixture object into its tests.

    fixture.LogicWordSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.LogicWordSpec into some other class, you can use this trait instead, because class fixture.LogicWordSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.LogicWordSpec.

    Annotations
    @Finders()
  43. trait NoArg extends DelayedInit with () ⇒ Unit

    Permalink

    A function that takes no parameters (i.e., a Function0 or "no-arg" function) and results in Unit, which when invoked executes the body of the constructor of the class into which this trait is mixed.

    A function that takes no parameters (i.e., a Function0 or "no-arg" function) and results in Unit, which when invoked executes the body of the constructor of the class into which this trait is mixed.

    This trait extends DelayedInit and defines a delayedInit method that saves the body of the constructor (passed to delayedInit) for later execution when apply is invoked.

    This trait is somewhat magical and therefore may be challenging for your collegues to understand, so please use it as a last resort only when the simpler options described in the "shared fixtures" section of your chosen style trait won't do the job. NoArg is intended to address a specific use case that will likely be rare, and is unlikely to be useful outside of its intended use case, but it is quite handy for its intended use case (described in the next paragraph). One potential gotcha, for example, is that a subclass's constructor body could in theory be executed multiple times by simply invoking apply multiple times. In the intended use case for this trait, however, the body will be executed only once.

    The intended use case for this method is (relatively rare) situations in which you want to extend a different instance of the same class for each test, with the body of the test inheriting the members of that class, and with code executed before and/or after the body of the test.

    For example, Akka's TestKit class takes an ActorSystem, which must have a unique name. To run a suite of tests in parallel, each test must get its own ActorSystem, to ensure the tests run in isolation. At the end of each test, the ActorSystem must be shutdown. With NoArg, you can achieve this by first defining a class that extends TestKit and mixes in NoArg. Here's an example taken with permission from the book Akka Concurrency, by Derek Wyatt:

    import akka.actor.ActorSystem
    import akka.testkit.{TestKit, ImplicitSender}
    import java.util.concurrent.atomic.AtomicInteger
    import org.scalatest.fixture.NoArg
    
    object ActorSys {
      val uniqueId = new AtomicInteger(0)
    }
    
    class ActorSys(name: String) extends
            TestKit(ActorSystem(name))
            with ImplicitSender
            with NoArg {
    
      def this() = this(
        "TestSystem%05d".format(
           ActorSys.uniqueId.getAndIncrement()))
    
      def shutdown(): Unit = system.shutdown()
    
      override def apply() {
        try super.apply()
        finally shutdown()
      }
    }
    

    Given this implementation of ActorSys, which will invoke shutdown after the constructor code is executed, you can run each test in a suite in a subclass of TestKit, giving each test's TestKit an ActorSystem with a unique name, allowing you to safely run those tests in parallel. Here's an example from Akka Concurrency:

    class MyActorSpec extends fixture.WordSpec
            with Matchers
            with UnitFixture
            with ParallelTestExecution {
    
      def makeActor(): ActorRef =
        system.actorOf(Props[MyActor], "MyActor")
    
      "My Actor" should {
        "throw when made with the wrong name" in new ActorSys {
          an [Exception] should be thrownBy {
            // use a generated name
            val a = system.actorOf(Props[MyActor])
          }
        }
        "construct without exception" in new ActorSys {
          val a = makeActor()
          // The throw will cause the test to fail
        }
        "respond with a Pong to a Ping" in new ActorSys {
          val a = makeActor()
          a ! Ping
          expectMsg(Pong)
        }
      }
    }
    

    UnitFixture is used in this example, because in this case, the fixture.WordSpec feature enabling tests to be defined as functions from fixture objects of type FixtureParam to Unit is not being used. Rather, only the secondary feature that enables tests to be defined as functions from no parameters to Unit is being used. This secondary feature is described in the second-to-last paragraph on the main Scaladoc documentation of fixture.WordSpec, which says:

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, ... In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Since FixtureParam is unused in this use case, it could be anything. Making it Unit will hopefully help readers more easily recognize that it is not being used.

    Note: As of Scala 2.11, DelayedInit (which is used by NoArg) has been deprecated, to indicate it is buggy and should be avoided if possible. Those in charge of the Scala compiler and standard library have promised that DelayedInit will not be removed from Scala unless an alternate way to achieve the same goal is provided. Thus it should be safe to use NoArg, but if you'd rather not you can achieve the same effect with a bit more boilerplate by extending (() => Unit) instead of NoArg and placing your code in an explicit body method. Here's an example:

    import akka.actor.ActorSystem
    import akka.testkit.{TestKit, ImplicitSender}
    import java.util.concurrent.atomic.AtomicInteger
    import org.scalatest.fixture.NoArg
    
    object ActorSys {
      val uniqueId = new AtomicInteger(0)
    }
    
    class ActorSys(name: String) extends
            TestKit(ActorSystem(name))
            with ImplicitSender
            with (() => Unit) {
    
      def this() = this(
        "TestSystem%05d".format(
           ActorSys.uniqueId.getAndIncrement()))
    
      def shutdown(): Unit = system.shutdown()
      def body(): Unit
    
      override def apply() = {
        try body()
        finally shutdown()
      }
    }
    

    Using this version of ActorSys will require an explicit body method in the tests:

    class MyActorSpec extends fixture.WordSpec
            with Matchers
            with UnitFixture
            with ParallelTestExecution {
    
      def makeActor(): ActorRef =
        system.actorOf(Props[MyActor], "MyActor")
    
      "My Actor" should {
        "throw when made with the wrong name" in new ActorSys {
          def body() =
            an [Exception] should be thrownBy {
              // use a generated name
              val a = system.actorOf(Props[MyActor])
            }
        }
        "construct without exception" in new ActorSys {
          def body() = {
            val a = makeActor()
            // The throw will cause the test to fail
          }
        }
        "respond with a Pong to a Ping" in new ActorSys {
          def body() = {
            val a = makeActor()
            a ! Ping
            expectMsg(Pong)
          }
        }
      }
    }
    

  44. abstract class PropSpec extends PropSpecLike

    Permalink

    A sister class to org.scalatest.PropSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.PropSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.PropSpec in situations for which PropSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.PropSpec is intended for use in special situations, with class PropSpec used for general needs. For more insight into where fixture.PropSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class PropSpec.

    Class fixture.PropSpec behaves similarly to class org.scalatest.PropSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture, passing in the test code to run via the OneArgTest argument. The withFixture method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.PropSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    Here's an example:

    package org.scalatest.examples.fixture.propspec
    
    import org.scalatest._
    import prop.PropertyChecks
    import java.io._
    
    class ExampleSpec extends fixture.PropSpec with PropertyChecks with Matchers {
    
      // 1. define type FixtureParam
      type FixtureParam = FileReader
    
      // 2. define the withFixture method
      def withFixture(test: OneArgTest) = {
    
        val FileName = "TempFile.txt"
    
        // Set up the temp file needed by the test
        val writer = new FileWriter(FileName)
        try {
          writer.write("Hello, test!")
        }
        finally {
          writer.close()
        }
    
        // Create the reader needed by the test
        val reader = new FileReader(FileName)
    
        try {
          // Run the test using the temp file
          test(reader)
        }
        finally {
          // Close and delete the temp file
          reader.close()
          val file = new File(FileName)
          file.delete()
        }
      }
    
      // 3. write property-based tests that take a fixture parameter
      // (Hopefully less contrived than the examples shown here.)
      property("can read from a temp file") { reader =>
        var builder = new StringBuilder
        var c = reader.read()
        while (c != -1) {
          builder.append(c.toChar)
          c = reader.read()
        }
        val fileContents = builder.toString
        forAll { (c: Char) =>
          whenever (c != 'H') {
            fileContents should not startWith c.toString
          }
        }
      }
    
      property("can read the first char of the temp file") { reader =>
        val firstChar = reader.read()
        forAll { (c: Char) =>
          whenever (c != 'H') {
            c should not equal firstChar
          }
        }
      }
    
      // (You can also write tests that don't take a fixture parameter.)
      property("can write tests that don't take the fixture") { () =>
        forAll { (i: Int) => i + i should equal (2 * i) }
      }
    }
    

    Note: to run the examples on this page, you'll need to include ScalaCheck on the classpath in addition to ScalaTest.

    In the previous example, withFixture creates and initializes a temp file, then invokes the test function, passing in a FileReader connected to that file. In addition to setting up the fixture before a test, the withFixture method also cleans it up afterwards. If you need to do some clean up that must happen even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. The reason you must perform cleanup in a finally clause is that in case an exception propagates back through withFixture, the finally clause will ensure the fixture cleanup happens as that exception propagates back up the call stack to runTest.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function. In other words, instead of starting your function literal with something like “reader =>”, you'd start it with “() =>”, as is done in the third test in the above example. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Passing multiple fixture objects

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(builder: StringBuilder, buffer: ListBuffer[String])
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.fixture.propspec.multi
    
    import org.scalatest._
    import prop.PropertyChecks
    import scala.collection.mutable.ListBuffer
    
    class ExampleSpec extends fixture.PropSpec with PropertyChecks with Matchers {
    
      case class FixtureParam(builder: StringBuilder, buffer: ListBuffer[String])
    
      def withFixture(test: OneArgTest) = {
    
        // Create needed mutable objects
        val stringBuilder = new StringBuilder("ScalaTest is ")
        val listBuffer = new ListBuffer[String]
        val theFixture = FixtureParam(stringBuilder, listBuffer)
    
        // Invoke the test function, passing in the mutable objects
        withFixture(test.toNoArgTest(theFixture))
      }
    
      property("testing should be easy") { f =>
        f.builder.append("easy!")
        assert(f.builder.toString === "ScalaTest is easy!")
        assert(f.buffer.isEmpty)
        val firstChar = f.builder(0)
        forAll { (c: Char) =>
          whenever (c != 'S') {
            c should not equal firstChar
          }
        }
        f.buffer += "sweet"
      }
    
      property("testing should be fun") { f =>
        f.builder.append("fun!")
        assert(f.builder.toString === "ScalaTest is fun!")
        assert(f.buffer.isEmpty)
        val firstChar = f.builder(0)
        forAll { (c: Char) =>
          whenever (c != 'S') {
            c should not equal firstChar
          }
        }
      }
    }
    

    Annotations
    @Finders()
  45. trait PropSpecLike extends TestSuite with TestRegistration with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.PropSpec, which is a sister class to org.scalatest.PropSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.PropSpec, which is a sister class to org.scalatest.PropSpec that can pass a fixture object into its tests.

    fixture.PropSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.PropSpec into some other class, you can use this trait instead, because class fixture.PropSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.PropSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()
  46. trait Suite extends scalatest.Suite

    Permalink

    Base trait for a family of style traits that can pass a fixture object into tests.

  47. trait TestDataFixture extends AnyRef

    Permalink

    Trait that when mixed into a fixture.Suite passes the TestData passed to withFixture as a fixture into each test.

    Trait that when mixed into a fixture.Suite passes the TestData passed to withFixture as a fixture into each test.

    For example, here's how you could access the test's name in each test using TestDataFixture:

    package org.scalatest.examples.fixture.testdatafixture
    
    import org.scalatest._
    
    class ExampleSpec extends fixture.FlatSpec with fixture.TestDataFixture {
    
      "Accessing the test data" should "be easy!" in { td =>
        assert(td.name == "Accessing the test data should be easy!")
      }
    
      it should "be fun!" in { td =>
        assert(td.name == "Accessing the test data should be fun!")
      }
    }
    

  48. trait TestRegistration extends AnyRef

    Permalink

    Trait declaring methods that can be used to register test functions that accept a fixture parameter and have any result type.

  49. trait TestSuite extends Suite with scalatest.TestSuite

    Permalink
  50. trait UnitFixture extends AnyRef

    Permalink

    Trait that when mixed into a fixture.Suite passes the unit value as a fixture into each test.

    Trait that when mixed into a fixture.Suite passes the unit value as a fixture into each test.

    Since a unit value is unlikely to be of much use to a test, this trait is useful when the unit value fixture is actually never passed into any tests. Instead each test in the fixture.Suite is defined as a no-arg function; no tests are defined as one-arg functions. This should be quite rare, but occasionally can be useful. For an example, see the main documentation for trait NoArg.

  51. abstract class WordSpec extends WordSpecLike

    Permalink

    A sister class to org.scalatest.WordSpec that can pass a fixture object into its tests.

    A sister class to org.scalatest.WordSpec that can pass a fixture object into its tests.

    Recommended Usage: Use class fixture.WordSpec in situations for which WordSpec would be a good choice, when all or most tests need the same fixture objects that must be cleaned up afterwards. Note: fixture.WordSpec is intended for use in special situations, with class WordSpec used for general needs. For more insight into where fixture.WordSpec fits in the big picture, see the withFixture(OneArgTest) subsection of the Shared fixtures section in the documentation for class WordSpec.

    Class fixture.WordSpec behaves similarly to class org.scalatest.WordSpec, except that tests may have a fixture parameter. The type of the fixture parameter is defined by the abstract FixtureParam type, which is a member of this class. This class also has an abstract withFixture method. This withFixture method takes a OneArgTest, which is a nested trait defined as a member of this class. OneArgTest has an apply method that takes a FixtureParam. This apply method is responsible for running a test. This class's runTest method delegates the actual running of each test to withFixture(OneArgTest), passing in the test code to run via the OneArgTest argument. The withFixture(OneArgTest) method (abstract in this class) is responsible for creating the fixture argument and passing it to the test function.

    Subclasses of this class must, therefore, do three things differently from a plain old org.scalatest.WordSpec:

    • define the type of the fixture parameter by specifying type FixtureParam
    • define the withFixture(OneArgTest) method
    • write tests that take a fixture parameter
    • (You can also define tests that don't take a fixture parameter.)

    If the fixture you want to pass into your tests consists of multiple objects, you will need to combine them into one object to use this class. One good approach to passing multiple fixture objects is to encapsulate them in a case class. Here's an example:

    case class FixtureParam(file: File, writer: FileWriter)
    

    To enable the stacking of traits that define withFixture(NoArgTest), it is a good idea to let withFixture(NoArgTest) invoke the test function instead of invoking the test function directly. To do so, you'll need to convert the OneArgTest to a NoArgTest. You can do that by passing the fixture object to the toNoArgTest method of OneArgTest. In other words, instead of writing “test(theFixture)”, you'd delegate responsibility for invoking the test function to the withFixture(NoArgTest) method of the same instance by writing:

    withFixture(test.toNoArgTest(theFixture))
    

    Here's a complete example:

    package org.scalatest.examples.wordspec.oneargtest
    
    import org.scalatest.fixture
    import java.io._
    
    class ExampleSpec extends fixture.WordSpec {
    
      case class FixtureParam(file: File, writer: FileWriter)
    
      def withFixture(test: OneArgTest) = {
    
        // create the fixture
        val file = File.createTempFile("hello", "world")
        val writer = new FileWriter(file)
        val theFixture = FixtureParam(file, writer)
    
        try {
          writer.write("ScalaTest is ") // set up the fixture
          withFixture(test.toNoArgTest(theFixture)) // "loan" the fixture to the test
        }
        finally writer.close() // clean up the fixture
      }
    
      "Testing" should {
        "be easy" in { f =>
          f.writer.write("easy!")
          f.writer.flush()
          assert(f.file.length === 18)
        }
    
        "be fun" in { f =>
          f.writer.write("fun!")
          f.writer.flush()
          assert(f.file.length === 17)
        }
      }
    }
    

    If a test fails, the OneArgTest function will result in a Failed wrapping the exception describing the failure. To ensure clean up happens even if a test fails, you should invoke the test function from inside a try block and do the cleanup in a finally clause, as shown in the previous example.

    Sharing fixtures across classes

    If multiple test classes need the same fixture, you can define the FixtureParam and withFixture(OneArgTest) implementations in a trait, then mix that trait into the test classes that need it. For example, if your application requires a database and your integration tests use that database, you will likely have many test classes that need a database fixture. You can create a "database fixture" trait that creates a database with a unique name, passes the connector into the test, then removes the database once the test completes. This is shown in the following example:

    package org.scalatest.examples.fixture.wordspec.sharing
    
    import java.util.concurrent.ConcurrentHashMap
    import org.scalatest.fixture
    import DbServer._
    import java.util.UUID.randomUUID
    
    object DbServer { // Simulating a database server
      type Db = StringBuffer
      private val databases = new ConcurrentHashMap[String, Db]
      def createDb(name: String): Db = {
        val db = new StringBuffer
        databases.put(name, db)
        db
      }
      def removeDb(name: String) {
        databases.remove(name)
      }
    }
    
    trait DbFixture { this: fixture.Suite =>
    
      type FixtureParam = Db
    
      // Allow clients to populate the database after
      // it is created
      def populateDb(db: Db) {}
    
      def withFixture(test: OneArgTest) = {
        val dbName = randomUUID.toString
        val db = createDb(dbName) // create the fixture
        try {
          populateDb(db) // setup the fixture
          withFixture(test.toNoArgTest(db)) // "loan" the fixture to the test
        }
        finally removeDb(dbName) // clean up the fixture
      }
    }
    
    class ExampleSpec extends fixture.WordSpec with DbFixture {
    
      override def populateDb(db: Db) { // setup the fixture
        db.append("ScalaTest is ")
      }
    
      "Testing" should {
        "should be easy" in { db =>
          db.append("easy!")
          assert(db.toString === "ScalaTest is easy!")
        }
    
        "should be fun" in { db =>
          db.append("fun!")
          assert(db.toString === "ScalaTest is fun!")
        }
      }
    
      // This test doesn't need a Db
      "Test code" should {
        "should be clear" in { () =>
          val buf = new StringBuffer
          buf.append("ScalaTest code is ")
          buf.append("clear!")
          assert(buf.toString === "ScalaTest code is clear!")
        }
      }
    }
    

    Often when you create fixtures in a trait like DbFixture, you'll still need to enable individual test classes to "setup" a newly created fixture before it gets passed into the tests. A good way to accomplish this is to pass the newly created fixture into a setup method, like populateDb in the previous example, before passing it to the test function. Classes that need to perform such setup can override the method, as does ExampleSpec.

    If a test doesn't need the fixture, you can indicate that by providing a no-arg instead of a one-arg function, as is done in the third test in the previous example, “Test code should be clear”. In other words, instead of starting your function literal with something like “db =>”, you'd start it with “() =>”. For such tests, runTest will not invoke withFixture(OneArgTest). It will instead directly invoke withFixture(NoArgTest).

    Both examples shown above demonstrate the technique of giving each test its own "fixture sandbox" to play in. When your fixtures involve external side-effects, like creating files or databases, it is a good idea to give each file or database a unique name as is done in these examples. This keeps tests completely isolated, allowing you to run them in parallel if desired. You could mix ParallelTestExecution into either of these ExampleSpec classes, and the tests would run in parallel just fine.

    Annotations
    @Finders()
  52. trait WordSpecLike extends TestSuite with TestRegistration with ShouldVerb with MustVerb with CanVerb with Informing with Notifying with Alerting with Documenting

    Permalink

    Implementation trait for class fixture.WordSpec, which is a sister class to org.scalatest.WordSpec that can pass a fixture object into its tests.

    Implementation trait for class fixture.WordSpec, which is a sister class to org.scalatest.WordSpec that can pass a fixture object into its tests.

    fixture.WordSpec is a class, not a trait, to minimize compile time given there is a slight compiler overhead to mixing in traits compared to extending classes. If you need to mix the behavior of fixture.WordSpec into some other class, you can use this trait instead, because class fixture.WordSpec does nothing more than extend this trait and add a nice toString implementation.

    See the documentation of the class for a detailed overview of fixture.WordSpec.

    Annotations
    @EnableReflectiveInstantiation() @Finders()

Ungrouped