понедельник, 23 сентября 2013 г.

Выездная школа тест-менеджеров

Только что вернулась с замечательного мероприятия - выездной школы тест-менеджеров.
И хочу сказать, что было очень здорово! Мы и поучились, и поиграли в тематические игры, и поиграли в простые игры Smile :)

Это если кратко. Но я же кратко не умею, так что дальше подробно.
Место проведения - Подмосковная агроусадьба Ранчо. Начало в 6 часов вечера в пятницу. Большой плюс, что можно спокойно за 1,5 часика добраться с Савеловского вокзала. Правда, на вокзал тоже надо доехать и что-то как-то я поздно с работы вышла, добралась до поезда - целый квест был (указатели, блин, надо точнее делать), но мы успели сесть в него за 2 минуты до отправления!

В поезде мы ехали с моей уже хорошей знакомой Юлей Свистуновой, которая, кстати, обещала предоставить собственный отчет не позже, чем во вторник (24.09.2013) вечером Smile :)

Потрещали, немного познакомились с юношами, которые ехали с нами. От станции за 200 рублей на такси - меньше, чем по 100р с носа, отлично! Приехали раньше организаторов, но нас заселили, что огромный плюс! А то бы уперлись "в 6 и точка" и все...

Заселились и стали играть. Так немного и познакомились. И ребятам "Алиас" показали. А потом приехала Наташа Руколь, рассказала о правилах и мы окончательно расселились. В нашей комнате ноутбуки размножались делением Smile :) Или почкованием?


Ну, неважно. Вскоре началось самое интересное - лекция!



Что хорошо в оффлайн версии?

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

Ах да, кстати, лекция то была вчера, в субботу утром. Ну а в пятницу вечером ребята пока собрались, пока расселились, в общем, вскоре уже все играли в шляпу и алиас. Так и познакомились. А утром Наташа Руколь встала в 8 утра (!!!), чтобы съездить в город и привезти нам завтрак. Это вообще очень круто, тем более что для Наташи это почти подвиг, так рано встать. Очень приятно, что ради нас она на это готова Smile :)

А я, кстати, прохожу еще онлайн курс по ШТМ, перед отпуском он заканчивался, но я попросила себе отсрочку. Так что в субботу утром, проводив Наташу, я не легла обратно спать, а включила ноутбук (моя прелесть!) и посмотрела 7 лекцию, последнюю лекцию с домашним заданием. Вот так продуктивно прошло мое утро.

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

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

Ну а потом был обед и тематические игры вечером! Секреты игр полностью раскрывать не буду, хотя вторая мне не очень понравилась. Но я просто с этим сталкиваюсь не первый тренинг уже, вот у Бескова была, также было - собрали незнакомых людей в команду и дали 10 минут требования записать (условно). Люди в команде спорят, повторяют работу итд итп.

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

А когда собираются незнакомые люди, начинается хаос. И ты или берешь на себя функции менеджера или делаешь, как скажут. Я вот НЕ ХОЧУ брать на себя в такой ситуации функции менеджера, но такая работа с команде меня убивает. Я вроде смотрю на это и внутри понимаю, что нам сейчас надо делать не так, но тут я больше интроверт. Мне хочется пойти в темный уголочек и сделать задачу самой. А не пытаться что-то кому-то доказать.

Тем более что задачку для тестовых целей дают простую, с которой проще разобраться одному. И толпа народа только мешает. Сколько надо человек лампочку вкрутить? 6! Один вкручивает, остальные менеджеры, указания раздают. Именно поэтому всякие скрамы и аджайлы внедряют в маленьких командах, в большой такое не прокатит. Вместо короткого митинга будет много потери времени.

Но и тут можно вынести полезные идеи. Я, например, не просто играла в подобную игру, я уже тестировала это приложение. И все равно, пару умных вопросов мы "аналитику" задали, а про пару забыли. Вот просто забыли. Казалось бы, они элементарные + на тренинге о них уже слышал, да и вообще, привет капитану очевидности. А вот ведь, на деле то не задаешь, нет такой привычки. Уже очень полезный вывод, я считаю.

Тем не менее, после тематических игр мы снова вернулись к алиасу и вечер прошел на ура!

А наутро снова в строй и ручку в зубы Smile :)




На этот раз тема была про мотивацию. И делегирование. И проекции! Очень интересная и спорная тема. На этот раз было много вопросов из зала. И не только вопросов, но и комментариев и даже споров.

Организаторы разбирали все эти кейсы - Наташа садилась поближе, а у нее, кстати, был помощник, Андрей Мясников (А вот и его отчетик)!! Он тоже очень многое для нас сделал в этой школе, в частности, замутил пару прикольных игр (в том числе тематических), за что ему отдельное спасибо!!



Вопросы и примеры были самые разные. Вот, например, один:

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

А ему это было не надо!!! Менеджер спроецировал себя "я хочу повышения, и все хотят, и он хочет". И целый год пытался этот автоматизатор их убедить, что они не правы, а потом пришел к Наташе на собеседование:

- Ого, ты работал начальником автоматизаторов, а к нам простым просишься... Почему?
- Да не хочу я быть начальником!
- Погоди... А до начальства пытался донести мысль?
- Да.
- А, может, вам грамотные автоматизаторы не нужны?
- Нужны!!

Ну и смысл тогда держать человека на нелюбимой должности?

И опять же, кто-то с чем-то не согласен, начинаются споры, примеры из практики и т.д. и т.п. В общем, очень классно!

А потом снова тематические игры, которые повернулись очень внезапно)) Один из коллег решил показать нам отличие краткосрочных результатов от долгосрочных. Дали задание делиться конфетками. И вот он подходил (ко мне, например), "а давай меняться, все мои на все твои, всем будет по + в карму". Я даю и вижу, что он мне только одну свою протягивает. И как-то так подозрительно, прямо чуяла подвох, но доверие победило. А Вася забрал мои конфетки, улыбнулся и сказал "Ну, а остальное я отдам тебе потом, о сроках мы не договаривались". И все, ушел.

Потом выяснилось, что он так еще парочку одурачил и больше с ним уже никто не менялся. Причем ладно бы он это сделал, именно чтобы краткосрочность от долгосрочности отличить. Но он очень хотел высказаться "а почему я это сделал" и, когда ему дали такую возможность, сказал "А все хотели смухлевать, дать мне 3 и получить 3, получить +3 за обмен, а не за само задание. Я просто на этом сыграл".

Но при чем тут мухлеж? Обмен, это вполне нормальная практика. Вы нам деньги, мы вам софт. Так наши отношения в ИТ и строятся, в общем-то. Но зато игра получилась очень показательной в плане получения краткосрочной выгоды. Получил ее, да. Но что будет, если сыграть еще раз? А два? А три? Да никто уже такому Васе ничего не даст. И об этом всегда надо помнить.

А вообще, само по себе как-то неправильно. Все воруют и я буду. Все убивают, а я чем хуже? Как-то так. Или "Да, я в споре сказал много лишнего, но это просто защитная реакция и я могу рассказать, на что она идет". Да какая разница, на что, если такие слова в принципе неприемлимы? Странно, в общем. Но крайне показательно. Так что и из этой игры можно вынести пользу Smile :)

Фуф... В принципе, потом было еще немножко алиаса и все поехали по домам.
Ну что я могу сказать? Было интересно послушать чужой опыт. Снова послушать интересные темы и обсудить их. Ну и фан, конечно же, фан.

А еще я в школе успела посмотреть одну запись по ШТМ и обсудить с тренером 2 домашки, что тоже очень даже здорово! Ну и весело провела выходные. что немаловажно.

Большое спасибо организаторам за то, что дали возможность все это сделать!!! И отдельно Наташе Руколь за ранние завтраки, почти что кофе в постель Smile :)

понедельник, 2 сентября 2013 г.

Экстремальный тайм-менеджмент. Николай Мрочковский и Алексей Толкачев



Ссылка на книгу (издательство "Альпина Паблишер").

Книжка внезапно оказалась невероятно интересной и захватывающей дух. Да что тут долго распинаться? Тайланд, внезапный отпуск на 2 недели.2-ой день “в раю”, когда не надо ничего делать. При этом тяжелый перелет и полубессонная ночь перед этим – проблема в том, что, если запустить болезнь, я начинаю тяжело кашлять. И долго. В последним день перед отлетом я так раскашлялась, что в 3 часа утра пошла греть себе молоко, иначе невозможно уже было! А в самолете спать неудобно, да и, опять же, кашель!

Так вот, 2 день в отеле, пришла в номер часов в 7-8 вечера и, вместо того, чтобы поспать (а оооооочень хочется, так и не акклиматизировалась же еще), я сидела и запоем читала книжку. И вот 0:30 ночи по местному времени, я села писать этот отчет (не смотрите на дату публикации, мне есть на что потратить тут деньги, опубликуюсь потом, в лобби на бесплатном интернете).

Обалдеть, больше 4 часов сидела и читала, читала, читала!!! Вообще-то начала я книжку вчера, но дошла только до построения главным героем колеса жизни и первого домашнего задания. И таки да, это не первая книжка по тайм-менеджменту, которую я читаю. Да и вообще не первая моя книжка, так что я знаю, что, если ты что-то прочитал и не поскакал это что-то тут же внедрять, то время, потраченное на обучение, проходит зря!

четверг, 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 :)

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

Светлана Иванова. Мотивация на 100%



Ссылка на книгу (издательство "Альпина Паблишер")

Прочитала книжку по рекомендации Натальи Руколь. Очень любопытная!

Написана довольно простым языком, интересная. А главное - в конце каждой главы идет задание для самостоятельной работы. Это самый эффективный тип книжек, книга-тренинг. Тут главное - не лениться и выполнять задания.

Книжка нужна в первую очередь для менеджеров, в нашем с вами случае - для тест-менеджеров. Она рассказывает о том, что суждение "мотивировать можно только повышением зарплаты" - ложно. Она рассказывает о том, какие еще бывают мотиваторы, как их выявить и что с ними делать дальше.

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

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

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

Кстати, у меня пока не получается посидеть и помедитировать над данным упражнением, но я придумала скрестить его с книжкой "Сначала нарушьте все правила" и поискать таланты, начав с себя. Так что начало положено! Посмотрим, что мне это все принесет, но я вас уверяю - это как минимум интересный опыт. Всем рекомендую Smile :)

PS - Добавила книгу в общий список прочитанных мною книг.