Как мне выполнить модульное тестирование этой процедуры PL / SQL? (используя utplsql) - PullRequest
2 голосов
/ 14 июля 2009

Пакет очень очень простой. Проходит курсором и обновляет 2 значения, где значения record_ids равны.

Какой тестовый модуль подходит для такого рода процедур?

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

PROCEDURE set_shift_times_to_null( RETVAL OUT VARCHAR2,
                                 ERRBUF OUT VARCHAR2,
                                RECORDS_UPDATED OUT NUMBER) IS 

   CURSOR evening_shift_employees_cur IS
   select employee
   FROM employees
   where SHIFT='EVENING'
   ;

BEGIN
   RECORDS_UPDATED := 0;
   RETVAL := '2';

   FOR evening_shift_employees IN evening_shift_employees_cur LOOP
      UPDATE NIGHT_SHIFT 
      Set SOME_DUMB_FIELD = evening_shift_employees.employee;

      RECORDS_UPDATED := RECORDS_UPDATED + 1;
   END LOOP;
   COMMIT;
   RETVAL := 0;
EXCEPTION WHEN OTHERS THEN
   ROLLBACK;
   ERRBUF := 'Error occurred - ' || SQLERRM;
END set_shift_times_to_null;

Ответы [ 5 ]

1 голос
/ 15 июля 2009

Пара предложений.

Использовать SQL% ROWCOUNT:

BEGIN
  UPDATE NIGHT_SHIFT
   Set SOME_DUMB_FIELD = evening_shift_employees.employee;
  v_rows_processed := SQL%ROWCOUNT;
  dbms_output.put_line('There were '||v_rows_processed||' rows updated');
END;

Не использовать, когда другие (почему вы хотите потерять трассировку стека). Просто используйте исключения, вы будете полагаться на вызывающего, чтобы проверить содержимое ошибки

begin
  insert into t values ( 1 );
  exception when others then 
  log_error; 
  raise; 
end;

Реализация log_error выглядит так:

create or replace procedure log_error
as
  pragma autonomous_transaction;
  l_whence varchar2(1024);
  l_msg    varchar2(1020) default sqlerrm;
  l_code   number default sqlcode;
  begin
    l_whence := whence;
    insert into error_table
     ( timestamp, whence, msg, code )
    values
     ( sysdate, whence, l_msg, l_code );
    commit;
   exception
  when others then
   rollback;
   raise;
  end;

Не используйте какой-либо pl / sql. На первый взгляд, обновление выглядит полностью выполнимым без курсора. Возможно обновляемое встроенное представление:

update (
  select e.sal as emp_sal, e.comm as emp_comm,
    ns.sal as ns_sal, ns.sal/2 as ns_comm
  from employees e, night_shift ns
  where e.deptno = ns.deptno
  ) 
set emp_sal = ns_sal, emp_comm = ns_comm
1 голос
/ 14 июля 2009

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

Вы можете создавать временные таблицы с ожидаемыми результатами, а код модульного тестирования сравнивает результаты. Конечно, это тяжелая работа, но если вы хотите проверить, вы должны сделать что-то вроде этого.

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

Многие условия должны быть проверены с ограничениями, а процедуры тестового модуля должны выполнять код, который вынуждает базу данных проверять эти ограничения (вставки и т. Д.).

0 голосов
/ 28 июля 2009

Для всех, кто видит это, я нашел это в документации по utplsql: PROCEDURE utAssert.eqtable (

   msg_in IN VARCHAR2,
   check_this_in IN VARCHAR2,
   against_this_in IN VARCHAR2,
   check_where_in IN VARCHAR2 := NULL,
   against_where_in IN VARCHAR2 := NULL,
   raise_exc_in IN BOOLEAN := FALSE
);

Это по документации assert; похоже, он делает именно то, что я пытался сделать.

0 голосов
/ 15 июля 2009

То, что я закончил, было следующим:

  1. Возьмите количество записей, что основной курсор обновит поля до нуля
  2. выполнить процедуру (возвращает значение обновленных строк)
  3. Взять количество записей из тех же записей, что и в первый раз
  4. Разница между количеством записей должна равняться количеству записей, обновленных в процедуре. Если это так, тест проходит успешно.

Имеет ли это смысл, или это круговая логика?

0 голосов
/ 14 июля 2009

По сути, вы хотите использовать все возможности вашей процедуры:

  • Тест с одинаковыми идентификаторами записи.
  • Тест с неравными идентификаторами записи.
  • Тест с недействительными (нецелыми? Отрицательными?) Идентификаторами записей.

Также проверьте граничные условия:

  • Тест с отключенными идентификаторами записей (например, 104 и 105).
  • Тест с максимальным идентификатором записи (MAX_INT?).
  • Тест с идентификатором записи с нулевым значением.

Вот хороший пример хороших методов юнит-тестирования.

РЕДАКТИРОВАТЬ: я не знаю надежного инструмента модульного тестирования для запросов к базе данных. Я бы настроил тестовую таблицу вечером_shift_employees с различными условиями идентификатора записи, как описано выше. Затем, в соответствии с предложением FerranB, убедитесь, что записи обновлены в соответствии с ожиданиями для проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...