如何确定循环中哪个断言失败?

I have a PHPUnit test that loops through an array of invalid values, and asserts that each one is correctly rejected by the function.

For instance, validateInput should return true only if the input is a string, else return false.

public function testValidateInput()
{
  $obj = new MyClass();
  $data = [
    null,
    42,
    21.21,
    -24,
    -12.12,
    false,
    array('key' => 'value'),
    (object) 'value'
  ];

  foreach ($data as $item){
    $this->assertSame(false, $obj->validateInput($item));
  }
}

When the test fails an assertion, I only get the line number - which is the same for all the values because it's in a loop.

1) MyClassTest::testValidateInput
Failed asserting that true is identical to false.

/home/jeff/MyClass/tests/MyClassTest.php:24

How can I determine which value failed the assertion?

Use a data provider. PHPUnit will then tell you what index of the provider failed.

/**
 * @dataProvider getInputData
 */
public function testValidateInput($value)
{
  $obj = new MyClass();

  $this->assertSame(false, $obj->validateInput($value));
}

public function getInputData()
{
    return [
      [null],
      [42],
      [21.21],
      [-24],
      [-12.12],
      [true],
      [false],
      [array('key' => 'value')],
      [(object) 'value'],
  ];
}

1) Test::testValidateInput with data set #3 (21.21)
Failed asserting that true matches expected false.

Also a hint: when asserting for boolean, use assertFalse method

PHPUnit's assertion methods all have an additional parameter at the end that you can use for a description. Simply include the loop iteration value in the description string, and you will know exactly which one has failed.

assertSame has an overload that accepts a message; you could pass along the index and the value in the message:

foreach ($data as $index => $item) {
    $this->assertSame(false, $obj->validateInput($item), (string)$item); // include $index too 
}