001: /*
002: * Copyright 2006-2007, Unitils.org
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.unitils;
017:
018: import org.testng.IHookCallBack;
019: import org.testng.IHookable;
020: import org.testng.ITestResult;
021: import org.testng.annotations.*;
022: import org.unitils.core.TestListener;
023: import org.unitils.core.Unitils;
024:
025: /**
026: * Base test class that will Unitils-enable your test. This base class will make sure that the
027: * core unitils test listener methods are invoked in the expected order. See {@link TestListener} for
028: * more information on the listener invocation order.
029: *
030: * @author Tim Ducheyne
031: * @author Filip Neven
032: */
033: public abstract class UnitilsTestNG implements IHookable {
034:
035: /* The main test listener, that hooks this test into unitils */
036: private static TestListener testListener;
037:
038: /* True if beforeTestClass was called */
039: private static boolean beforeTestClassCalled = false;
040:
041: /* True if beforeTestSetUp was called */
042: private static boolean beforeTestSetUpCalled = false;
043:
044: /**
045: * Called at the beginning of the test run. This will initialize unitils and the test listener
046: * and call {@link TestListener#beforeAll}.
047: */
048: @BeforeSuite(alwaysRun=true)
049: protected void unitilsBeforeSuite() {
050: testListener = getUnitils().createTestListener();
051: testListener.beforeAll();
052: }
053:
054: /**
055: * Called at the end of the test run. This is where {@link TestListener#afterAll} is called.
056: */
057: @AfterSuite(alwaysRun=true)
058: protected void unitilsAfterSuite() {
059: testListener.afterAll();
060: }
061:
062: /**
063: * Called before a test of a test class is run. This is where {@link TestListener#beforeTestClass} is called.
064: */
065: @BeforeClass(alwaysRun=true)
066: protected void unitilsBeforeClass() {
067: beforeTestClassCalled = true;
068: testListener.beforeTestClass(getClass());
069: }
070:
071: /**
072: * Called after all tests of a test class were run. This is where {@link TestListener#afterTestClass} is called.
073: * <p/>
074: * NOTE: alwaysRun is enabled to be sure that this method is called even when an exception occurs during
075: * {@link #unitilsBeforeClass}.
076: */
077: @AfterClass(alwaysRun=true)
078: protected void unitilsAfterClass() {
079: // alwaysRun is enaled, extra test to ensure that unitilsBeforeClass was called
080: if (beforeTestClassCalled) {
081: beforeTestClassCalled = false;
082: testListener.afterTestClass(getClass());
083: }
084: }
085:
086: /**
087: * Called before all test setup. This is where {@link TestListener#beforeTestSetUp} is called.
088: */
089: @BeforeMethod(alwaysRun=true)
090: protected void unitilsBeforeTestSetUp() {
091: beforeTestSetUpCalled = true;
092: testListener.beforeTestSetUp(this );
093: }
094:
095: /**
096: * Called after all test tear down. This is where {@link TestListener#afterTestTearDown} is called.
097: * <p/>
098: * NOTE: alwaysRun is enabled to be sure that this method is called even when an exception occurs during
099: * {@link #unitilsBeforeTestSetUp}.
100: */
101: @AfterMethod(alwaysRun=true)
102: protected void unitilsAfterTestTearDown() {
103: // alwaysRun is enaled, extra test to ensure that unitilsBeforeTestSetUp was called
104: if (beforeTestSetUpCalled) {
105: beforeTestSetUpCalled = false;
106: testListener.afterTestTearDown(this );
107: }
108: }
109:
110: /**
111: * Implementation of the hookable interface to be able to call {@link TestListener#beforeTestMethod} and
112: * {@link TestListener#afterTestMethod}.
113: *
114: * @param callBack the TestNG test callback, not null
115: * @param testResult the TestNG test result, not null
116: */
117: public void run(IHookCallBack callBack, ITestResult testResult) {
118: RuntimeException firstRuntimeException = null;
119: try {
120: testListener.beforeTestMethod(this , testResult.getMethod()
121: .getMethod());
122: callBack.runTestMethod(testResult);
123:
124: } catch (RuntimeException e) {
125: // hold exception until later, first call afterTestMethod
126: firstRuntimeException = e;
127: }
128:
129: try {
130: testListener.afterTestMethod(this , testResult.getMethod()
131: .getMethod(), firstRuntimeException);
132:
133: } catch (RuntimeException e) {
134: // first exception is typically the most meaningful, so ignore second exception
135: if (firstRuntimeException == null) {
136: firstRuntimeException = e;
137: }
138: }
139:
140: // if there were exceptions, throw the first one
141: if (firstRuntimeException != null) {
142: throw firstRuntimeException;
143: }
144: }
145:
146: /**
147: * This will return the default singleton instance by calling {@link Unitils#getInstance()}.
148: * <p/>
149: * You can override this method to let it create and set your own singleton instance. For example, you
150: * can let it create an instance of your own Unitils subclass and set it by using {@link Unitils#setInstance}.
151: *
152: * @return the unitils core instance, not null
153: */
154: protected Unitils getUnitils() {
155: return Unitils.getInstance();
156: }
157:
158: }
|