org.scalatest.OneInstancePerTest.scala Maven / Gradle / Ivy
Show all versions of scalatest_2.11.0-M3 Show documentation
/*
* Copyright 2001-2009 Artima, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.scalatest
/**
* Trait that facilitates a style of testing in which each test is run in its own instance
* of the suite class to isolate each test from the side effects of the other tests in the
* suite.
*
*
* If you mix this trait into a Suite
, you can initialize shared reassignable
* fixture variables as well as shared mutable fixture objects in the constructor of the
* class. Because each test will run in its own instance of the class, each test will
* get a fresh copy of the instance variables. This is the approach to test isolation taken,
* for example, by the JUnit framework.
*
*
*
* Here's an example of OneInstancePerTest
being used in a FunSuite
:
*
*
*
* import org.scalatest.FunSuite
* import org.scalatest.OneInstancePerTest
* import collection.mutable.ListBuffer
*
* class MySuite extends FunSuite with OneInstancePerTest {
*
* val builder = new StringBuilder("ScalaTest is ")
* val buffer = new ListBuffer[String]
*
* test("easy") {
* builder.append("easy!")
* assert(builder.toString === "ScalaTest is easy!")
* assert(buffer.isEmpty)
* buffer += "sweet"
* }
*
* test("fun") {
* builder.append("fun!")
* assert(builder.toString === "ScalaTest is fun!")
* assert(buffer.isEmpty)
* }
* }
*
*
* @author Bill Venners
*/
trait OneInstancePerTest extends AbstractSuite {
this: Suite =>
/**
* Run this Suite's
tests each in their own instance of this Suite
's class.
*
*
* If the passed testName
is None
, this trait's implementation of this
* method will for each test name returned by testNames
, invoke newInstance
* to get a new instance of this Suite
, and call run
on it, passing
* in the test name wrapped in a Some
. If the passed testName
is defined,
* this trait's implementation of this method will simply forward all passed parameters
* to super.run
. If the invocation of either newInstance
on this
* Suite
or run
on a newly created instance of this Suite
* completes abruptly with an exception, then this runTests
method will complete
* abruptly with the same exception.
*
*
* @param testName an optional name of one test to run. If None
, all relevant tests should be run.
* I.e., None
acts like a wildcard that means run all relevant tests in this Suite
.
* @param reporter the Reporter
to which results will be reported
* @param stopper the Stopper
that will be consulted to determine whether to stop execution early.
* @param filter a Filter
with which to filter tests based on their tags
* @param configMap a Map
of key-value pairs that can be used by the executing Suite
of tests.
* @param distributor an optional Distributor
, into which to put nested Suite
s to be run
* by another entity, such as concurrently by a pool of threads. If None
, nested Suite
s will be run sequentially.
* @param tracker a Tracker
tracking Ordinal
s being fired by the current thread.
* @throws NullPointerException if any of the passed parameters is null
.
* @throws IllegalArgumentException if testName
is defined, but no test with the specified test name
* exists in this Suite
*/
protected abstract override def runTests(testName: Option[String], reporter: Reporter, stopper: Stopper, filter: Filter,
configMap: Map[String, Any], distributor: Option[Distributor], tracker: Tracker) {
testName match {
case Some(tn) => super.runTests(testName, reporter, stopper, filter, configMap, None, tracker)
case None =>
for (tn <- testNames) {
val oneInstance = newInstance
oneInstance.run(Some(tn), reporter, stopper, filter, configMap, None, tracker)
}
}
}
/**
* Construct a new instance of this Suite
.
*
*
* This trait's implementation of runTests
invokes this method to create
* a new instance of this Suite
for each test. This trait's implementation
* of this method uses reflection to call this.getClass.newInstance
. This
* approach will succeed only if this Suite
's class has a public, no-arg
* constructor. In most cases this is likely to be true, because to be instantiated
* by ScalaTest's Runner
a Suite
needs a public, no-arg
* constructor. However, this will not be true of any Suite
defined as
* an inner class of another class or trait, because every constructor of an inner
* class type takes a reference to the enclosing instance. In such cases, and in
* cases where a Suite
class is explicitly defined without a public,
* no-arg constructor, you will need to override this method to construct a new
* instance of the Suite
in some other way.
*
*
*
* Here's an example of how you could override newInstance
to construct
* a new instance of an inner class:
*
*
*
* import org.scalatest.Suite
*
* class Outer {
* class InnerSuite extends Suite with OneInstancePerTest {
* def testOne() {}
* def testTwo() {}
* override def newInstance = new InnerSuite
* }
* }
*
*/
def newInstance = this.getClass.newInstance.asInstanceOf[Suite]
}