org.scalatest.OneInstancePerTest.scala Maven / Gradle / Ivy
Show all versions of scalatest_2.8.0 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.
*
*
* @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 Suites to be run
* by another entity, such as concurrently by a pool of threads. If None, nested Suites will be run sequentially.
* @param tracker a Tracker tracking Ordinals 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]
}