org.scalatest.BeforeAndAfterAll.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 can be mixed into suites that need methods invoked before and after executing the * suite. This trait allows code to be executed before and/or after all the tests and nested suites of a * suite are run. This trait overrides
FunSuite: * *run
(the mainrun
method that * takes seven parameters, an optional test name, reporter, stopper, filter, configMap, optional distributor, * and tracker) and calls the *beforeAll
method, then callssuper.run
. After thesuper.run
* invocation completes, whether it returns normally or completes abruptly with an exception, * this trait'srun
method will invokeafterAll
. * ** Trait
* *BeforeAndAfterAll
defines two overloaded variants each ofbeforeAll
* andafterAll
, one that takes aconfigMap
and another that takes no * arguments. This traits implemention of the variant that takes theconfigMap
* simply invokes the variant that takes no parameters, which does nothing. Thus you can override * whichever variant you want. If you need something from theconfigMap
before * all tests and nested suites are run, overridebeforeAll(Map[String, Any])
. Otherwise, * overridebeforeAll()
. ** For example, the following
* *MasterSuite
mixes inBeforeAndAfterAll
and * inbeforeAll
, creates and writes to a temp file, taking the name of the temp file * from theconfigMap
. This sameconfigMap
is then passed to therun
* methods of the nested suites,OneSuite
,TwoSuite
,RedSuite
, * andBlueSuite
, so those suites can access the filename and, therefore, the file's * contents. After all of the nested suites have executed,afterAll
is invoked, which * again grabs the file name from theconfigMap
and deletes the file: ** import org.scalatest.SuperSuite * import org.scalatest.BeforeAndAfterAll * import java.io.FileReader * import java.io.FileWriter * import java.io.File * * class MasterSuite extends Suite with BeforeAndAfterAll { * * private val FileNameKeyInGoodies = "tempFileName" * * // Set up the temp file needed by the test, taking * // a file name from the configMap * override def beforeAll(configMap: Map[String, Any]) { * * require( * configMap.isDefinedAt(FileNameKeyInGoodies), * "must place a temp file name in the configMap under the key: " + FileNameKeyInGoodies * ) * * val fileName = configMap(tempFileName) * * val writer = new FileWriter(fileName) * try { * writer.write("Hello, suite of tests!") * } * finally { * writer.close() * } * } * * override def nestedSuites = * List(new OneSuite, new TwoSuite, new RedSuite, new BlueSuite) * * // Delete the temp file * override def afterAll(configMap: Map[String, Any]) { * // No need to require that configMap contains the key again because it won't get * // here if it didn't contain the key in beforeAll * val fileName = configMap(tempFileName)) * val file = new File(fileName) * file.delete() * } * } ** ** Because the
BeforeAndAfterAll
trait invokessuper.run
to run the suite, you may need to * mix this trait in last to get the desired behavior. For example, this won't * work, becauseBeforeAndAfterAll
is "super" to* class MySuite extends BeforeAndAfterAll with FunSuite *** You'd need to turn it around, so that
*FunSuite
is "super" toBeforeAndAfterAll
, like this: ** class MySuite extends FunSuite with BeforeAndAfterAll ** * Note: This trait does not currently ensure that the code inafterAll
is executed after * all the tests and nested suites are executed if aDistributor
is passed. The * plan is to do that eventually, but in the meantime, be aware thatafterAll
is * guaranteed to be run after all the tests and nested suites only when they are run * sequentially. * * @author Bill Venners */ trait BeforeAndAfterAll extends AbstractSuite { this: Suite => /** * Defines a method to be run before any of this suite's tests or nested suites are run. * ** This trait's implementation * of
*/ protected def beforeAll() = () /** * Defines a method (that takes arun
invokes the overloaded form of this method that * takes aconfigMap
before executing * any tests or nested suites. This trait's implementation of thatbeforeAll(Map[String, Any])
* method simply invokes thisbeforeAll()
* method. Thus this method can be used to set up a test fixture * needed by the entire suite, when you don't need anything from theconfigMap
. * This trait's implementation of this method does nothing. *configMap
) to be run before any * of this suite's tests or nested suites are run. * ** This trait's implementation * of
*/ protected def beforeAll(configMap: Map[String, Any]) { beforeAll() } /** * Defines a method to be run after all of this suite's tests and nested suites have * been run. * *run
invokes this method before executing * any tests or nested suites (passing in theconfigMap
passed to it), thus this * method can be used to set up a test fixture * needed by the entire suite. This trait's implementation of this method invokes the * overloaded form ofbeforeAll
that takes noconfigMap
. ** This trait's implementation * of
*/ protected def afterAll() = () /** * Defines a method (that takes arun
invokes the overloaded form of this method that * takes aconfigMap
after executing * all tests and nested suites. This trait's implementation of thatafterAll(Map[String, Any])
method simply invokes this *afterAll()
method. Thus this method can be used to tear down a test fixture * needed by the entire suite, when you don't need anything from theconfigMap
. * This trait's implementation of this method does nothing. *configMap
) to be run after * all of this suite's tests and nested suites have been run. * ** This trait's implementation * of
*/ protected def afterAll(configMap: Map[String, Any]) { afterAll() } /** * Execute a suite surrounded by calls torun
invokes this method after executing all tests * and nested suites (passing in theconfigMap
passed to it), thus this * method can be used to tear down a test fixture * needed by the entire suite. This trait's implementation of this method invokes the * overloaded form ofafterAll
that takes noconfigMap
. *beforeAll
andafterAll
. * ** This trait's implementation of this method ("this method") invokes
* *beforeAll(Map[String, Any])
* before executing any tests or nested suites andafterAll(Map[String, Any])
* after executing all tests and nested suites. It runs the suite by invokingsuper.run
, passing along * the seven parameters passed to it. ** If any invocation of
*/ abstract override def run(testName: Option[String], reporter: Reporter, stopper: Stopper, filter: Filter, configMap: Map[String, Any], distributor: Option[Distributor], tracker: Tracker) { var thrownException: Option[Throwable] = None beforeAll(configMap) try { super.run(testName, reporter, stopper, filter, configMap, distributor, tracker) } catch { case e: Exception => thrownException = Some(e) } finally { try { afterAll(configMap) // Make sure that afterAll is called even if run completes abruptly. thrownException match { case Some(e) => throw e case None => } } catch { case laterException: Exception => thrownException match { // If both run and afterAll throw an exception, report the test exception case Some(earlierException) => throw earlierException case None => throw laterException } } } } }beforeAll
completes abruptly with an exception, this * method will complete abruptly with the same exception. If any call to *super.run
completes abruptly with an exception, this method * will complete abruptly with the same exception, however, before doing so, it will * invokeafterAll
. IfafterAll also completes abruptly with an exception, this * method will nevertheless complete abruptly with the exception previously thrown by super.run
. * Ifsuper.run
returns normally, butafterAll
completes abruptly with an * exception, this method will complete abruptly with the same exception. *