PHPUnit DataProvider для функционального тестирования в symfony2

Я пытаюсь сделать функциональный тест на форме следующим образом

// счастливый сценарий

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);
}

// неверный регистр
Как я могу использовать провайдер данных для проверки неверного регистра для функционального тестирования?
вот моя попытка:

 /**
* @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'],
];
}

Однако я не знаю, как назначить сообщение проверки формы с использованием поставщика данных

3

Решение

Несколько заметок для вас, чтобы иметь в виду.

  • Никогда во время модульного тестирования не вызывайте методы, которые возвращают случайные данные. Потому что так может случиться, что тесты пройдут один раз, а в другой раз не пройдут.
  • Не генерируйте URL-адреса, а жестко запишите их в своих тестах. Я знаю, что это поначалу неправильно, но на самом деле это то, что вы хотите сделать. Если у вас есть публичный API, например, и вы «случайно» изменили URL, тесты все равно будут работать, но приложения, использующие API, перестанут работать. Test предупредит вас об изменениях, а затем вы увидите, действительно ли это то, что вы хотели.

Тесты выглядят сложными для меня в целом. Я бы разделил его на 2 или 3 теста. Вы можете проверить, была ли страница загружена нормально в другом тесте. Кроме того, я бы предложил вам сделать некий неявный метод входа в систему, если вам нужен токен, пользователь или что-то еще для вашей аутентификации.

Поставщики данных выглядят так:

    /**
* 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'),
);
}

Если вы выполняете функциональное тестирование с помощью phpunit, это нормально, но действительно стоит подумать об использовании behat. Это намного проще, когда вы привыкнете к этому.

2

Другие решения

Других решений пока нет …