Codeception multiple tests, 1 script
Asked Answered
T

3

6

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?

Taperecord answered 8/10, 2013 at 13:55 Comment(0)
T
3

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

Taperecord answered 18/12, 2013 at 15:34 Comment(1)
Unfortunately multiple wantTo() calls don't create separate tests I've found.Weitman
E
1

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.

Egide answered 9/10, 2013 at 21:11 Comment(1)
I would argue that hard-coding all your tests makes maintenance painful and laborious. Is there something fundamentally wrong with loops and conditionals in tests?Weitman
S
0

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

Sirotek answered 17/10, 2013 at 9:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.