简体   繁体   中英

PHPUnit DataProvider for functional test in symfony2

I am trying to do a functional test on a form as following

// happy scenario

public function testRegisterActionInvalidCase($password, $confPassword, $gender, $country, $city, $schoo, $schoolName, $shortName, $keyWords, $expectedMessage) {
    $user = $this->_testUtilityService->getRandomEntity($this->_userService, 'FOS\UserBundle\Model\User');
    $token = $user->getConfirmationToken();
    $url = $this->generateUrl('teacher_register', array('token' => $token));
    $crawler = $this->client->request('POST', $url);
    $crawlerResponse = $this->client->getResponse();

    //[ASSERTIONS] Page is loaded ok
    $this->assertEquals(200, $crawlerResponse->getStatusCode());
    //[ASSERTIONS] that the loaded page is the correct one
    $this->assertContains($this->Translator->trans('Teacher Registration'), $this->client->getResponse()->getContent());
    $form = $crawler->selectButton('Save')->form();
    $confPassword = $password = $this->Faker->password();

    if ($gender === 'GENDER') {
        $gender = $this->Faker->randomElement([Gender::FEMALE, Gender::MALE]);
    }
    if ($gender === 'COUNTRY') {
        $country = $this->_testUtilityService->getRandomEntity($this->_countryService, '\ITJari\GeneralBundle\Entity\Country');
    }
    if ($gender === 'CITY') {
        $city = $this->_testUtilityService->getRandomEntity($this->_cityService, '\ITJari\GeneralBundle\Entity\City');
    }
    if ($gender === 'SCHOOL') {
        $schoo = $this->_testUtilityService->getRandomEntity($this->_schoolService, '\ITJari\SchoolBundle\Entity\School');
    }

    // fill in the form to be submitted
    $form["plainPassword['first']"] = $password;
    $form["plainPassword['second']"] = $confPassword;
    $form["gender"] = $gender;
    $form["country"] = $country;
    $form["city"] = $city;
    $form["school"] = $schoo;
    $form["school_name"] = $schoolName;
    $form["short_name"] = $shortName;
    $form["key_words"] = $keyWords;
    $crawler = $this->client->submit($form);
    //[ASSERTIONS] that the form submitted successfully
    $this->assertTrue($crawler->filter('html:contains("Teacher has been created successfully")')->count() > 0);
}

//invalid case How can i use data provider to test invalid case for functional test? here is my try:

 /** 
 * @dataProvider provideDataForRegistrationActionInvalidCase
 * @assertions Assert for exception asserted on "exception message"
 * 
 */
public function testRegisterActionInvalidCase($password, $confPassword, $gender, $country, $city, $schoo, $schoolName, $shortName, $keyWords, $expectedMessage) {
    $user = $this->_testUtilityService->getRandomEntity($this->_userService, 'FOS\UserBundle\Model\User');
    $token = $user->getConfirmationToken();
    $url = $this->generateUrl('teacher_register', array('token' => $token));
    $crawler = $this->client->request('POST', $url);
    $crawlerResponse = $this->client->getResponse();

    //[ASSERTIONS] Page is loaded ok
    $this->assertEquals(200, $crawlerResponse->getStatusCode());
    //[ASSERTIONS] that the loaded page is the correct one
    $this->assertContains($this->Translator->trans('Teacher Registration'), $this->client->getResponse()->getContent());
    $form = $crawler->selectButton('Save')->form();
    $confPassword = $password = $this->Faker->password();

    if ($gender === 'GENDER') {
        $gender = $this->Faker->randomElement([Gender::FEMALE, Gender::MALE]);
    }
    if ($gender === 'COUNTRY') {
        $country = $this->_testUtilityService->getRandomEntity($this->_countryService, '\ITJari\GeneralBundle\Entity\Country');
    }
    if ($gender === 'CITY') {
        $city = $this->_testUtilityService->getRandomEntity($this->_cityService, '\ITJari\GeneralBundle\Entity\City');
    }
    if ($gender === 'SCHOOL') {
        $schoo = $this->_testUtilityService->getRandomEntity($this->_schoolService, '\ITJari\SchoolBundle\Entity\School');
    }

    // fill in the form to be submitted
    $form["plainPassword['first']"] = $password;
    $form["plainPassword['second']"] = $confPassword;
    $form["gender"] = $gender;
    $form["country"] = $country;
    $form["city"] = $city;
    $form["school"] = $schoo;
    $form["school_name"] = $schoolName;
    $form["short_name"] = $shortName;
    $form["key_words"] = $keyWords;
    $crawler = $this->client->submit($form);
    //[ASSERTIONS] that the form submitted successfully
    $this->assertTrue($crawler->filter('html:contains("Teacher has been created successfully")')->count() > 0);
}

/**
 * @description prepare data to be used as providers for test cases
 * @author Mohamed Ragab Dahab <mdahab@treze.co.uk>
 * @access public
 * 
 * @covers TeacherService::submitSubscriptionFormData
 * 
 * @return array arguments array passed to each test case scenario 
 */
public function provideDataForRegistrationActionInvalidCase() {
    [
        //password
        ["password", "differentPassword", 'GENDER', 'COUNTRY', 'CITY', 'SCHOOL', 'my school name', 'my short  name', 'my key words', 'password does not match'],
        //Gender
        ["password", "password", 'invalid value', 'COUNTRY', 'CITY', 'SCHOOL', 'my school name', 'my short  name', 'my key words', 'Gender invalid value'],
        //Country
        ["password", "password", 'GENDER', 'invalid value', 'CITY', 'SCHOOL', 'my school name', 'my short  name', 'my key words', 'Country Invalid value'],
        //City
        ["password", "password", 'GENDER', 'COUNTRY', 'invalid value', 'SCHOOL', 'my school name', 'my short  name', 'my key words', 'City Invalid value'],
        //School
        ["password", "password", 'GENDER', 'COUNTRY', 'CITY', 'invalid value', 'my school name', 'my short  name', 'my key words', 'School Invalid value'],
        // School Name
        ["password", "password", 'GENDER', 'COUNTRY', 'CITY', 'SCHOOL', '112233Invalid Value', 'my short  name', 'my key words', 'School name invalid value'],
        // Short Name
        ["password", "password", 'GENDER', 'COUNTRY', 'CITY', 'SCHOOL', 'my school name', '112233Invalid Value', 'my key words', 'Short name invalid value'],
        // Key Words
        ["password", "password", 'GENDER', 'COUNTRY', 'CITY', 'SCHOOL', 'my school name', 'my short  name', 'TOO_MUCH_TEXT', 'Too much text'],
    ];
}

however i don't know how to assign the form validation message to using the data provider

A few notes for you to keep in mind.

  • Never during unit testing call methods which return random data. Because this way it might happen that tests pass once, and fail another time.
  • Do not generate urls, but rather hard code them in your tests. I know it feels wrong at the start, but it is actually something you want to do. If you have a public api for example and you "accidently" change the url, the tests would still work, but applications relying on the api would stop working. Test will warn you about the change and then you can see if that is really what you wanted.

The tests look to complicated to me in general. I would split it in 2 or 3 tests. You can check if the page loaded ok in another test. Also, I would suggest you to make some kind of implicit login method, if you need token, user or whatever for your authentication.

Data providers look like this:

    /**
     * Test description
     * @dataProvider getSomeData
     * @param array $data
     */
    public function testSomething($data)
    {
        $test = $data['test'];
        ...
    }

    static function getSomeData()
    {
        return array(
            array('test' => 'a'),
            array('test' => 'b'),
            array('test' => 'c'),
        );
    }

If you do functional test with phpunit, its fine, but really consider using behat. It is so much easier, once you get used to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM