Symfony2 + Atoum

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

02 déc. 2013, 15:09

Hello,

quelqu'un aurait-il un exemple d'un WebTestCase Atoum pour Symfony2. J'ai ceci pour l'instant en PHPUnit que je voudrais essayer de convertir en test Atoum (ça me semble bien plus rapide à l'exécution):
class TeacherControllerTest extends AbstractControllerTest {
    
    private $FIELD_PREFIX = 'virgule_bundle_mainbundle_teachertype';

    public function testUserCreationSuccess() {
        // Create a new client to browse the application
        $this->client = static::createClient();
        $this->crawler = $this->client->request('GET', '/');
        
        $this->login($this->ADMIN_USERNAME, $this->ADMIN_PASSWORD);
        $this->goToUserCreationForm();
        
        $lastName =  "Lachance" . time();
        $firstName = "Bob" . time();        
        $phoneNumber = "2026770549";
        $cellPhoneNumber = "0620518103";     
        $phoneNumberFormatted = "20 26 77 05 49";
        $cellPhoneNumberFormatted = "06 20 51 81 03";
        $emailAddress = "bob.lachance." . time() . "@example.com";
        $userName = "bob" . time();
        $passwordFirst = "password";
        $passwordSecond = $passwordFirst;
        $this->fillAndSubmitForm($firstName, $lastName, $phoneNumber, $cellPhoneNumber, $emailAddress, $userName, $passwordFirst, $passwordSecond);
        
        $this->assertTrue($this->crawler->filter("html:contains('Créer un nouveau compte utilisateur')")->count() == 0);
        
        $this->assertEquals(1, $this->crawler->filter("td:contains('" . $firstName . " " . $lastName . "')")->count());
        $this->assertEquals(1, $this->crawler->filter("td:contains('" . $phoneNumberFormatted ."')")->count());
        $this->assertEquals(1, $this->crawler->filter("td:contains('" . $cellPhoneNumberFormatted ."')")->count());
        
        $crawlerTeacher = $this->crawler->filter("td:contains('" . $firstName . " " . $lastName . "')")->siblings();
        $this->crawler = $this->client->click($crawlerTeacher->selectLink('Détails')->link());
        
        $this->assertTrue($this->crawler->filter("html:contains('Fiche formateur')")->count() == 1);
        $this->assertTrue($this->crawler->filter("html:contains('Liste des formateurs actifs')")->count() == 0);
        
        $this->assertEquals(1, $this->crawler->filter("div.widget-title:contains('" . $firstName . " " . $lastName . "')")->count());
        $this->assertEquals(1, $this->crawler->filter("div.controls:contains('" . $phoneNumberFormatted ."')")->count());
        $this->assertEquals(1, $this->crawler->filter("div.controls:contains('" . $cellPhoneNumberFormatted ."')")->count());
        $this->assertEquals(1, $this->crawler->filter("div.controls:contains('" . $emailAddress ."')")->count());
        $this->assertEquals(1, $this->crawler->filter("div.controls:contains('" . date("d/m/Y") ."')")->count());
                
        $this->assertEquals(1, $this->crawler->filter("div.widget-content:contains('Aucun apprenant trouvé')")->count());
        $this->assertEquals(1, $this->crawler->filter("div.widget-content:contains(' Aucun cours dirigé pour le moment')")->count());
        $this->assertEquals(1, $this->crawler->filter("div.widget-content:contains('Aucun compte-rendu enregistré pour le moment')")->count());
    }
    
    }
Malheureusement je ne vois pas bien à partir de l'exemple du bundle https://github.com/atoum/AtoumBundle#web-test-case comment faire des asserts.

Merci :)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

02 déc. 2013, 18:50

On peux dire que tu tombes à pic, je prenais une pause après avoir fini mes tests ;)

La manière "officielle" de faire un test de contrôleur est détaillée ici : https://github.com/atoum/AtoumBundle#test-a-controller

Pour ma part, comme je teste un retour de WebService, j'ai eu des soucis avec le crawler, donc voici le genre de code que j'utilise :
<?php

class ServiceController extends AbstractController 
{
    public function testGetServices()
    {   
        $this
            ->if($client = static::createClient())
            ->and($crawler = $client->request('GET', '/services'))
            ->and($response = $client->getResponse())
            ->then
                ->integer($response->getStatusCode())
                    ->isEqualTo(200)
                ->string($response->headers->get('Content-Type'))
                    ->isEqualTo('application/json')
                ->array($services = json_decode($response->getContent(), true))
                    ->hasSize(2)
                ->array($firstService = array_pop($services))
                    ->hasSize(13)
                    ->hasKey('id')
                    ->hasKey('title')
                    ->hasKey('code')
                    ->hasKey('priority')
                    ->hasKey('url')
                    ->hasKey('has_category')
                    ->hasKey('has_mea')
                    ->hasKey('has_ad_skin')
                    ->hasKey('has_tabbar')
                    ->hasKey('has_emc')
                    ->hasKey('has_autocontrib')
                    ->hasKey('create_date')
                    ->hasKey('update_date')
        ;
    }

    public function testGetServicesNoResult()
    {
        $this
            ->if($client = static::createClient())
            ->and($crawler = $client->request('GET', $this->getUrl('/services')))
            ->and($response = $client->getResponse())
            ->then
                ->integer($response->getStatusCode())
                    ->isEqualTo(200)
                ->string($response->headers->get('Content-Type'))
                    ->isEqualTo('application/json')
                ->array($services = json_decode($response->getContent(), true))
                    ->hasSize(0)
        ;
    }
}
Je préconise toutefois la première méthode, plus simple et efficace.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

04 déc. 2013, 12:05

Cool merci, je n'avais pas vu que le test de controller étendait aussi WebTestCase, je pensais que c'était deux trucs différents. Donc je comprends que tu peux tout tester d'un coup comme ça, lister tes objets, aller au formulaire de création, le soumettre, aller au formulaire d'édition ?

Je trouve cet enchaînement d'appels de méthodes un peu perturbant au début, je ne m'y retrouve pas dans l'indentation, j'ai l'impression d'être en apnée jusqu'à la fin de la méthode, mais j'imagine que c'est une question d'habitude :-)

Je n'ai pas trouvé beaucoup d'exemples de tests Atoum/Symfony sur le net, j'essaierai de poster le mien si j'y arrive, en tant qu'expert tu pourras l'améliorer ;)

Merci

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

04 déc. 2013, 12:43

A noter que je connais très bien le mainteneur du AtoumBundle, et qu'il est friand de doc pour son produit ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer