Есть ли в PHPUnit встроенная функция сравнения рекурсивных массивов?

Некоторые из тестов, которые мне нужно будет выполнить, потребуют сравнения известного массива с результатом, который я получу от функций, которые я буду запускать.

Для рекурсивного сравнения массивов:

  • Есть ли у PHPUnit встроенная функция?
  • Есть ли у кого-нибудь здесь код, который они создали, чтобы поделиться?
  • Это будет что-то, что я должен буду построить самостоятельно?

person Ben Dauphinee    schedule 30.05.2010    source источник


Ответы (4)


Да, это так. assertEquals() и assertNotEquals() документация.

Конкретно:

утвердитьравно()

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

[ИЗМЕНИТЬ]

Вот код для неупорядоченных списков:

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
)
person Gutzofter    schedule 30.05.2010
comment
Является ли это функцией, которая требует, чтобы сравниваемые массивы находились в точно таком же порядке, ключ для ключа? - person Ben Dauphinee; 30.05.2010
comment
Так что, если я хочу проверить неупорядоченный массив на заведомо исправный, мне нужно убедиться, что ключи совпадают, но это единственное предостережение? Спасибо за помощь! - person Ben Dauphinee; 30.05.2010
comment
@wilmoore: ты уверен? array_values переиндексирует массив и удалит все ключи массива, но не изменит порядок числовых массивов. - person mpen; 17.12.2013
comment
@Mark, просто отметив, что ответ был обновлен, удалив часть array_values. - person Wil Moore III; 05.02.2014
comment
Вопрос был о рекурсивном сравнении. В вашем примере представлены только одномерные массивы. Итак, вопрос остается открытым: поддерживает ли asserEqual() сравнение многомерных массивов? И ответ ДА. - person Alex Skrypnyk; 08.09.2015

@уилмур

$array1 = array('hi','hi2');
$array2 = array('hi2','hi');
$this->assertEquals(array_values($array1), array_values($array2));

Не удастся.

@Бен Дофини

Возможно, стоит взглянуть на assertContains(mixed $needle, array $haystack), но вам придется перебрать оба массива и сравнить каждый элемент с другим массивом, чтобы убедиться, что он содержит все необходимые элементы и ничего больше, однако это не будет учитывать массив, содержащий два идентичных элемента

$array1 = array('hi','hi2','hi');
$array2 = array('hi2','hi');

пройдет в этом случае

Он также не учитывает дальнейшую рекурсию, с которой, вероятно, будет довольно сложно иметь дело.

В зависимости от сложности в долгосрочной перспективе может быть проще реализовать собственную функцию утверждения.

person ians    schedule 25.01.2011
comment
действительно, метод array_values не сработает. Это было много лет назад, когда я писал, поэтому я не совсем помню, почему это утверждалось. - person Wil Moore III; 17.12.2013

Заголовок метода assertEqual выглядит так:

public static function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)

Если для параметра canonicalize установлено значение true, массивы сначала будут проходить через sort(), это можно использовать, если ключи произвольны и имеют значение только значения.

Однако после просмотра кода компаратора массива assertEqual фактически не заботится о порядке связанного массива :) Он просто ищет ожидаемый ключ в массиве результатов, а затем сравнивает значения этих ключей.

person Silwing    schedule 10.01.2012

У меня была эта проблема с некоторыми сгенерированными массивами с ключами - в итоге я передал как ожидаемый массив, так и проверяемый массив через 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
person HorusKol    schedule 14.07.2011