Показаны сообщения с ярлыком подготовка тестовых данных. Показать все сообщения
Показаны сообщения с ярлыком подготовка тестовых данных. Показать все сообщения

понедельник, 11 августа 2014 г.

Регистрация по EMAIL


Нерушимое правило

Тестировщикам, особенно начинающим, важно всегда помнить следующий принцип:

Никогда не используйте "левые" email'ы для тестирования.

Не должно быть вымышленных email'ов или email'ов, которые не принадлежат вам, если система рассылает по ним почту. Потому что вы один раз зарегистрировались, а система будет слать туда письма.

Допустим, форма регистрации следующая:


Чтобы ее протестировать, надо ввести N уникальных значений почты:

  • Можно ли оставить имя пустым?
  • Можно ли ввести "Ольга"?
  • А "Олечка"?
  • А "Olga"?
  • А "Киселева-Иванова Раисия Ивановна"?
  • А "%:;*Ц;(*;?%"?
  • А можно ли создать пароль в 1 символ?
  • А можно ли ... ?
Статья не о принципах тест-дизайна, поэтому остановимся на данном списке. Но понятно, что он будет больше раз в 10. И каждый раз регистрировать новый email? Да ну-у-у-у... Если формат эл. почты не проверяется, можно и "123" туда записывать, пока тестируются другие поля. А если проверяется, то "123@mail.ru".

Чем это плохо?

  1. Система на каждый такой "левый" адрес высылает почту, то есть фактически спамит mail.ru по несуществующим адресам. Mail.ru банит такого отправителя как злостного спамера. А менеджер проекта уже отрывает руки тому вредителю, благодаря которому их занесли в черные списки. Вы же не хотите быть таким вредителем, правда? Smile :)
  2. Тексты писем, которые отправляются пользователям, тоже надо тестировать. Если все время вбивать в поле всякую фигню, почту мы в итоге не получим и не сможем ее проверить.
Поэтому неважно, работаете вы на проекте или просто учитесь (в рамках курса для тестировщиков или просто для самообразования выбрали сайт), не портите карму создателям, помните правило!

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

Но, если вы не знаете точно, есть такое или нет - следуйте правилу, не указывайте "левые" email`ы!

А что же тогда делать?

Страдать!


На самом деле не надо страдать, есть выход Smile :)
И даже не надо каждый раз заводить новую почту!


У gmail есть хинт - берете свою почту и добавляете к ней часть с плюсиком.

Например, myMail@gmail.com - это моя почта, так вот
  • myMail+1@gmail.com
  • myMail+2@gmail.com
  • myMail+10@gmail.com
  • maMail+test@gmail.com
будет приходит на myMail@gmail.com.

Пользуйтесь на здоровье и берегите нервы своих менеджеров! Smile :)

PS - Уже скоро стартует мой курс "Онлайн-интенсив для начинающих тестировщиков", в котором мы будем злыми менеджерами, отрывающими головы за невыполнение этого правила Wink ;) Записаться на курс 1-7 сентября.

четверг, 22 августа 2013 г.

ORACLE. Перенос значений из одной таблицы в другую

Вернемся к нашей задачке, которую я рассматривала ранее.

Полностью она выглядит так - у меня есть некая табличка folks, в которой содержатся люди. У людей есть свои уникальные идентификаторы, у половины даже есть телефоны. А я хочу, чтобы телефоны были у всех.

Создаю отдельную табличку для создания нужного количества телефонов. Теперь мне надо данные оттуда перенести в folks, учитывая то, что телефонов нет у 1 человека, 2,3 6, 11 итд. То есть нельзя просто взять и перетащить данные. Надо их распихать в отдельные строки.



Хотя, конечно, один из вариантов решения - создав нужное количесто телефонов отдельно, перенести их как раз скопом, затерев уже существующие.

Но, предположим, что этот вариант нас не устраивает. Как распихать строки из одной таблички в строки из другой?

1. Добавляем поле id к телефонам

alter table phone add ( id INTEGER );
commit; 

2. Заполняем новую колонку значениями id тех людей, у которых еще нет телефонов.

insert into phone (id)
(select a.id from
((SELECT  
  rownum AS rw_id, 
  id  
FROM folks WHERE phone_number IS NULL) a
JOIN
  (SELECT rownum AS rw_id  
  FROM phone
  ) b
ON (a.rw_id=b.rw_id)));

commit;

3. Метчим 2 таблицы по id людей!

MERGE INTO folks b USING phone ab ON (b.id = ab.id)
WHEN MATCHED THEN
  UPDATE
  SET b.filed_1    = ab.filed_1,
    b.filed_2      = ab.filed_2,
    b.filed_3      = ab.filed_3,
    b.filed_4      = ab.filed_4,
    b.filed_5      = ab.filed_5,
    b.filed_6      = ab.filed_6,
    b.filed_7      = ab.filed_7,
    b.phone_number = ab.phone_number,
    b.filed_9      = ab.filed_9;
    
commit;

Все Smile :)

ORACLE. Функция TRANSLATE

Конечно же, реальность немного сложнее, чем прогон тестовых данных. Что, кстати, только подтверждает следующие факты:

  • Изначально идея должна проверяться на модульных тестах - небольших объемах данных, очень простых. Потому что, если не работает простенькая функция, но обнаруживаем мы это спустя 3 часа регрессии - это не гуд.
  • После модульных тестов прогоняем интеграционные, потому что, если что-то работает на маленьких тестовых данных, не факт, что будет так же хорошо работать на больших и более-менее реальных объемах.

Итак, настоящая задача - есть у меня табличка с телефонами. Примерно такая

CREATE TABLE phone (
  field_01 NUMBER,
  field_02 DATE,
  field_03 VARCHAR2(50 byte),
  field_04 NUMBER,
  field_05 VARCHAR2(100 byte),
  field_06 VARCHAR2(100 byte),
  field_07 CHAR(100 byte),
  phone_number VARCHAR2(100 byte),
  field_09 VARCHAR2(100 byte)
);


И мне надо 100 телефонов превратить в 200 (реальные данные, конечно, чуть-чуть побольше Smile :) ). Дублирующиеся данные - зло, тестировать лучше на уникальных. Что делать? А почему бы и не прибавить к уже существующим телефонам 100 или 1000?

Сказано, сделано. Проверила сначала сам запрос, как мне строку (varchar2) превратить в число, прибавить к нему что-то и потом сконвертировать обратно. Тест прошел успешно.

Но, когда я этот запрос применила к реальной табличке

INSERT INTO phone (
  field_01,
  field_02,
  field_03,
  field_04,
  field_05,
  field_06,
  field_07,
  phone_number,
  field_09
)
(SELECT
  field_01,
  field_02,
  field_03,
  field_04,
  field_05,
  field_06,
  field_07,
  to_char(to_number(phone_number)+10),
  field_09
from phone);

То словила неприятный эксепшен "Invalid number".
В чем дело? Да в том, что телефоны можно записать по разному:
  • 111-11-11
  • 8 926 11 22 345
  • 8 (926) 111-22-34
  • ...
И вот всякие строки с тире в число уже так просто не переведешь...
Что делать? 

Можно воспользоваться функцией TRANSLATE Функция TRANSLATE анализирует строку str и заменяет в ней все символы, встречающиеся в строке from_mask, на соответствующие символы из to_mask. Для корректной работы функции строки from_mask и to_mask должны иметь одинаковую длину или строка from_mask должна быть длиннее, чем to_mask. Если from_mask длинее, чем to_mask, и в процессе обработки строки str обнаружатся символы, соответствующие одному из символов from_mask, и при этом им не найдется соответствия в to_mask, то такие символы будут удалены из строки str. Если передать from_mask или to_mask, равное NULL, то функция возвратит значение NULL. Сравнение производится с учетом регистра.

Отлично! Накладываем маску "0123456789", все, что ей соответствует, заменим на пробел. 
А потом применим к ней trim - обрезание пробелов в начале и в конце.

И если функция TRANSLATE после обрезания пробелов вернет нам null (то есть в ней больше ничего и не было) - значит, это число! Можно смело добавлять к нему 10, 20 или сколько там нам нужно.

А вот если функция вернет не null, то там не число. И, чтобы не влететь на эксепшен, лучше просто сгенерировать рандомное значение в определенном диапазоне. Так как у меня Мегафон, то и данные я генерю для 926 Smile :)

Получается, нам надо "или или" - в этом нам поможет оператор CASE. Получаем

case when trim(TRANSLATE(to_char(p01_phone_number_txt),'0123456789', ' ')) is null
  then to_char(to_number(phone_number) + 1111)
  else to_char(trunc(dbms_random.value(89261111111,89268888888), 0))
end

Функция trunc(x, 0) делает число x целочисленным, так как dbms_random генерирует дробные значения.

Иииии, запускаем весь запрос

INSERT INTO phone (
  field_01,
  field_02,
  field_03,
  field_04,
  field_05,
  field_06,
  field_07,
  phone_number,
  field_09
)
(SELECT
  field_01,
  field_02,
  field_03,
  field_04,
  field_05,
  field_06,
  field_07,
  case when trim(TRANSLATE(to_char(p01_phone_number_txt),'0123456789', ' ')) is null
  then to_char(to_number(phone_number) + 1111)
  else to_char(trunc(dbms_random.value(89261111111,89268888888), 0))
end,
  field_09
from phone);

И снова получаем  "Invalid number" о_О

Смотрим на данные, применив к ним trim(TRANSLATE(to_char(p01_phone_number_txt),'0123456789', ' '))

Видим, что у нас есть некоторые значения формата "892611 22345". С пробелом посередине. И опять, с пробелом - не число, преобразовывать не буду. А, проходя через функцию, получаются ведь все пробелы, что подпадает под первое условие. Функция считает, что мы получили число и радостно отдает его в then, где не менее радостно падает, так как число с пробелом посередине числом не является.

Что делать? Повсюду баги, блин... 
Приходится изгаляться, чтобы их обойти - в функции then прописываем еще один TRANSLATE, который заменит нам все пробелы на нули.

Ну и заодно обрежем строку, а то получим на выходе больше 11 символов - и опять все упадет...
substr(x,1,11) - берет строку x и, начиная обрезает все после 11 символа (считать начинает с 1).

Получаем case:

case when trim(TRANSLATE(to_char(p01_phone_number_txt),'0123456789', ' ')) is null
  then to_char(to_number(substr(TRANSLATE(trim(p01_phone_number_txt),' ','0'),1,11)) + 1111)
  else to_char(trunc(dbms_random.value(89261111111,89268888888), 0))
end

А полный запрос:

INSERT INTO phone (
  field_01,
  field_02,
  field_03,
  field_04,
  field_05,
  field_06,
  field_07,
  phone_number,
  field_09
)
(SELECT
  field_01,
  field_02,
  field_03,
  field_04,
  field_05,
  field_06,
  field_07,
  case when trim(TRANSLATE(to_char(p01_phone_number_txt),'0123456789', ' ')) is null
  then to_char(to_number(substr(TRANSLATE(trim(p01_phone_number_txt),' ','0'),1,11)) + 1111)
  else to_char(trunc(dbms_random.value(89261111111,89268888888), 0))
end,
  field_09
from phone);

среда, 21 августа 2013 г.

Notepad++, небольшие регэкспы

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



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

Итак, есть схема создания некой таблички

CREATE TABLE test (
  field_01 NUMBER,
  field_02 DATE,
  field_03 VARCHAR2(50 byte),
  field_04 NUMBER,
  field_05 VARCHAR2(100 byte),
  field_06 VARCHAR2(100 byte),
  field_07 CHAR(100 byte),
  field_08 VARCHAR2(100 byte),
  field_09 VARCHAR2(100 byte)
);

Нам надо взять все эти поля и переложить в табличку test_data.
Ищем и заменяем:

Примеры написаны в стиле

  • Find - то, что ищем
  • Replace - то, на что заменяем
Поехали, большинство замен шли в режиме регулярных выражений:
  • VARCHAR2\(.* byte\),
  • ,
Тут важно помнить о том, что скобки надо заэкранировать, иначе результат будет нулевой.

Также убираем CHAR и NUMBER, последнюю строку вручную, ну или убрать потом из find запятую. Дата:
  • \sDATE
  • пусто
Тут, опять же, важно не забыть про "\s", иначе по закону подлости, обязательно найдутся поля вида field_date_2, а оттуда нам вырезать ничего не надо.

Отлично, все вырезали, получили примерно так


SELECT (
  field_01 ,
  field_02 ,
  field_03 ,
  field_04 ,
  field_05 ,
  field_06 ,
  field_07 ,
  field_08 ,
  field_09  
)...;


А теперь мы хотим сметчить эти поля в test_data и test. И получить что-то типа


WHEN MATCHED THEN
  UPDATE
  SET b.field = ab.field

Только для всех полей. Ок, сначала удаляем все пробелы
  • \s
  • пусто
Потом пишем
  • (.*),
  • b.\1 = ab.\1,
Тут, опять же, важно помнить, что в поле replace мы для подстановки группы из регулярного выражения должны писать "\", а не "$".

Ну и наконец, простейший пример Smile :)

Нам надо взять названия наших филдов

  field_01 ,
  field_02 ,
  field_03 ,
  field_04 ,
  field_05 ,
  field_06 ,
  field_07 ,
  field_08 ,
  field_09

И переложить в одну строку, чтобы потом добавить в файл с тестовыми данными. Казалось бы, элементарно
  • $
  • пусто
Но тут возникает проблема - блокнот находит конец строки, и даже типа делает замену, только внешний вид текста не меняется. Что делать? Переключаем на расширенный режим (Extended) и вводим
  •  \r\n
  • пусто
Такие вот небольшие примеры из жизни тестировщика, подготавливающего тестовые данные Smile :)

вторник, 20 августа 2013 г.

ORACLE. Размножение чисел добавлением к ним 10

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

Итак - у нас есть табличка, в ней числовые данные, но тип у них VARCHAR2.
Надо их переложить в другую таблицу, а потом еще раз переложить, но добавив к значениям 10 (20, 30 - не важно), чтобы не дублировать значения.



Проверяем на маленьком объеме (модульное тестирование).

Создаем таблички

create table test (id number, data VARCHAR2(60 byte));
create table test_data (id number, data VARCHAR2(60 byte));

insert into test values (1, 1);
insert into test values (2, 2);
insert into test values (3, 3);
commit;

Проверяем, что получилось:

select * from test;
select * from test_data;

Заполняем таблицу test_data значениями таблицы test

insert into test_data (data) 
select data from test;
commit;

А теперь нам надо добавить к ним какое-то число.
Для этого мы берем строку, конвертируем ее в число, добавляем 10, а потом конвертируем обратно в строку.

insert into test_data (data) 
(select to_char(to_number(data)+10) from test);

commit;

Вот и все Smile :)