Пример разработки функции Divide

Разберем пример разработки функции деления

Как правило все хотят быстрее выполнить свою работу и что из этого получается. Постановщик пишет спецификацию: Функция
Результат=ФункцияДеления(делитель,делимое)
Математическая формула:
6/3=2

Программист уточняет:
1. какой тип будет данных нужно возвращать целое или нет?
2. Какая будет размерность?

Постановщик говорит
1. целое
2. размерность 4 байта

Программист пишет функцию:

 Function Divide(iA,iB:integer):integer;
 begin
  result:=iA div iB;
 end;

Проверяет работу

 Preedure Test_Divide;
  var iRes: integer;
  begin
    iRes:=Divide(6,3);
    // check resilt
    if iRes<>2 then
      TestFrameWork.ShowError('Error 6/3<>2')
     else     
      TestFrameWork.ShowOk('passed 6/3=2');

Как правило на этом все заканчивается, работа выполнена, функционал работает правильно.

Тестировщик:
1. Изучение спецификации
2. Планирование тест-кейсов
а) Что будет если вместо целого числа ввести дробное число?
б) Если разделить на 0 что будет?

  • программа прекратит работу?
  • будет исключение?
  • вернет случайное значение?
  • вернет специальное число указывающее на ошибку?

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

Постановщик дописывает спецификацию:
«входные параметры только положительные, если делитель ноль то обработать исключение, при ошибочных параметрах или исключении вернуть 0.

Задание уходит разработчику на реализацию.
Программист меняет функцию:

 Function Divide(iA,iB:cardinal):cardinal;
 begin
  if iB = 0 then
   result:=0
  else  
  result:=iA div iB;
 end;

Проверяет работу

 Preedure Test_Divide;
  var iRes: integer;
  begin
    iRes:=Divide(6,3);
    // check resilt
    if iRes<>2 then
      TestFrameWork.ShowError('Error 6/3<>2')
     else     
      TestFrameWork.ShowOk('passed 6/3=2');
 
 
  iRes:=Divide(6,0);
    // check resilt
    if iRes<>0 then
      TestFrameWork.ShowError('Error 6/0=0')
     else     
      TestFrameWork.ShowOk('passed 6/0=0');
 

Потом создает программу Test_Divide.exe в которой тестировщик может вводить свои значения и смотреть результат.

Далее тестировщик проверяет работу в этой программе

  1. определяет диапазон данных для делителя и делимого
    1. начальный диапазон берем числа 0,1,2
    2. средний диапазон - по 3 числа
      1. 65 535 - это битовая половина диапазона
      2. 2 147 483 647 численная половина 4-х байтового положительного целого числа
    3. конечный диапазон $FFFFFFFF - 3 числа

Тестировщик делает тест
0/0=0 - код ошибки
0/1=0 - это не ошибка
1/0=0 - это ошибка

То есть явно не правильная логика обработки ошибок.
Код использующий функцию Divide будет работать не правильно! Он будет считать ошибкой, то что ей не является.
Ноль не должен быть кодом ошибки.
Высылает постановщику тест кейс.
Постановщик соглашается и меняет спецификацию.

«при ошибочных параметрах или исключении вернуть минус 1.»
Программист переписывает код

 Function Divide(iA,iB:cardinal):integer;
 begin
  if iB = 0 then
   result:=-1
  else  
  result:=iA div iB;
 end;

Проверяет работу

 Preedure Test_Divide;
  var iRes: integer;
  begin
    iRes:=Divide(6,3);
    // check resilt
    if iRes<>2 then
      TestFrameWork.ShowError('Error 6/3<>2')
     else     
      TestFrameWork.ShowOk('passed 6/3=2');
 
 
iRes:=Divide(6,0);
    // check resilt
    if iRes<>-1 then
      TestFrameWork.ShowError('Error 6/0=-1')
     else     
      TestFrameWork.ShowOk('passed 6/0=-1');
 
 
iRes:=Divide(0,1);
    // check resilt
    if iRes<>0 then
      TestFrameWork.ShowError('Error 0/1=0')
     else     
      TestFrameWork.ShowOk('passed 0/1=0');
 

На этой самой маленькой и примитивной функции, видно на сколько может изменится спецификация и тесты в момент тестирования и на сколько важно как можно раньше начинать тестирование и писать тест-кейсы еще на этапе написания спецификаций.