Тестирование программ PL/SQL: технологии, рекомендации и автоматизация

Стас Белков

Стас Белков

Автор статьи. Известный специалист в мире IT. Консультант по продуктам и решениям Oracle. Практикующий программист и администратор баз данных. Подробнее.

Тестирование программ PL/SQLВсем нам нравится создавать что-то новое — собственно, это одна из причин, по которой мы занимаемся программированием. Мы берем интересную задачу и придумываем способ ее реализации на языке PL/SQL.

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


Оглавление статьи[Показать]


Таким образом, программы почти всегда нуждаются в дополнительном тестировании. Как повысить его эффективность в мире PL/SQL?

Для начала мы рассмотрим типичный пример неудачного процесса тестирования. Затем будут представлены выводы относительно ключевых проблем ручного тестирования, и мы познакомимся со средствами автоматизированного тестирования кода PL/SQL.

 

Типичные неэффективные технологии тестирования

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

Это очень хорошее общее описание процесса тестирования; остается выяснить, как определить все необходимые тестовые сценарии и реализовать тесты. Начнем с весьма типичного (и к сожалению, неэффективного) подхода к тестированию.

Допустим, мы пишем большое приложение, обрабатывающее большое количество строк. В PL/SQL имеется функция SUBSTR, которая возвращает заданную часть строки. Однако ее использование связано с некоторыми проблемами. Дело в том, что эту функцию удобно применять, когда вы знаете начальную позицию и длину строки. Однако очень часто известно лишь местоположение начального (start) и конечного (end) символов, а длину строки приходится вычислять. Но по какой формуле? Чтобы не мучиться с вычислениями (кстати говоря, правильный ответ end — start + 1), мы напишем функцию betwnstr, которая произведет все вычисления за нас:


FUNCTION betwnstr (string_in IN VARCHAR2 
                  ,start_in IN INTEGER 
                  ,end_in IN INTEGER
)
   RETURN VARCHAR2 
IS
BEGIN
   RETURN (SUBSTR ( string_in, start_in, end_in - start_in + 1));
END betwnstr;

К сожалению, объем работы весьма велик, а это всего лишь одна из множества написанных программ, которую необходимо протестировать. Мы пишем примитивный «тестовый сценарий» с использованием DBMS_OUTPUT.PUT_LINE и запускаем его:

BEGIN
   DBMS_OUTPUT.put_line (NVL (betwnstr ('abcdefg', 3, 5)
                           , '**Really NULL**'));
END;

cde

Работает... надо же! Но одного теста недостаточно. Давайте зададим конечное значение за пределами строки — например, 500. Функция должна вернуть остаток строки, как бы это сделала функция SUBSTR:

BEGIN
   DBMS_OUTPUT.put_line (NVL (betwnstr ('abcdefg', 3, 500)
                           , '**Really NULL**'));
END;

cdefg

Снова работает! Теперь нужно убедиться в том, что функция правильно работает со значениями NULL:

BEGIN
   DBMS_OUTPUT.put_line (NVL (betwnstr ('abcdefg', NULL, 5)
                           , '**Really NULL**'));
END;

**Really NULL**) );

Три из трех! Функция работает правильно, скажете вы? Нет — скорее всего, вы покачаете головой и скажете себе: «Такое тестирование даже в первом приближении не проверяет все возможные сценарии. Оно даже не изменяет значение первого аргумента! К тому же при каждом изменении входных значений предыдущий тест терялся».

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

 

разные значения аргументов

 

На основании этой таблицы строится простой сценарий следующего вида:


BEGIN
   DBMS_OUTPUT.put_line ('Test 1: ' || betwnstr (NULL, 3, 5));
   DBMS_OUTPUT.put_line ('Test 2: ' || betwnstr ('abcdefgh', 0, 5));
   DBMS_OUTPUT.put_line ('Test 3: ' || betwnstr ('abcdefgh', 3, 5));
   DBMS_OUTPUT.put_line ('Test 4: ' || betwnstr ('abcdefgh', -3, -5));
   DBMS_OUTPUT.put_line ('Test 5: ' || betwnstr ('abcdefgh', NULL, 5));
   DBMS_OUTPUT.put_line ('Test 6: ' || betwnstr ('abcdefgh', 3, NULL));
   DBMS_OUTPUT.put_line ('Test 7: ' || betwnstr ('abcdefgh', 3, 100));
END;

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

SQL> @betwnstr.tst
Test 1:
Test 2: abcdef 
Test 3: cde 
Test 4:
Test 5:
Test 6:
Test 7: cdefgh

«Проверим результаты»... Легко сказать, но как это сделать? Как узнать, прошли ли тесты? Нам придется просматривать результаты строку за строкой и проверять их по таблице. К тому же при действительно тщательном тестировании у нас будет более 30 тестовых сценариев (не забыли об отрицательных значениях начальной и конечной позиции?). На просмотр результатов уйдет несколько минут, и это для совершенно тривиального кода. Сама мысль о распространении этой методики на «реальный» код выглядит устрашающе. А теперь представьте, что программа изменяет две таблицы и возвращает два аргумента OUT. Счет тестовых сценариев пойдет на сотни, да еще добавьте к этому проблемы настройки конфигурации и проверку правильности содержимого таблиц.

И все же многие разработчики выбирают этот путь при «тестировании» своего кода. Почти все проводимое тестирование обладает рядом ключевых недостатков:

Если вы хотите, чтобы тестирование было действительно эффективным и тщательным, необходимо действовать иначе. Тесты должны определяться так, чтобы они могли легко сопровождаться с течением времени. Мы должны иметь возможность легко проводить тестирование и, что еще важнее, — без продолжительного анализа определить результат: успех или неудача. При этом выполнение тестов не должно требовать написания больших объемов тестового кода.

Далее я сначала дам несколько советов относительно того, как организовать тестирование вашего кода. Затем будут рассмотрены средства автоматизации тестирования для разработчиков PL/SQL; особое внимание будет уделено utPLSQL и Quest Code Tester for Oracle.

 

Общие рекомендации по тестированию кода PL/SQL

Выбор инструмента тестирования зависит только от вас, но для повышения качества тестирования следует принять во внимание следующие факторы:

 

Средства автоматизации тестирования программ PL/SQL

В наши дни разработчики PL/SQL могут использовать целый ряд автоматизированных инфраструктур и средств тестирования своего кода:

Вас заинтересует / Intresting for you:

Управление приложениями PL/SQL...
Управление приложениями PL/SQL... 4651 просмотров Stas Belkov Thu, 16 Jul 2020, 06:20:48
Встроенные методы коллекций PL...
Встроенные методы коллекций PL... 14838 просмотров sepia Tue, 29 Oct 2019, 09:54:01
Программирование динамического...
Программирование динамического... 4919 просмотров Максим Николенко Sun, 09 Sep 2018, 06:56:23
Работа с числами в PL/SQL на п...
Работа с числами в PL/SQL на п... 45206 просмотров Antoniy Mon, 28 May 2018, 16:45:11
Печать
Войдите чтобы комментировать

apv аватар
apv ответил в теме #9676 3 года 9 мес. назад
Превосходный обзор методик тестирования кода PL/SQL в ручном и автоматическом режиме! Автору огромная благодарность!