// Copyright � 2002-2007 Canoo Engineering AG, Switzerland.
package com.canoo.webtest.ant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import junit.framework.AssertionFailedError;
import org.apache.commons.collections.EnumerationUtils;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.RuntimeConfigurable;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.UnsupportedElementException;
import org.apache.tools.ant.taskdefs.Echo;
import com.canoo.webtest.engine.Configuration;
import com.canoo.webtest.engine.Context;
import com.canoo.webtest.engine.StepFailedException;
import com.canoo.webtest.reporting.IResultReporter;
import com.canoo.webtest.reporting.ReportCreationException;
import com.canoo.webtest.reporting.RootStepResult;
import com.canoo.webtest.reporting.StepResult;
import com.canoo.webtest.self.CollectingBuildListener;
import com.canoo.webtest.self.CollectingBuildListener.CollectedBuildEvent;
import com.canoo.webtest.self.LogCatchingTestCase;
import com.canoo.webtest.self.TestBlock;
import com.canoo.webtest.self.ThrowAssert;
import com.canoo.webtest.steps.BaseStepTestCase;
import com.canoo.webtest.steps.Step;
/**
* Unit tests for {@link WebtestTask}
* @author Unknown
* @author Marc Guillemot
*/
public class WebtestTaskTest extends LogCatchingTestCase {
private WebtestTask fTask;
private Configuration fConfig;
private Project fProject;
private Target fTarget;
protected void setUp() throws Exception {
super.setUp();
fProject = new Project();
fTarget = new Target();
fTask = new WebtestTask();
fTask.setProject(fProject);
fTask.setOwningTarget(fTarget);
fTask.setName("foo");
final Context context = new Context(fTask);
WebtestTask.setThreadContext(context);
fConfig = new Configuration();
fConfig.setProject(fProject);
fConfig.setOwningTarget(fTarget);
fConfig.setResultpath(BaseStepTestCase.getTemporaryResultPathFolder());
fTask.addConfig(fConfig);
setUpCatchLoggerMessages();
}
public void testEvents()
{
final CollectingBuildListener listener = new CollectingBuildListener()
{
public void messageLogged(final BuildEvent event)
{
// do nothing, ignore message;
}
};
fProject.addBuildListener(listener);
fTask.addConfig(fConfig);
final TestStepSequence steps = new TestStepSequence();
steps.setProject(fProject);
steps.setOwningTarget(fTarget);
final Step step = dummyStep();
steps.addStep(step);
BaseStepTestCase.registerDummyResultReporter(fProject);
fTask.addSteps(steps);
fTask.perform();
final List<CollectedBuildEvent> expectedEvents = new ArrayList<CollectedBuildEvent>();
expectedEvents.add(new CollectedBuildEvent("taskStarted", new BuildEvent(fTask)));
expectedEvents.add(new CollectedBuildEvent("taskStarted", new BuildEvent(fConfig)));
expectedEvents.add(new CollectedBuildEvent("taskFinished", new BuildEvent(fConfig)));
expectedEvents.add(new CollectedBuildEvent("taskStarted", new BuildEvent(steps)));
expectedEvents.add(new CollectedBuildEvent("taskStarted", new BuildEvent(step)));
expectedEvents.add(new CollectedBuildEvent("taskFinished", new BuildEvent(step)));
expectedEvents.add(new CollectedBuildEvent("taskFinished", new BuildEvent(steps)));
expectedEvents.add(new CollectedBuildEvent("taskFinished", new BuildEvent(fTask)));
assertEquals(expectedEvents, listener.getCollectedEvents());
}
/**
* Test the equality of the content of the collections
* @param expected the expected elements
* @param actual the actual elements
*/
protected void assertEquals(final Collection<?> expected, final Collection<?> actual)
{
final Iterator<?> iterExpected = expected.iterator();
final Iterator<?> iterActual = actual.iterator();
int i = 0;
while (iterExpected.hasNext())
{
if (!iterActual.hasNext())
fail("Expected " + expected.size() + " elements, got " + actual.size() + "(the first " + i + " are equals)");
assertEquals("Element " + i, iterExpected.next(), iterActual.next());
++i;
}
if (iterActual.hasNext())
fail("Expected " + expected.size() + " elements, got " + actual.size() + "(the first " + i + " are equals)");
}
/**
* Unit tests for {@link #assertEquals(Collection, Collection)}
*/
public void testAssertEqualsCollection() {
assertEquals(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
assertEquals(Collections.singleton("foo"), Collections.singletonList("foo"));
testAssertEqualsCollectionFails(Collections.singleton("foo"), Collections.EMPTY_LIST);
testAssertEqualsCollectionFails(Collections.EMPTY_LIST, Collections.singleton("foo"));
}
/**
* Utility method for {@link #testAssertEqualsCollection()}
*/
private void testAssertEqualsCollectionFails(final Collection<?> colExpected, final Collection<?> colActual)
{
ThrowAssert.assertThrows(AssertionFailedError.class, new TestBlock()
{
public void call()
{
assertEquals(colExpected, colActual);
}
});
}
protected void tearDown() throws Exception {
super.tearDown();
tearDownCatchLoggerMessages();
}
private Step dummyStep() {
final Step step = new Step()
{
public void doExecute() throws Exception
{
// nothing
}
};
step.setProject(fProject);
step.setOwningTarget(fTarget);
return step;
}
protected EasyRootStepResult buildRootStepResult()
{
final TestStepSequence steps = new TestStepSequence();
return new EasyRootStepResult(steps);
}
public void testStopOnError() {
fConfig.setHaltonerror(true);
final EasyRootStepResult result = buildRootStepResult();
result.setLastFailingTaskResult(new StepResult("myTask"), new RuntimeException());
ThrowAssert.assertThrows(BuildException.class, new TestBlock() {
public void call() throws Exception {
fTask.stopBuildIfNeeded(result, fConfig);
}
});
fConfig.setHaltonerror(false);
fTask.stopBuildIfNeeded(result, fConfig);
// runs without exception
}
public void testSetsErrorProperty() {
fConfig.setHaltonerror(false);
fConfig.setErrorProperty("errorProp");
final EasyRootStepResult result = buildRootStepResult();
result.setLastFailingTaskResult(new StepResult("myTask"), new RuntimeException());
fTask.stopBuildIfNeeded(result, fConfig);
assertEquals("error property should be set to true", "true",
fTask.getProject().getProperties().get("errorProp"));
}
public void testStopOnFailure() {
fConfig.setHaltonfailure(true);
final EasyRootStepResult result = buildRootStepResult();
result.setLastFailingTaskResult(new StepResult("myTask"), new StepFailedException("bla"));
final StepResult failingStepResult = new StepResult("myTask");
result.addChild(failingStepResult);
result.setLastFailingTaskResult(failingStepResult, new StepFailedException("bla"));
ThrowAssert.assertThrows(BuildException.class, new TestBlock() {
public void call() throws Exception {
fTask.stopBuildIfNeeded(result, fConfig);
}
});
fConfig.setHaltonfailure(false);
fTask.stopBuildIfNeeded(result, fConfig);
// runs without exception
}
public void testSetsFailureProperty() {
fConfig.setHaltonfailure(false);
fConfig.setFailureProperty("failureProp");
final EasyRootStepResult result = buildRootStepResult();
final StepResult failingStepResult = new StepResult("myTask");
result.addChild(failingStepResult);
result.setLastFailingTaskResult(failingStepResult, new StepFailedException("bla"));
fTask.stopBuildIfNeeded(result, fConfig);
assertEquals("failure property should be set", "true",
fTask.getProject().getProperties().get("failureProp"));
}
public void testSetConfig() {
fTask.addConfig(fConfig);
assertEquals("checking config was set ok", fConfig, fTask.getConfig());
}
public void testNoReportIfNoSummary() {
fTask.addConfig(fConfig);
fTask.writeTestReportIfNeeded(null);
// runs without NPE
}
public static void testInternalAssertions() {
final WebtestTask task = new WebtestTask();
ThrowAssert.assertThrows(BuildException.class, new TestBlock() {
public void call() throws Exception {
task.assertNotNull(null, new String[]{"", "", "", ""});
}
});
}
public void testReporterWithClassNotFoundException() {
getSpoofAppender().getEvents().clear();
fTask.callSelectedReporter("unknown.class", null);
assertEquals("Exception caught while writing test report",
getSpoofAppender().allMessagesToString());
}
public void testReporterWithReportCreationException() throws Exception {
getSpoofAppender().getEvents().clear();
final IResultReporter reporter = (IResultReporter) mock(IResultReporter.class, "reporter");
reporter.generateReport(null);
modify().throwException(new ReportCreationException(new RuntimeException("xxx")));
startVerification();
fTask.report(reporter, null);
final LoggingEvent ev = (LoggingEvent) getSpoofAppender().getEvents().get(0);
assertEquals("xxx", ev.getThrowableInformation().getThrowable().getMessage());
}
public void testHelperForCoverage() {
// coverage hacks
getSpoofAppender().getEvents().clear();
// generate a message of any kind
fTask.callSelectedReporter("unknown.class", null);
/* ignore true case */ getSpoofAppender().containsMessage("Exception caught while writing test report");
/* ignore false */ getSpoofAppender().containsMessage("dummy");
/* ignore */ getSpoofAppender().close();
/* ignore */ getSpoofAppender().requiresLayout();
// generate a second message
fTask.callSelectedReporter("unknown.class", null);
/* ignore */ getSpoofAppender().allMessagesToString();
}
public void testAddTask()
{
final Configuration defaultConfig = new Configuration();
final TestStepSequence steps = new TestStepSequence();
final WebtestTask task = new WebtestTask()
{
public void addConfig(final Configuration config)
{
super.addConfig(config);
assertSame(defaultConfig, config);
}
public void addSteps(final TestStepSequence steps)
{
super.addSteps(steps);
assertSame(steps, steps);
}
};
task.addTask(defaultConfig);
task.addTask(steps);
ThrowAssert.assertThrows(UnsupportedElementException.class, "", new TestBlock()
{
public void call()
{
task.addTask(new Echo());
}
});
}
/**
* Test that a default configuration is set if no one was specified in ant file
* @throws Exception
*
*/
public void testExecuteUsesDefaultConfiguration() throws Exception {
final Configuration defaultConfig = new Configuration();
final WebtestTask task = new WebtestTask() {
protected Configuration createDefaultConfiguration() {
return defaultConfig;
}
};
task.setName("foo");
task.setProject(fProject);
task.addTask(new Echo());
assertSame(defaultConfig, task.getConfig());
}
public void testExecuteSetWebtestVersion() {
assertNull(fProject.getProperty("webtest.version"));
fConfig.setSaveresponse(false);
fConfig.setProject(fProject);
fConfig.setOwningTarget(fTarget);
fTask.addConfig(fConfig);
final TestStepSequence steps = new TestStepSequence();
steps.setProject(fProject);
steps.setOwningTarget(fTarget);
steps.addStep(dummyStep());
fTask.addSteps(steps);
fTask.execute();
assertNotNull(fProject.getProperty("webtest.version"));
}
/**
* When <steps> is omitted, we should fill it as would Ant do
*/
public void testImplicitsSteps()
{
final WebtestTask webtest = new WebtestTask();
webtest.setProject(new Project());
final Step step = dummyStep();
webtest.addTask(step);
assertEquals(1, webtest.getStepSequence().getSteps().size());
final RuntimeConfigurable stepsWrapper = webtest.getStepSequence().getRuntimeConfigurableWrapper();
assertEquals(1, EnumerationUtils.toList(stepsWrapper.getChildren()).size());
}
}
class EasyRootStepResult extends RootStepResult
{
EasyRootStepResult(final TestStepSequence step)
{
super(step);
}
public void setLastFailingTaskResult(final StepResult stepResult, final Throwable cause)
{
super.setLastFailingTaskResult(stepResult, cause);
}
}