Is there a way I can have PHPUnit just continue after an error? For example, I have a large test suite (400+ steps) and I would prefer that if say, an element is not found, it doesn't stop the rest of my script from continuing.
2 Answers
We do the same thing in our Selenium tests. You need to catch the exceptions thrown for assertion failures, and the only way to do that is to create a custom test case base class that overrides the assertion methods. You can store the failure messages and fail the test at the end using a test listener.
I don't have the code in front of me, but it was pretty straight-forward. For example,
abstract class DelayedFailureSeleniumTestCase extends PHPUnit_Extension_SeleniumTestCase
{
public function assertElementText($element, $text) {
try {
parent::assertElementText($element, $text);
}
catch (PHPUnit_Framework_AssertionFailedException $e) {
FailureTrackerListener::addAssertionFailure($e->getMessage());
}
}
... other assertion functions ...
}
class FailureTrackerListener implements PHPUnit_Framework_TestListener
{
private static $messages;
public function startTest() {
self::$messages = array();
}
public static function addAssertionFailure($message) {
self::$messages[] = $message;
}
public function endTest() {
if (self::$messages) {
throw new PHPUnit_Framework_AssertionFailedException(
implode("\n", self::$messages));
}
}
}
Comments
There is a better way to do this. Instead of overloading every assert*() method you can overload just one method: runTest(). It is for each assertion, and exceptions can be caught:
abstract class AMyTestCase extends PHPUnit_Framework_TestCase
{
public function runTest()
{
try {
parent::runTest();
}
catch ( MyCustomException $Exc ) {
// will continue tests
}
catch ( Exception $Exc ) {
if ( false === strpos($Exc->getMessage(), 'element not found') ) {
// rethrow:
throw $Exc;
}
// will also continue
}
}
}