org.scalatest.BeforeAndAfterAll.scala Maven / Gradle / Ivy
Show all versions of scalatest_2.9.3 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. * *also completes abruptly with an exception, this * method will nevertheless complete abruptly with the exception previously thrown by* 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
* *runand calls the *beforeAllmethod, then callssuper.run. After thesuper.run* invocation completes, whether it returns normally or completes abruptly with an exception, * this trait'srunmethod will invokeafterAll. ** Trait
* *BeforeAndAfterAlldefines two overloaded variants each ofbeforeAll* andafterAll, one that takes aconfigMapand another that takes no * arguments. This trait's 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 theconfigMapbefore * all tests and nested suites are run, overridebeforeAll(Map[String, Any]). Otherwise, * overridebeforeAll(). ** For example, the following
* *ExampleSpecmixes inBeforeAndAfterAlland * inbeforeAll, creates and writes to a temp file, taking the name of the temp file * from theconfigMap. This sameconfigMapis then passed to therun* methods of the nested suites,OneSpec,TwoSpec,RedSpec, * andBlueSpec, so those suites can access the filename and, therefore, the file's * contents. After all of the nested suites have executed,afterAllis invoked, which * again grabs the file name from theconfigMapand deletes the file. Each of these five * test classes extend traitTempFileExistsSpec, which defines a test that ensures the temp file exists. * (Note: if you're unfamiliar with thewithFixture(OneArgTest)approach to shared fixtures, check out * the documentation for traitfixture.FlatSpec.) ** package org.scalatest.examples.beforeandafterall * * import org.scalatest._ * import java.io._ * * trait TempFileExistsSpec extends fixture.FlatSpec { * * type FixtureParam = File * override def withFixture(test: OneArgTest) { * val fileName = test.configMap("tempFileName").asInstanceOf[String] * val file = new File(fileName) * withFixture(test.toNoArgTest(file)) // loan the fixture to the test * } * * "The temp file" should ("exist in " + suiteName) in { file => * assert(file.exists) * } * } * * class OneSpec extends TempFileExistsSpec * class TwoSpec extends TempFileExistsSpec * class RedSpec extends TempFileExistsSpec * class BlueSpec extends TempFileExistsSpec * * class ExampleSpec extends Specs( * new OneSpec, * new TwoSpec, * new RedSpec, * new BlueSpec * ) with TempFileExistsSpec with BeforeAndAfterAll { * * private val tempFileName = "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(tempFileName), * "must place a temp file name in the configMap under the key: " + tempFileName * ) * * val fileName = configMap(tempFileName).asInstanceOf[String] * * val writer = new FileWriter(fileName) * try writer.write("Hello, suite of tests!") * finally writer.close() * } * * // 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").asInstanceOf[String] * val file = new File(fileName) * file.delete() * } * } ** ** Running the above class in the interpreter will give an error if you don't supply a mapping for
* *"tempFileName"in the config map: ** scala> new ExampleSpec execute * ExampleSpec: * Exception encountered when invoking run on a suite. *** ABORTED *** * java.lang.IllegalArgumentException: requirement failed: must place a temp file name in the configMap under the key: tempFileName * ... * *** RUN ABORTED *** * java.lang.IllegalArgumentException: requirement failed: must place a temp file name in the configMap under the key: tempFileName * ... ** ** If you do supply a mapping for
* *"tempFileName"in the config map, you'll see that the temp file is available to all the tests: ** scala> new ExampleSpec execute (configMap = Map("tempFileName" -> "tmp.txt")) * ExampleSpec: * OneSpec: * The temp file * - should exist in OneSpec * TwoSpec: * The temp file * - should exist in TwoSpec * RedSpec: * The temp file * - should exist in RedSpec * BlueSpec: * The temp file * - should exist in BlueSpec * The temp file * - should exist in ExampleSpec ** ** Note: This trait does not currently ensure that the code in
* * @author Bill Venners */ trait BeforeAndAfterAll extends SuiteMixin { this: Suite => /** * Defines a method to be run before any of this suite's tests or nested suites are run. * *afterAllis executed after * all the tests and nested suites are executed if aDistributoris passed. The * plan is to do that eventually (in fact, in a soon-to-be-released 2.0 milestone), but in the meantime, be aware thatafterAllis * guaranteed to be run after all the tests and nested suites only when they are run * sequentially. ** This trait's implementation * of
*/ protected def beforeAll() = () /** * Defines a method (that takes aruninvokes the overloaded form of this method that * takes aconfigMapbefore 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. * *runinvokes this method before executing * any tests or nested suites (passing in theconfigMappassed 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 ofbeforeAllthat takes noconfigMap. ** This trait's implementation * of
*/ protected def afterAll() = () /** * Defines a method (that takes aruninvokes the overloaded form of this method that * takes aconfigMapafter 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 toruninvokes this method after executing all tests * and nested suites (passing in theconfigMappassed 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 ofafterAllthat takes noconfigMap. *beforeAllandafterAll. * ** 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
beforeAllcompletes abruptly with an exception, this * method will complete abruptly with the same exception. If any call to *super.runcompletes abruptly with an exception, this method * will complete abruptly with the same exception, however, before doing so, it will * invokeafterAll. IfafterAll super.run. * Ifsuper.runreturns normally, butafterAllcompletes abruptly with an * exception, this method will complete abruptly with the same exception. * * * @param testName an optional name of one test to run. IfNone, all relevant tests should be run. * I.e.,Noneacts like a wildcard that means run all relevant tests in thisSuite. * @param args theArgsfor this run * @return aStatusobject that indicates when the test started by this method has completed, and whether or not it failed . */ abstract override def run(testName: Option[String], args: Args): Status = { var thrownException: Option[Throwable] = None beforeAll(args.configMap) try { val runStatus = super.run(testName, args) runStatus.succeeds() runStatus } catch { case e: Exception => thrownException = Some(e) FailedStatus } finally { try { afterAll(args.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 } } } } }