Question

I think I might be getting the concept wrong or not thinking about something correctly. I'm looking for a way to connect to db, and then run a selenium test (in phantomjs) for every row of a table. The test is to check for broken images on a bespoke CMS, and could be applied to any CMS.

I basically want to run an acceptance test for every page (of a specific type) by loading their IDs from the db and then running a separate test for each ID.

This is what I have so far:

$I = new WebGuy($scenario);
$results = $I->getArrayFromDB('talkthrough', '`key`', array());
foreach ($results as $r) {
    $I->wantTo('Check helpfile '.$r['key'].'for broken images');
    $I->amOnPage('/talkThrough.php?id='.$r['key']);
    $I->seeAllImages();
}

This works to some extent in that it executes until the first failure (because it is running as 1 test with many assertions).

How do I make this run as individual tests?

Was it helpful?

Solution

I ended up looping through and storing the key that failed in a comma delimited string and setting a bool to say failures found.

$I = new WebGuy($scenario);
$results = $I->getArrayFromDB('talkthrough', '`key`', array());
$failures = "Broken help files are: ";
$failures_found = false;
foreach ($results as $key => $r) {
   $I->wantTo('Check helpfile '.$r['key'].'for broken images');
   $I->amOnPage('/talkThrough.php?id='.$r['key']);
   $allImagesFine = $I->checkAllImages();
   if($allImagesFine != '1')
   {
       $fail = $r['key'].",";
       $failures.= $fail;
       $failures_found = true;
   }
}
$I->seeBrokenImages($failures_found,$failures);

With following as my webhelper

<?php
namespace Codeception\Module;

// here you can define custom functions for WebGuy 

class WebHelper extends \Codeception\Module
{
    function checkAllImages()
    {
        $result = $this->getModule('Selenium2')->session->evaluateScript("return     (function(){ return Array.prototype.slice.call(document.images).every(function (img) {return img.complete && img.naturalWidth > 0;}); })()");
        return $result;
    }
    function getArrayFromDB($table, $column, $criteria = array())
    {
        $dbh = $this->getModule('Db');
        $query = $dbh->driver->select($column, $table, $criteria);
        $dbh->debugSection('Query', $query, json_encode($criteria));

        $sth = $dbh->driver->getDbh()->prepare($query);
        if (!$sth) \PHPUnit_Framework_Assert::fail("Query '$query' can't be executed.");

        $sth->execute(array_values($criteria));
        return $sth->fetchAll();
    }
    function seeBrokenImages($bool,$failArray)
    {
        $this->assertFalse($bool,$failArray);
    }
}

Thanks for the submitted answers

OTHER TIPS

That's not going to work. Please avoid loops and conditionals in your tests. You should place the key manually. And not get them from database. As it introduces additional complexity.

It might not be the best design choice, but If you really want to follow this approach you could use the specify tool from codeception, in order to allow your test continue running even if one assertion fails: https://github.com/Codeception/Specify

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top