Есть ли у PHPUnit встроенная функция сравнения рекурсивных массивов?
Некоторое тестирование, которое мне нужно будет выполнить, потребует сравнения известного массива с результатом, который я получаю от функций, которые я буду запускать.
Для рекурсивного сравнения массивов:
- Есть ли у PHPUnit встроенная функция?
- Есть ли у кого-нибудь код, который они создали для совместного использования?
- Будет ли это что-то, что мне придется строить самостоятельно?
Ответы
Ответ 1
Да, да. assertEquals()
и assertNotEquals()
документация.
В частности:
assertEquals()
assertEquals(mixed $expected, mixed $actual[, string $message = ''])
Сообщает об ошибке, идентифицированной $message
, если две переменные $expected
и $actual
не равны.
assertNotEquals()
является обратным к этому утверждению и принимает те же аргументы.
Тестовый код:
public function testArraysEqual() {
$arr1 = array( 'hello' => 'a', 'goodbye' => 'b');
$arr2 = array( 'hello' => 'a', 'goodbye' => 'b');
$this->assertEquals($arr1, $arr2);
}
public function testArraysNotEqual() {
$arr1 = array( 'hello' => 'a', 'goodbye' => 'b');
$arr2 = array( 'hello' => 'b', 'goodbye' => 'a');
$this->assertNotEquals($arr1, $arr2);
}
[EDIT]
Вот код для выписки из списка aLists:
public function testArraysEqualReverse() {
$arr1 = array( 'hello' => 'a', 'goodbye' => 'b');
$arr2 = array( 'goodbye' => 'b', 'hello' => 'a');
$this->assertEquals($arr1, $arr2);
}
Этот тест не выполняется:
public function testArraysOutOfOrderEqual() {
$arr1 = array( 'a', 'b');
$arr2 = array( 'b', 'a');
$this->assertEquals($arr1, $arr2);
}
С сообщением:
Failed asserting that
Array
(
[0] => b
[1] => a
)
is equal to
Array
(
[0] => a
[1] => b
)
Ответ 2
@wilmoore
$array1 = array('hi','hi2');
$array2 = array('hi2','hi');
$this->assertEquals(array_values($array1), array_values($array2));
Ошибка.
@Ben Dauphinee
Возможно, стоит взглянуть на assertContains(mixed $needle, array $haystack)
, но вам придется перебирать оба массива и сравнивать каждый элемент с другим массивом, чтобы убедиться, что он содержит все необходимые элементы, а другие нет, однако это не учитывает массив содержащий два идентичных элемента
$array1 = array('hi','hi2','hi');
$array2 = array('hi2','hi');
будет проходить в этом случае
Он также не учитывает дальнейшую рекурсию, которая, вероятно, будет довольно сложной для решения.
В зависимости от сложности может быть проще в долгосрочной перспективе реализовать свою собственную функцию assert.
Ответ 3
У меня была эта проблема с некоторыми сгенерированными массивами с ключами - в итоге я передал как ожидаемый массив, так и массив, протестированный через ksort, прежде чем вызвать assertEquals. Однако это не работает на рекурсивных массивах.
$expectedArray = array('foo' => 1, 'bar' => 0);
$array = array('bar' => 0, 'foo' => 1);
ksort($expectedArray);
ksort($array);
var_dump($expectedArray); // outputs array('bar' => 0, 'foo' => 1);
var_dump($array); // outputs array('bar' => 0, 'foo' => 1);
$this->assertEquals($expectedArray, $array); // passes
Ответ 4
Глава метода assertEqual
выглядит следующим образом:
public static function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)
Если для параметра canonicalize установлено значение true, массивы будут выполняться через sort()
во-первых, это можно использовать, если ключи являются произвольными и имеют значение только значения.
Однако после просмотра кода компаратора массива assertEqual
на самом деле не заботится о порядке связанного массива:) Он просто ищет ожидаемый ключ в массиве результатов и затем сравнивает значения этих ключей.
Ответ 5
Когда-нибудь я сделаю так:
$arrayResult = [....];
$arrayExpected = [....];
ksort($arrayResult); // or sort() for associative arrays
ksort($arrayExpected);
self::assertSame($arrayExpected, $arrayResult);