Пишу тесты для моделей (которые разрабатываю не я) на phpunit. Опыта программирования мало. Хотелось бы получить советы: как улучшить стиль написания тестов, какие грубые ошибки, какие недочеты, ну и т. д.
Проект на yii. Для тестов отдельная БД (mongodb - периодически делается рестор с основной БД). На основной БД созданы тестовые пользователи с тестовыми данными (есть статические пользователи - у которых данные не меняются (используются для методов типа get), есть динамические пользователи (в тестах у них добавляются, изменяются, удаляются данные, причем чаще всего эти изменения не подчищаются после выполнения тестов, т.к. они ни на что не повлияют в дальнейшем)).
Параметры для теста чаще всего формируются с помощью провайдера. Чаще всего, отдельный тест проверяет отдельный метод модели, а провайдер передает различные параметры для метода (обеспечивается полное (ну или почти полное) покрытие кода метода).
Вот пример теста:
public function testSend($params, $expResult, $userEmail, $expExceptionMsg) {
// перезаходим под необходимым юзером
self::changeUserID($userEmail);
// здесь, если expExceptionMsg != null, то выставляется ожидаемое исключение
self::setExpException($this, $expExceptionMsg);
// выполняем метод который необходимо проверить
$result = Chat::send($params);
// при необходимости в ожидаемый результат подставляем непредсказуемые данные
$expResult['date'] = $result['date'];
$expResult['timestamp'] = $result['timestamp'];
$expResult['index'] = $result['index'];
$this->assertEquals($expResult, $result);
}
И пример провайдера:
public function providerSend(){
// из этих массивов затем формируется массив для провайдера
// параметры для проверяемого метода
$params = array();
// логин пользователя под которым будет выполняться тест
$userEmail = array();
// ожидаемый результат
$expResult = array();
// ожидаемое исключение
$expExceptionMsg = array();
//------------- Test#0 ---------------------
// отправка сообщения не участником чата
$i = 0;
$params[$i] = array(
'chatId' => '42378423747',
'text' => 'Сообщение, которое не отправится в чат',
);
$userEmail[$i] = 'test@test.test';
$expExceptionMsg[$i] = 'Access error';
//------------- Test#1 ---------------------
// сообщение пользователя
// $i определяет под каким номером будет тестовый случай в провайдере.
//к примеру если необходимо не выполнять какой-то тестовый случай, то можно
// его закомментировать и сформируется корректный провайдер, но без него.
$i++;
$params[$i] = array(
'chatId' => '42378423747',
'text' => 'Тестовое сообщение',
);
$userEmail[$i] = 'album_dynamic@test.test';
$expResult[$i] = array(
'chatId' => $params[$i]['chatId'],
'text' => $params[$i]['text'],
'date' => 'Меняем в тесте',
'timestamp' => 'Меняем в тесте',
'from' => User::get(array('userId' => '529f06e2ecaa3c5b05000001')),
'type' => GEMessage::GE_MESSAGE_TYPE_GENERAL,
'index' => 'Меняем в тесте',
'objects' => null,
);
//------------- end ---------------------
// Здесь формируется массив для провайдера
return self::returnProviderArray(array($params, $expResult, $userEmail, $expExceptionMsg));
}
Вот как формируется провайдер:
protected static function returnProviderArray($params) {
$providerArray = array();
foreach ($params[0] as $key => $value) {
// массив параметров для одного теста
$paramsArray = array();
foreach ($params as $param) {
// незаполненые параметры заполняем null
if (!isset($param[$key]))
$param[$key] = null;
$paramsArray[] = $param[$key];
}
$providerArray[] = $paramsArray;
}
return $providerArray;
}