Source Code Cross Referenced for WebtestTask.java in  » Testing » webtest » com » canoo » webtest » ant » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » webtest » com.canoo.webtest.ant 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright © 2002-2007 Canoo Engineering AG, Switzerland.
002:        package com.canoo.webtest.ant;
003:
004:        import java.util.HashMap;
005:        import java.util.Iterator;
006:        import java.util.Map;
007:
008:        import org.apache.commons.lang.StringUtils;
009:        import org.apache.log4j.Logger;
010:        import org.apache.tools.ant.BuildException;
011:        import org.apache.tools.ant.PropertyHelper;
012:        import org.apache.tools.ant.Task;
013:        import org.apache.tools.ant.TaskContainer;
014:        import org.apache.tools.ant.UnsupportedElementException;
015:
016:        import com.canoo.webtest.boundary.PackageBoundary;
017:        import com.canoo.webtest.engine.Configuration;
018:        import com.canoo.webtest.engine.Context;
019:        import com.canoo.webtest.engine.WebClientContext;
020:        import com.canoo.webtest.interfaces.IPropertyHandler;
021:        import com.canoo.webtest.reporting.IResultReporter;
022:        import com.canoo.webtest.reporting.PlainTextReporter;
023:        import com.canoo.webtest.reporting.RootStepResult;
024:        import com.canoo.webtest.reporting.StepExecutionListener;
025:
026:        /**
027:         * Ant task that specifies a Web Test Sequence.
028:         *
029:         * @author Unknown
030:         * @author Marc Guillemot
031:         * @webtest.step
032:         *   category="General"
033:         *   name="webtest"
034:         *   alias="testSpec"
035:         *   description="This <key>ANT</key> task provides the ability to specify
036:         *   and execute functional tests for web-based applications.
037:         *   The steps of the test specification to execute are defined as a sequence
038:         *   of nested test steps.
039:         *   Each <em><webtest></em> task is executed in its own web session,
040:         *   i.e. two subsequent <em><webtest></em> tasks are executed in different sessions.
041:         *   This task was previously named \"testSpec\". For compatibility reasons, both names will work."
042:         */
043:        public class WebtestTask extends Task implements  TaskContainer,
044:                IPropertyHandler {
045:            private static final Logger LOG = Logger
046:                    .getLogger(WebtestTask.class);
047:            private String fName;
048:            private Configuration fConfig;
049:            private TestStepSequence fSteps;
050:            private boolean fImplicitSteps = true; // indicates that <steps> has been ommitted
051:            public static final String REPORTER_CLASSNAME_PROPERTY = "webtest.resultreporterclass";
052:            public static final String DEFAULT_REPORTER_CLASSNAME = "com.canoo.webtest.reporting.XmlReporter";
053:            private final Map fDynamicProperties = new HashMap();
054:            private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal();
055:
056:            /**
057:             * Gets the context to use for this thread.
058:             * In a normal execution, this is the one that is created at the beginning of &lt;webtest&gt;
059:             * and which should be used by all the steps from this webtest. These tests may
060:             * be nested within macros, external targets, ... and may not "see" the &lt;webtest&gt; directly.<br/>
061:             * A step doesn't need to call this method as it can access the context through {@link com.canoo.webtest.steps.Step#getContext()}.
062:             * @return the currently used context, <code>null</code> if not inside the execution of a webtest.
063:             */
064:            public static Context getThreadContext() {
065:                return (Context) CONTEXT_HOLDER.get();
066:            }
067:
068:            /**
069:             * Sets the context for this thread. 
070:             * Normally this method should not be public and only the webtest should use it.
071:             *  Its visibility will be restricted once the unit tests have been adapted.
072:             * @param context the context to set
073:             */
074:            public static void setThreadContext(final Context context) {
075:                CONTEXT_HOLDER.set(context);
076:            }
077:
078:            public void setDynamicProperty(final String name, final String value) {
079:                fDynamicProperties.put(name, value);
080:            }
081:
082:            public String getDynamicProperty(final String name) {
083:                return (String) fDynamicProperties.get(name);
084:            }
085:
086:            public Map getDynamicProperties() {
087:                return fDynamicProperties;
088:            }
089:
090:            /**
091:             * Called by ant to add the nested "configuration ..." task.
092:             *
093:             * @param config the configuration task
094:             * @webtest.nested.parameter
095:             * required="no"
096:             * description="The webtest configuration."
097:             */
098:            public void addConfig(final Configuration config) {
099:                if (fSteps != null) {
100:                    final String msg = config.getTaskName()
101:                            + " invalid at this position! "
102:                            + "It has to be the first node of \""
103:                            + getTaskName() + "\"!";
104:                    throw new UnsupportedElementException(msg, config
105:                            .getTaskName());
106:                }
107:                fConfig = config;
108:                fConfig.setPropertyHandler(this );
109:            }
110:
111:            /**
112:             * In a first time doesn't support other tasks as config and testSpec, but
113:             * this class has to implement {@link TaskContainer} to work with Groovy's AntBuilder
114:             * (a bug in this AntBuilder?)
115:             * @see org.apache.tools.ant.TaskContainer#addTask(org.apache.tools.ant.Task)
116:             */
117:            public void addTask(final Task task) {
118:                LOG.debug("addTask: " + task.getTaskName() + " " + task);
119:                if (task instanceof  Configuration) {
120:                    addConfig((Configuration) task);
121:                } else {
122:                    if (task instanceof  TestStepSequence) {
123:                        addSteps((TestStepSequence) task);
124:                    } else if (!fImplicitSteps) {
125:                        throw new UnsupportedElementException(
126:                                "No step allowed after </steps>!", task
127:                                        .getTaskName());
128:                    } else {
129:                        if (fSteps == null) {
130:                            final TestStepSequence implicitSteps = new TestStepSequence();
131:                            implicitSteps
132:                                    .setDescription("Implicit <steps> task");
133:                            implicitSteps.setTaskName("steps");
134:                            implicitSteps.setProject(getProject());
135:                            implicitSteps.setOwningTarget(task
136:                                    .getOwningTarget());
137:                            implicitSteps.setLocation(task.getLocation());
138:                            addSteps(implicitSteps);
139:
140:                            fImplicitSteps = true;
141:                        }
142:                        if (fImplicitSteps) {
143:                            // we have created <steps> by ourself, we need to populate its wrapper too 
144:                            // as Ant would have done
145:                            getStepSequence()
146:                                    .getRuntimeConfigurableWrapper()
147:                                    .addChild(
148:                                            task
149:                                                    .getRuntimeConfigurableWrapper());
150:                        }
151:                        getStepSequence().addTask(task);
152:                    }
153:                }
154:            }
155:
156:            /**
157:             * Called by ant to add the nested "webtest ..." task.
158:             *
159:             * @param steps the steps
160:             * @webtest.nested.parameter
161:             * required="yes"
162:             * description="All the webtest steps."
163:             */
164:            public void addSteps(final TestStepSequence steps) {
165:                // first create config if needed
166:                if (getConfig() == null) {
167:                    addConfig(createDefaultConfiguration());
168:                    LOG
169:                            .info("No configuration defined, using default configuration.");
170:                }
171:
172:                if (fSteps != null) {
173:                    final String msg = getTaskName()
174:                            + " doesn't support multiple nested \""
175:                            + steps.getTaskName() + "\" elements.";
176:                    throw new UnsupportedElementException(msg, steps
177:                            .getTaskName());
178:                }
179:                fSteps = steps;
180:                fImplicitSteps = false;
181:            }
182:
183:            /**
184:             * Executes the task.
185:             * If it doesn't contain a nested &lt;config&gt; a default one is created
186:             * using {@link #createDefaultConfiguration()}.
187:             */
188:            public void execute() throws BuildException {
189:                final String message = "webtest \"" + getName() + "\" ("
190:                        + getLocation() + ")";
191:                LOG.info("Starting " + message);
192:                final String webtestVersion = PackageBoundary.versionMessage();
193:                LOG.info(webtestVersion);
194:                getProject().setProperty("webtest.version", webtestVersion);
195:
196:                assertParametersNotNull();
197:                final Context context = new Context(this );
198:                CONTEXT_HOLDER.set(context);
199:
200:                LOG.debug("Executing configuration task");
201:                getConfig().setContext(context);
202:                getConfig().perform();
203:
204:                // register custom property helper in place of the original one
205:                final PropertyHelper originalPropertyHelper = PropertyHelper
206:                        .getPropertyHelper(getProject());
207:
208:                WebtestPropertyHelper
209:                        .configureWebtestPropertyHelper(getProject());
210:
211:                // register the listener that will capture the results
212:                fResultBuilderListener = new StepExecutionListener(context);
213:                getProject().addBuildListener(fResultBuilderListener);
214:
215:                try {
216:                    fSteps.perform();
217:                } catch (final BuildException e) {
218:                    // nothing, exception is available in result build listener too
219:                } finally {
220:                    getProject().removeBuildListener(fResultBuilderListener);
221:                    WebtestPropertyHelper.definePropertyHelper(getProject(),
222:                            originalPropertyHelper);
223:
224:                    // clean the WebClient(s) to stop running js scripts (like setTimeout)
225:                    for (final Iterator iter = context.getWebClientContexts()
226:                            .values().iterator(); iter.hasNext();) {
227:                        final WebClientContext webClientContext = (WebClientContext) iter
228:                                .next();
229:                        webClientContext.destroy();
230:                    }
231:                }
232:
233:                LOG.info("Finished executing " + message);
234:
235:                writeTestReportIfNeeded(fResultBuilderListener.getRootResult());
236:                stopBuildIfNeeded(fResultBuilderListener.getRootResult(),
237:                        fConfig);
238:            }
239:
240:            private StepExecutionListener fResultBuilderListener;
241:
242:            /**
243:             * TODO: check if it should really be accessible
244:             * @return the listener that will build the results
245:             */
246:            protected StepExecutionListener getResultBuilderListener() {
247:                return fResultBuilderListener;
248:            }
249:
250:            /**
251:             * Creates the default configuration to use if no <configuration> was
252:             * present in the ant file.
253:             * @return the configuration
254:             */
255:            protected Configuration createDefaultConfiguration() {
256:                final Configuration configuration = new Configuration(this );
257:                LOG.debug("Default configuration created: host="
258:                        + configuration.getHost() + ", port="
259:                        + configuration.getPort() + ", protocol="
260:                        + configuration.getProtocol());
261:                return configuration;
262:            }
263:
264:            protected void stopBuildIfNeeded(
265:                    final RootStepResult webTestResult,
266:                    final Configuration config) {
267:                LOG.debug("Looking if it is needed to stop the build");
268:                if (webTestResult.isError() && config.isHaltOnError()
269:                        || webTestResult.isFailure()
270:                        && config.isHaltOnFailure()) {
271:                    LOG
272:                            .debug("Exception: "
273:                                    + webTestResult.getException().getClass()
274:                                            .getName());
275:                    LOG.debug("Throwing BuildException");
276:                    if (webTestResult.getException() instanceof  BuildException) {
277:                        throw (BuildException) webTestResult.getException();
278:                    } else {
279:                        final String str = PlainTextReporter
280:                                .getBuildFailMessage(webTestResult);
281:                        LOG.debug("str: " + str);
282:                        throw new BuildException(webTestResult.getException());
283:                    }
284:                }
285:                if (webTestResult.isError()
286:                        && !StringUtils.isEmpty(config.getErrorProperty())) {
287:                    LOG.debug("Set error property \""
288:                            + config.getErrorProperty() + "\" to true");
289:                    getProject().setProperty(config.getErrorProperty(), "true");
290:                }
291:                if (webTestResult.isFailure()
292:                        && !StringUtils.isEmpty(config.getFailureProperty())) {
293:                    LOG.debug("Set failure property \""
294:                            + config.getFailureProperty() + "\" to true");
295:                    getProject().setProperty(config.getFailureProperty(),
296:                            "true");
297:                }
298:            }
299:
300:            // *********************************************************************
301:            // Implementation of the IPropertyHandler interface
302:            // *********************************************************************
303:            public String getProperty(final String propertyName) {
304:                return getProject().getProperty(propertyName);
305:            }
306:
307:            private void assertParametersNotNull() throws BuildException {
308:                assertAttributeNotNull(fName, "name");
309:                assertNestedElementNotNull(fSteps, "steps");
310:            }
311:
312:            private void assertAttributeNotNull(final Object parameter,
313:                    final String parameterName) {
314:                final String[] msg = { "attribute ", "\n", parameterName, "\n" };
315:                assertNotNull(parameter, msg);
316:            }
317:
318:            private void assertNestedElementNotNull(final Object parameter,
319:                    final String parameterName) {
320:                final String[] msg = { "nested element ", "<", parameterName,
321:                        ">" };
322:                assertNotNull(parameter, msg);
323:            }
324:
325:            protected void assertNotNull(final Object parameter,
326:                    final String[] msg) {
327:                if (parameter == null) {
328:                    throw new BuildException("Required " + msg[0] + msg[1]
329:                            + msg[2] + msg[3] + " is not set!");
330:                }
331:            }
332:
333:            /**
334:             * @param name
335:             * @webtest.parameter
336:             *   required="yes"
337:             *   description="Defines a name for this test specification."
338:             */
339:            public void setName(final String name) {
340:                fName = name;
341:            }
342:
343:            /**
344:             * gets the name of this webtest
345:             * @return the name (as specified in &lt;webtest name="..."&gt;)
346:             */
347:            public String getName() {
348:                return fName;
349:            }
350:
351:            protected void writeTestReportIfNeeded(final RootStepResult result) {
352:                if (!fConfig.isSummary()) {
353:                    LOG.info("No report to write according to config");
354:                    return;
355:                }
356:                String reporterClass = getProject().getProperty(
357:                        REPORTER_CLASSNAME_PROPERTY);
358:                if (reporterClass == null) {
359:                    reporterClass = DEFAULT_REPORTER_CLASSNAME;
360:                }
361:                LOG.debug("Writing test report using Report class: "
362:                        + reporterClass);
363:                callSelectedReporter(reporterClass, result);
364:                LOG.debug("Report written");
365:            }
366:
367:            protected void callSelectedReporter(final String reporterClass,
368:                    final RootStepResult result) {
369:                try {
370:                    final IResultReporter reporter = (IResultReporter) Class
371:                            .forName(reporterClass).newInstance();
372:                    report(reporter, result);
373:                } catch (final Exception e) {
374:                    LOG.error("Exception caught while writing test report", e);
375:                }
376:            }
377:
378:            protected void report(final IResultReporter reporter,
379:                    final RootStepResult result) {
380:                try {
381:                    reporter.generateReport(result);
382:                    LOG.info("Test report successfully created.");
383:                } catch (final Exception e) {
384:                    LOG.error("Exception caught while writing test report", e);
385:                }
386:            }
387:
388:            public Configuration getConfig() {
389:                return fConfig;
390:            }
391:
392:            protected void setConfig(final Configuration config) {
393:                fConfig = config;
394:            }
395:
396:            public TestStepSequence getStepSequence() {
397:                return fSteps;
398:            }
399:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.