Пока жизнь не научит, тестировщик будет писать в багах кратенько «проверил, вроде все ок». Ну или чуть подробнее «проверил на файлах с данными по ФИО русскими, казахскими, японскими. Все ок!».
А спустя полгода надо будет сделать аналогичную задачу. Найдешь исходную в надежде быстренько воспроизвести. Но нет... Данных никаких, придумывай, родной, заново русские, японские и казахские ФИО, подходящие под задачу. Иногда даже через неделю или день приходится возвращаться к задаче, а уже все забыл.
Конечно, если просто брать то, что было раньше — попадетесь на эффекте пестицида. Кейсы менять можно и нужно! Но «базовый набор» для быстрого воспоизведения — записывайте, не жалейте места в комментарии. Зато «я-будущий» скажет вам потом спасибо.
Пара примеров из практики, когда инструкция по верификации бага облегчает жизнь в будущем:
Исходная постановка — после выполнения задачи в таблицу БД записывается время завершения. Если оборвать соединение с базой ровно в тот момент, когда сама задача отработала и идет обновление статуса в БД — задача остается «висеть» как незавершенная.
Разработчик отписался — «Не освобождали lock при падении на этапе обновления статуса задачи. Теперь освобождается». Класс! А тестировать такое как?
Уточнила у разработчика и переписала его инструкцию в JIRA, добавив деталей от себя:
================================================================
1. Создаем триггер на таблице task_execution, который будет ломаться на обновлении enddate с null на не null
{code:sql}
CREATE OR REPLACE TRIGGER test_trigger
BEFORE UPDATE ON task_execution FOR EACH ROW
BEGIN
IF :new.end_date IS not NULL and :old.end_date is null THEN
raise_application_error(-20001, 'failed to update end date');
END IF;
END;
/
{code}
2. Запускаем триггер, он должен сломаться на завершении первой джобы — «тут имя конкретного триггера, чтобы не напрягать потом мозг, на чем конкретно воспроизводить»
3. В конце всех тестов не забываем удалить триггер
{code:sql}
drop trigger test_trigger;
{code}
================================================================
Слабо такое запомнить?
Проверила, что-то не понравилось. Отписалась о результатах. Разработчик поправил на следующий день, надо с нуля воспроизводить. Я повторяю все по своему комментарию и ловлю себя на мысли — «Не занесла бы в джиру, сейчас бы думала, как триггер создать или листала скайп-чат с разработчиком в поисках этой переписки». А так все под рукой. И даже через полгода можно за 2 минуты воспроизвести в рамках регрессии
Ведь на самом деле иногда даже над простым запросом тупишь, забываешь, как именно update делается и лезешь в доку оракла за примером. Поэтому, если при ручной проверке фигурирует sql, я его записываю! И часто это очень помогает в будущем.
Решили сделать улучшение — если запрос к базе висит какое-то время, задача падает с ошибкой. А то мало ли...
Комментарий разработчика при резолве задачи:
Готово.
Нашел два механизма, выполняющие потенциально долгие SQL-вызовы:
- performer
- connector
Для тестирования можно эмулировать долгий запрос выражением
{code:sql}
CALL SYS.DBMS_LOCK.SLEEP(60); -- в секундах
{code}
В целом, уже неплохое описание, пример вызова sleep-а есть, казалось бы, что еще надо? Но я тоумная наученная горьким опытом. Я не просто пишу «добавила слипы туда и сюда и вызвала такие-то задачи для проверки», нееееет, я пишу пошаговую инструкцию, куда чего добавлять:
================================================================
Для проверки подхачиваем билд:
1. Performer
1.1. Ставим в код sleep на 80 секунд
services\src\main\schema\schema_task_refresh_view.sql → добавляем CALL SYS.DBMS_LOCK.SLEEP(80);.
Получается
{noformat}
CALL SYS.DBMS_LOCK.SLEEP(80);
CALL export_pkg.update_view_1();
CALL export_pkg.update_view_2();
{noformat}
1.2. Ставим таймаут в задаче на 50 секунд
такой-то файл
{code}
вот как должно получиться
{code}
2. Connector
2.1. Добавляем sleep в функцию function_1 → DBMS_LOCK.Sleep( 80 );
такой-то файл
{code:sql}
вот как должно получиться
{code}
2.2. Ставим таймаут в коннекторе
такой-то файл
{code}
вот как должно получиться
{code}
Собираем билд, стартуем триггеры:
1. name_1
2. name_2
Профит!
================================================================
Все проверила, все хорошо. Но хотелось бы не в коде таймаут прописывать, а через GUI. Решили, что «сейчас заморачиваться не будем, сделаем в следующем релизе». И вот спустя пару недель сделали,
Как проверять? Снова вспоминать, куда добавлять слипы, снова вспоминать, чем запись sleep отличается в функции и вне ее... Но зачем? Уже же все для этого есть, готовенькое!
Тут я сказала «себе-прошлой» большое спасибо за подробную инструкцию, по которой все быстро сделала. Особенно удобно в таких ситуациях то, что ты не просто пишешь, куда добавить строку, но и что в итоге должно получиться — очень наглядно!
А вы все еще пишите кратко и каждый раз при воспроизведении этой же или подобной задачи создаете все данные с нуля?
А спустя полгода надо будет сделать аналогичную задачу. Найдешь исходную в надежде быстренько воспроизвести. Но нет... Данных никаких, придумывай, родной, заново русские, японские и казахские ФИО, подходящие под задачу. Иногда даже через неделю или день приходится возвращаться к задаче, а уже все забыл.
Любимые грабельки — не писать,
как проверял задачу
Конечно, если просто брать то, что было раньше — попадетесь на эффекте пестицида. Кейсы менять можно и нужно! Но «базовый набор» для быстрого воспоизведения — записывайте, не жалейте места в комментарии. Зато «я-будущий» скажет вам потом спасибо.
Пара примеров из практики, когда инструкция по верификации бага облегчает жизнь в будущем:
Зависание задачи в оракле
Исходная постановка — после выполнения задачи в таблицу БД записывается время завершения. Если оборвать соединение с базой ровно в тот момент, когда сама задача отработала и идет обновление статуса в БД — задача остается «висеть» как незавершенная.
Разработчик отписался — «Не освобождали lock при падении на этапе обновления статуса задачи. Теперь освобождается». Класс! А тестировать такое как?
Уточнила у разработчика и переписала его инструкцию в JIRA, добавив деталей от себя:
================================================================
1. Создаем триггер на таблице task_execution, который будет ломаться на обновлении enddate с null на не null
{code:sql}
CREATE OR REPLACE TRIGGER test_trigger
BEFORE UPDATE ON task_execution FOR EACH ROW
BEGIN
IF :new.end_date IS not NULL and :old.end_date is null THEN
raise_application_error(-20001, 'failed to update end date');
END IF;
END;
/
{code}
2. Запускаем триггер, он должен сломаться на завершении первой джобы — «тут имя конкретного триггера, чтобы не напрягать потом мозг, на чем конкретно воспроизводить»
3. В конце всех тестов не забываем удалить триггер
{code:sql}
drop trigger test_trigger;
{code}
================================================================
Слабо такое запомнить?
Проверила, что-то не понравилось. Отписалась о результатах. Разработчик поправил на следующий день, надо с нуля воспроизводить. Я повторяю все по своему комментарию и ловлю себя на мысли — «Не занесла бы в джиру, сейчас бы думала, как триггер создать или листала скайп-чат с разработчиком в поисках этой переписки». А так все под рукой. И даже через полгода можно за 2 минуты воспроизвести в рамках регрессии
Ведь на самом деле иногда даже над простым запросом тупишь, забываешь, как именно update делается и лезешь в доку оракла за примером. Поэтому, если при ручной проверке фигурирует sql, я его записываю! И часто это очень помогает в будущем.
Таймауты к базе
Решили сделать улучшение — если запрос к базе висит какое-то время, задача падает с ошибкой. А то мало ли...
Комментарий разработчика при резолве задачи:
Готово.
Нашел два механизма, выполняющие потенциально долгие SQL-вызовы:
- performer
- connector
Для тестирования можно эмулировать долгий запрос выражением
{code:sql}
CALL SYS.DBMS_LOCK.SLEEP(60); -- в секундах
{code}
В целом, уже неплохое описание, пример вызова sleep-а есть, казалось бы, что еще надо? Но я то
================================================================
Для проверки подхачиваем билд:
1. Performer
1.1. Ставим в код sleep на 80 секунд
services\src\main\schema\schema_task_refresh_view.sql → добавляем CALL SYS.DBMS_LOCK.SLEEP(80);.
Получается
{noformat}
CALL SYS.DBMS_LOCK.SLEEP(80);
CALL export_pkg.update_view_1();
CALL export_pkg.update_view_2();
{noformat}
1.2. Ставим таймаут в задаче на 50 секунд
такой-то файл
{code}
вот как должно получиться
{code}
2. Connector
2.1. Добавляем sleep в функцию function_1 → DBMS_LOCK.Sleep( 80 );
такой-то файл
{code:sql}
вот как должно получиться
{code}
2.2. Ставим таймаут в коннекторе
такой-то файл
{code}
вот как должно получиться
{code}
Собираем билд, стартуем триггеры:
1. name_1
2. name_2
Профит!
================================================================
Все проверила, все хорошо. Но хотелось бы не в коде таймаут прописывать, а через GUI. Решили, что «сейчас заморачиваться не будем, сделаем в следующем релизе». И вот спустя пару недель сделали,
Как проверять? Снова вспоминать, куда добавлять слипы, снова вспоминать, чем запись sleep отличается в функции и вне ее... Но зачем? Уже же все для этого есть, готовенькое!
Тут я сказала «себе-прошлой» большое спасибо за подробную инструкцию, по которой все быстро сделала. Особенно удобно в таких ситуациях то, что ты не просто пишешь, куда добавить строку, но и что в итоге должно получиться — очень наглядно!
А вы все еще пишите кратко и каждый раз при воспроизведении этой же или подобной задачи создаете все данные с нуля?
Если описания ошибки/задачи недостаточно и выянялась какая-то полезная инфа в скайпике, то конечно в комменте я ее записываю. Круто когда и другие тестеры делают так же - меньше дергать других людей. Ну а какие-то готовые sql скрипты - вообще маст хэв и благодарность:)
ОтветитьУдалитьВот! Правильно! А я иногда не записываю скрипты, особенно простейшие типа апдейта одного значения, в итоге каждый раз тепряется минута-две на то, чтобы вспомнить, что тут делать))
УдалитьИ все ставить на версионный контроль :)
УдалитьДа да, все конспектировать :)
УдалитьХех... Я в молодости работал в телефонном сервисе сотового оператора. Там меня очень хорошо надрючили записывать обращения клиентов так, чтобы потом не надо было гадать "что это было вообще".
ОтветитьУдалитьА вообще-то за экономию на тексте надо бить по башке не только тестировщиков, но и разработчиков. Сколько раз ко мне приходили таски с описанием в сабджекте "Сделать хрень". и комментарием Done.
Самое весёлое, когда PL из таких разработчиков и работаешь в Agile. За фразу
DoD: Should work when we are there
хочется превентивно убить в колыбели :)
Ну, стена текста это тоже плохо :)
УдалитьНадо искать золотую середину!
Но вот на примере для воспроизведения экономить не рекомендую, да =)