Как модульно протестировать зависимые операторы if?

#php #unit-testing

#php #модульное тестирование

Вопрос:

следующий сценарий:

  public class InputFilter(){

  public function isInputValid($input) : bool
  {
    $isValid = false;


    if($inputA amp;amp; $inputB amp;amp; $inputC){
       return true;     
    }

    if($inputD amp;amp; $inputE){
      return true;     
    }

   ...

    return $isValid;
  }

}



 public Test(){

 //1. TestCase
 isInputValid_ValidInputABCGiven_ShouldReturnTrue(){
   $input[a => true, $b => true, c => true, d => false, e => false]
   assertSame(true, InputFilter->isInputValid, '')
 }

 //2. TestCase
 isInputValid_ValidInputBCGiven_ShouldReturnTrue{
  $input[a => false, $b => false, c => false, d => true, e => true]
  assertSame(true, InputFilter->isInputValid, '')
 }

}
  

вероятно, я действительно не знаю, как протестировать этот сценарий.
Давайте представим, что первый тестовый пример завершается неудачей, тогда я не знаю, связано ли это с тем, что
первый оператор if (a amp; amp; b amp; amp; c) не удался, или проблема во втором операторе if (d amp; amp; e).
если второй тест также завершится неудачей, я бы понятия не имел, какое из этих утверждений вызвало сбой. Реальная проблема имеет несколько из этих условий if…

есть ли какой-либо способ протестировать метод, чтобы я знал, почему тест не удался?

Комментарии:

1. Операторы If никогда не «имеют проблем». Они делают именно то, что говорят. Вы не тестируете операторы if. Вы тестируете сценарии.

Ответ №1:

Операторы If никогда не «имеют проблем». Они делают именно то, что говорят, в 100% случаев. Нет необходимости тестировать операторы if.

Однако вам следует протестировать отдельные сценарии.

Например:

 function testResultReturnsFalseForADTrue
{
     $input[a => true, $b => false, c => false, d => true, e => false]
     assertFalse(InputFilter->isInputValid);
}
  

если второй тест также завершится неудачей, я бы понятия не имел, какой из них
инструкции вызвали сбой

На самом деле не имеет значения, какой оператор if вызвал сбой. Если вы тестируете этот ввод с помощью A amp; B return false и он возвращает true, у вас уже есть достаточно информации.

Нет способа указать точную строку, которая возвращает true, когда вы ожидаете false или наоборот.

Ответ №2:

Цель модульного тестирования (и тестирования в целом) — найти ошибки. Подход заключается в том, чтобы использовать некоторый код контролируемым образом, чтобы у вас было четкое представление о том, как он ведет себя. Если во время выполнения теста фактическое поведение отличается от ожидаемого, вы должны начать свое расследование с того, в чем проблема. Возможно, вы обнаружили ошибку — или, возможно, тестовый пример неверен! Это показывает, что вы не можете даже предположить, что проблема на самом деле в коде. Часто, в случае неудачного теста, начинается отладка.

Однако, если у вас есть код, как вы показали, безусловно, должно быть намного больше тестовых примеров. Схема неудачных и последующих тестов может помочь вам в вашем расследовании. Критерием качества набора тестов является то, что вы можете легко отследить потенциальную проблему, просмотрев список результатов тестирования.

Ответ №3:

Сделать:

 if($inputA amp;amp; $inputB amp;amp; $inputC){
       return true;     
    }
  

Функция, которую вы вызываете в своей функции. И затем:

 if($inputD amp;amp; $inputE){
  return true;     
}
  

Другая функция, которую вы вызываете.

А затем выполнить тесты для этих функций

Комментарии:

1. Спасибо за ваш ответ. Эти функции были бы закрытыми, потому что не было бы причин делать их видимыми для других классов. И из того, что я прочитал, тестирование частных методов считается плохой практикой.