Есть ли в PHPUnit встроенная функция сравнения рекурсивных массивов? - PullRequest
23 голосов
/ 30 мая 2010

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

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

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

Ответы [ 5 ]

26 голосов
/ 30 мая 2010

Да, это так. 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]

Вот код для вышедших из строя списков:

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
)
4 голосов
/ 25 января 2011

@ wilmoore

$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');

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

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

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

1 голос
/ 10 января 2012

Голова метода assertEqual выглядит следующим образом:

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

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

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

1 голос
/ 14 июля 2011

У меня была эта проблема с некоторыми сгенерированными массивами с ключами - в итоге я пропустил ожидаемый массив и проверяемый массив через 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
0 голосов
/ 05 июля 2017

Иногда я делаю это так:

$arrayResult = [....];
$arrayExpected = [....];

ksort($arrayResult); // or sort() for associative arrays
ksort($arrayExpected); 

self::assertSame($arrayExpected, $arrayResult);
...