<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Тестирование. Все про автоматизированные, нагрузочные, ручные тесты. Все про обеспечение и контроль качества</title><link>http://alexeybulat.blogspot.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/protesting" /><description>Ручное, автоматизированное, нагрузочное тестирование программного обеспечения.&#xD;
Процессы разработки ПО.</description><language>en</language><managingEditor>noreply@blogger.com (Алексей Булат)</managingEditor><lastBuildDate>Fri, 27 Jan 2012 04:40:05 PST</lastBuildDate><generator>Blogger http://www.blogger.com</generator><openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">75</openSearch:totalResults><openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">1</openSearch:startIndex><openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">25</openSearch:itemsPerPage><feedburner:info uri="protesting" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Technology/Software How-To</media:category><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Education/Training</media:category><itunes:owner><itunes:email>noreply@blogger.com</itunes:email></itunes:owner><itunes:explicit>no</itunes:explicit><itunes:subtitle>Ручное, автоматизированное, нагрузочное тестирование программного обеспечения Процессы разработки ПО</itunes:subtitle><itunes:summary>Ручное, автоматизированное, нагрузочное тестирование программного обеспечения Процессы разработки ПО</itunes:summary><itunes:category text="Technology"><itunes:category text="Software How-To" /></itunes:category><itunes:category text="Education"><itunes:category text="Training" /></itunes:category><item><title>Дипломатия или решаем проблемы грамотно</title><link>http://feedproxy.google.com/~r/protesting/~3/6SUDMep08sI/blog-post.html</link><category>Процессы</category><category>Урок тестирования</category><category>менеджмент</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 23 Jan 2012 03:59:15 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-2874150332525366988</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/C2PYPQu4shut6GH3_fn_CLlYI5k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C2PYPQu4shut6GH3_fn_CLlYI5k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/C2PYPQu4shut6GH3_fn_CLlYI5k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C2PYPQu4shut6GH3_fn_CLlYI5k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Когда вокруг рассеялся дым курительной трубки, старик уже сидел в позе лотоса и медитировал с закрытыми глазами. Минуту стояла полная тишина. Ученики знали, что в такие моменты ему лучше не мешать, дабы не спугнуть ту самую искру вдохновения, выбирающую тему урока, зародившуюся в его голове.&lt;/p&gt;
&lt;p&gt;Старик открыл глаза и сказал:&lt;br/&gt;
- Я рад, что вы пришли, рад что качество и тестирование вам не безразлично, и что вы все без исключения идете по правильному пути. Однако, чтобы стать настоящими багоборцами качества, вам предстоит пройти еще не одно сражение и силой дипломатии, убеждения, а иногда и хитростью дать менеджерам, разработчикам  и архитекторам понять, почему и как именно должно работать приложение, на которое сейчас направлено все Ваше внимание.&lt;/p&gt;
&lt;span class="fullpost"&gt;
&lt;p&gt;- Учитель, а что они сами не понимают, как оно должно работать? - спросила рыженькая девочка с веснушками на щеках.&lt;/p&gt;
&lt;p&gt;- Они конечно же понимают, но в силу того, что каждый из них преследует свои цели, они видят не все. В то время как вы, отвечая за качество, должны знать и видеть все как по частям, так и целиком.&lt;/p&gt;
&lt;p&gt;- А какие у них цели? - тихо, боясь задать глупый вопрос, сквозь зубы процедила девочка.&lt;/p&gt;
&lt;p&gt;- Менеджер стремится сдать проект и получить свой бонус за своевременную сдачу. Архитекторы возводят прочный фундамент и каркас приложения, по необходимости добавляют в него базу данных, и верят, что это венец их творения, и что пока нельзя создать лучше. Программист же пишет красивый код, при этом, восхищаясь его красотой, он не всегда замечает недоработки. Вы же, в случае если ошибки просочатся через стену тестирования, всегда будете крайними. Таким образом, требуя исправления, вы защищаете себя, а значит вы отстаиваете качество продукта ценой собственной репутации, как QA специалистов. И тут уже Вы должны проявить себя хитроумными стратегами. Нужно правильно сказать программисту, что именно эта ошибка делает его код несовершенным и некрасивым, а менеджеру, что из-за нее он не только не получит бонус, но еще и оплатит неустойку за простои в работе клиента.&lt;/p&gt;
&lt;p&gt;Вверх несмело поднялась рука, затем встал невысокого роста аккуратно причесанный "ботаник" и, поправив очки, несмело спросил:&lt;br/&gt;
- Учитель, а вдруг они нас не послушают и не захотят исправлять ошибку, вдруг они посмеются над нами. Что тогда делать?&lt;/p&gt;
&lt;p&gt;- Эх, - вздохнул учитель, который тоже задавался такими вопросами вначале своего пути. - Может и не захотят, может и посмеются. Но! Смеется тот, кто смеется последним. У вас есть секретное оружие - система багтрекинга. Заносите туда описание ошибки, назначайте её на того, кого надо. Если программист вернул её Вам обратно, требуйте его написать комментарий, по какой причине он не хочет исправлять ошибку. Если вы все еще не согласны с тем, что проблему можно оставить, переназначьте её на менеджера, чтобы он принял окончательное решение. Но! Не забудьте обосновать почему, по-вашему, ошибка должна быть исправлена. Таким образом именно менеджер возьмет на себя всю ответственность за проблемы, связанные с той ошибкой.&lt;/p&gt;
&lt;p&gt;- Учитель, на летней практике, у меня был случай, когда я был уверен, что нашел ошибку, но, как оказалось, о подобном сценарии ничего не говорилось в спецификации. Разработчик просто отклонил багрепорт с комментарием "Цэ не баг, цэ фiча". Я был расстроен, но поделать ничего не мог. Как быть в такой ситуации? - спросил "молодой боец" с гелевым ежиком на голове.&lt;/p&gt;
&lt;p&gt;- Да, бывают ситуации, когда наша логика оказывается хитрее спецификации. Вы видите проблему, которую не додумал бизнес аналитик. Вы пишите багрепорт, а разработчик, слепо следующий спецификации, проблему отклоняет. Вы не знаете, что делать, но ведь все просто. Если Вы уверены, что это проблема и что она не описана в спецификации, то спросите у того, кто её писал, а именно -  у бизнес аналитика. И если он согласится, что это был недостаток спецификации, то он обязательно внесет в нее изменения. И тогда вы сможете перенаправить багрепорт разработчику, указав, что спецификация была изменена, и что проблему все-таки придется решить.&lt;/p&gt;
&lt;p&gt;В воздухе на секунду повисла тишина. Ученики обдумывали слова учителя, а учитель вспоминал первые конфликты и первые разрешения спорных ситуаций, первые победы и горечь поражений. И как бы в продолжение он вдруг добавил: &lt;br/&gt;
- У вас всегда будут трудности. Вам всегда надо будет решать проблемы. В одиночку вам трудно. Всегда ищите союзников. Дружите с разработчиками, делитесь проблемами с менеджерами, общайтесь с аналитиками. Черпайте информацию отовсюду. Чем больше вы будете знать о проекте, тем глубже вы будете копать в поисках ошибок, тем интереснее будут ваши багрепорты,  тем ценнее вы будете как сотрудник.&lt;/p&gt;

&lt;p align="center"&gt;*   *   *   *   *&lt;/p&gt;

&lt;p&gt;- На этом урок окончен. - Добавил учитель и, выдохнув, растворился в облаке горько-сладкого табачного дыма.&lt;/p&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-2874150332525366988?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=6SUDMep08sI:lyLIz9RMmhM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=6SUDMep08sI:lyLIz9RMmhM:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=6SUDMep08sI:lyLIz9RMmhM:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=6SUDMep08sI:lyLIz9RMmhM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/6SUDMep08sI" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-23T12:59:15.273+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2012/01/blog-post.html</feedburner:origLink></item><item><title>Процесс, который алмазы точит...</title><link>http://feedproxy.google.com/~r/protesting/~3/9yzLgqYkfoo/blog-post.html</link><category>тестирование ПО</category><category>Процессы</category><category>Урок тестирования</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 23 Jan 2012 03:59:15 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-5441505218992541493</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZGXY0cdVRuu1Q9uVngaoECpi7HA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZGXY0cdVRuu1Q9uVngaoECpi7HA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZGXY0cdVRuu1Q9uVngaoECpi7HA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZGXY0cdVRuu1Q9uVngaoECpi7HA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;Старик убрал седые волосы с морщинистого лба и взглянул на сидящих учеников. Минуту стояла тишина, перебиваемая лишь шорохом ветра.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&amp;nbsp;- Я расскажу вам, что вас ждет, что вам надо будет выучить и что - сделать. Слушайте внимательно и не упускайте ни одной мелочи...&lt;/span&gt;&lt;/div&gt;&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Тестирование начинается не с того момента, когда вам дали рабочее приложение, а намного раньше - как только пошли слухи, что команда будет работать над проектом, можно считать, что вы уже приступили. В голове начинают полниться и томиться мысли-вопросы о том:&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&amp;nbsp;- какой ОН - этот проект?&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&amp;nbsp;- какие у него будут фичи?&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&amp;nbsp;- какие тесты вы проведете?&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&amp;nbsp;- какие интересные дефекты вы там найдете?&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Вы уже предвкушаете кайф, который чувствует ребенок, получая новую долгожданную игрушку.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;И вот пришло время, вы получаете первый комплект артефактов: спецификации, мокапы, планы...&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&amp;nbsp;Старик замолчал на мгновение, вспоминая свой первый тест план.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Учитель, а что же дальше? Что дальше? - зашептали ученики почти в один голос.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Не перебивайте, будьте терпеливей. - сказал старик и продолжил...&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Как заправские тестировщики, имеющие за спиной, как боль поражений, так и радость побед, прошедшие сотни сражений с разными заказчиками, менеджерами, разработчиками, админами и с самим собой, вы начинаете готовиться. Пишите тест план, разрабатываете тест кейсы, оцениваете необходимость использования автоматизации, как нагрузочного, так и функционального тестирования.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Учитель, а что такое автоматизация? - перебил его очкарик в первом ряду.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Это невиданная сила, это дракон, запертый в ящик пандоры, это то, о чем я вам расскажу, когда вы будете готовы. - сказал старый учитель, доставая из кармана курительную трубку...&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Время прошло, и вся документация готова. На каждую ситуацию у вас есть готовая процедура, на каждую функцию готовый комплект тест кейсов. Время расписано по часам. Осталось совсем немного - воплотить, разработанный план в жизнь, и не упустить ничего из виду.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Разработчики подготовили первый билд и небрежно кидают его вам, и просят левым глазком взглянуть на него. Не проходит и часа, как вы уже возвращаете его назад и говорите, что "ЭТО" тестировать невозможно, что через клик приложение "валится", да и ни одна функция не работает, как того требует спецификация. Говорите, что все найденные дефекты записаны в багтрекер и отправляете отчет "&lt;b&gt;smoke test failed!!!&lt;/b&gt;"&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Проектный менеджер вроде бы доволен, что тестировщики знают свое дело, но вот если так и дальше пойдет, то в сроки проект не впишется. Температура его мозга начинает подниматься...&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Руководитель разработки уже не рад, что взял на этот проект двух студентов без опыта, а ведущего программиста отправил в отпуск... Но что поделать, надо работать...&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Учитель, а зачем надо дефекты в багтрекер заносить? Ведь эту версию-то все равно возвращаем обратно. - Спросила рыжая девочка с ярко зеленым глазами.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Всегда надо иметь то, на основании чего мы должны принять приложение в тестирование. Назовем это критериями начала тестирования. В данном случае эти критерии не выполнены, так как основные функции работают крайне плохо или не работают вообще. Если вы просто скажете, что все плохо, то разработчики не будут знать, что им надо исправить. А записав дефекты в багтрекер вы всем показываете, что именно не работает и на основании чего вы не приняли приложение в тестирование. - спокойно сказал учитель, затягивая сладкий табак в легкие.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Учитель, а зачем вообще нужен этот smoke test? Неужели без него нельзя? - спросил паренек в малиновом пиджаке.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Без него то, конечно можно. Но с ним как-то сподручнее. Дымовой тест - делается для того, чтобы понять, можно ли вообще тестировать приложение или нет, соответствует ли оно требуемым критериям качества для начала тестирования или нет. Нет смысла проверять то, как далеко стреляет лук, если тетива на нем не натянута, да и стрела кривая. - с ухмылкой ответил учитель и продолжил...&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;К утру следующего дня вам дают новый билд, однако уже с ним приходит письмо со списком того, что якобы готово на 100%, а что пока трогать нет смысла, т.к. ребята в поте лица стараются сделать все, что в их силах, но пока "никак не выходит у них каменный цветок".&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;На этот раз Вас не обманули - все критические баги, находящиеся на поверхности, были исправлены. С гордостью за разработчиков и за их труды вы отправляете отчет, что &lt;b&gt;smoke test passed&lt;/b&gt;.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Менеджер проекта доволен, руководитель разработки улыбается, т.к. он единственный кто знает, что творится в коде :)&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Вы же, открыв багтрекер, начинаете &lt;b&gt;р&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&lt;b&gt;егрессионное тестирование&lt;/b&gt; (&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Regression testing) &amp;nbsp;и&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&lt;b&gt;санитарное тестирование&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;&amp;nbsp;(&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Sanity testing&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;). Вы перепроверяете дефекты, которые разработчики перевели в статус Fixed (Исправлено), Rejected, Can't Reproduce и т.д. Замечу, что статусы Rejected и Can't Reproduce для вас самые неприятные - это явное свидетельство того, что либо вы недостаточно хорошо локализовали дефект, не очень понятно описали шаги для воспроизведения, либо разработчик поленился воспроизвести ситуацию.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Учитель, а как надо закрывать дефекты и причем тут эти “регрессионное и санитарное” тестирования? - поинтересовалась девочка с iPhone-ом в руке&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Дефект проверить не проблема - проходите все описанные шаги, проверяете результат и все. Однако, исправив одно, разработчик мог сломать что-то другое. Проверив четко по шагам, надо сделать еще несколько тестов, чтобы убедиться в том, что вокруг тоже все работает как и раньше. Вот для этого мы и проводим эти самые “регрессионное и санитарное тестирования”. - Поучительно сказал старик, сделав очередную затяжку курительной трубки.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Покончив с закрытием и пере-открытием дефектов, вы переходите к основной работе - централизованному &lt;b&gt;тестированию по тест кейсам&lt;/b&gt; и/или (если вы адепт исследовательского тестирования) вы начинаете упорно исследовать приложение :)&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;И вот больше тестировать нечего, и все, что было запланировано, пройдено. В итоге, вы имеете &amp;nbsp;результаты прогона тест кейсов, баг репорты, вопросы к аналитикам и заметки на полях своих тетрадей. Основываясь на всем этом, вы составляете отчет по проведенному тестированию и отправляете его на проектную группу.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Менеджер проекта закипает от количества дефектов и ужасного качества, не обращая внимания на то, что это всего навсего вторая попавшая в тестирование версия.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Руководитель разработки начинает проникаться уважением к тестировщикам, нашедшим несколько десятков интересных дефектов. Легким движением багтрекера он назначает их на разработчиков, и понеслось все сначала...&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Учитель, а-а что лучше: т-тестирование по т-т-тест кейсам или и-и-исследовательское? Какой путь в-в-выбрать? - заикаясь спросил кучерявый ботаник на первой парте.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- На протяжении века идет спор. Лучшие тестировщики нового и старого света уходили ни с чем с поля боя. У каждого из них были свои доводы и результаты, но никто из них не смог доказать свою правоту. Что посоветую вам я, так это совместить оба подхода, всегда планировать как тестирование по тест кейсам, так и исследовательское тестирование. Пройдя все тест кейсы, потратьте несколько часов на “свободный полет”, проверьте все, что по-вашему можно проверить еще. И будет вам почет и уважение. - сказал старик, вспоминая дефекты найденные по тест кейсам и во время исследования.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;i&gt;Дальше все идет по накатанной: новые билды, пройденные и не пройденные дымовые тесты, то закипающий, то остывающий мозг проектного менеджера, то гнев, то милость руководителя разработки. Однако, через какое-то время сойдётся "задачка с ответом" - &amp;nbsp;результаты тестирования сойдутся, с прописанными в плане тестирования, критериями окончания тестирования.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;*&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&amp;nbsp;- На этом мы закончим сие поверхностное описание процесса тестирования. Надеюсь что вы запомнили, последовательность выполненных видов тестирования:&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;b&gt;Дымовое &amp;gt; Регрессионное &amp;gt; все остальные виды тестирования&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span class="Apple-style-span" style="font-family: Arial;"&gt;- Упрощенная схемка прилагается. - сказал учитель и растворился в воздухе, оставив на столе лишь свою курительную трубку...&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-gcWqJcAqf2o/Tp_pygT_EYI/AAAAAAAACLk/pvANv6l-qFI/s1600/test_process.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-gcWqJcAqf2o/Tp_pygT_EYI/AAAAAAAACLk/pvANv6l-qFI/s1600/test_process.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span &gt;&lt;b&gt;Авторы&lt;/b&gt;: Алексей Булат и Алексей Лемешев.&lt;/span&gt;&lt;/div&gt;
&lt;/span&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-5441505218992541493?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=9yzLgqYkfoo:GTtiN7OPwPU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=9yzLgqYkfoo:GTtiN7OPwPU:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=9yzLgqYkfoo:GTtiN7OPwPU:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=9yzLgqYkfoo:GTtiN7OPwPU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/9yzLgqYkfoo" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-23T12:59:15.276+01:00</app:edited><media:thumbnail url="http://2.bp.blogspot.com/-gcWqJcAqf2o/Tp_pygT_EYI/AAAAAAAACLk/pvANv6l-qFI/s72-c/test_process.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2011/10/blog-post.html</feedburner:origLink></item><item><title>Happy vs Unhappy клиент</title><link>http://feedproxy.google.com/~r/protesting/~3/ynABQzblbRI/happy-vs-unhappy.html</link><category>Обеспечение качества. Контроль качества. Тестирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Tue, 06 Dec 2011 04:35:50 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-51436276938277718</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/x3uJLRUW3puDhkuRDo4jegnyVSI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x3uJLRUW3puDhkuRDo4jegnyVSI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/x3uJLRUW3puDhkuRDo4jegnyVSI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/x3uJLRUW3puDhkuRDo4jegnyVSI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Найдите одно отличие:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.protesting.ru/img/happy-vs-unhappy.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="285" src="http://www.protesting.ru/img/happy-vs-unhappy.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Подумаем из-за чего же так может получиться, что мы сдаем не то, что хотел заказчик:&lt;span class="fullpost"&gt;&lt;br /&gt;
- клиент сам не знает, что хочет&lt;br /&gt;
- клиент не следит за тем что происходило по ходу проекта&lt;br /&gt;
- клиенту вообще не важно, что ты сделаешь ему - просто осваивает бюджет&lt;br /&gt;
- ...&lt;br /&gt;
и самая плохая для нас, как для исполнителя, причина - &lt;b&gt;мы облажались&lt;/b&gt;!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;РЕЗЮМЕ&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
В конце любого проекта, заказчик остается либо доволен, либо не доволен.&lt;br /&gt;
Наша задача оставлять его всегда довольным, иначе следующий к нам может и вовсе не прийти. Поэтому мы должны сделать все, чтобы клиент становился HAPPY, даже когда пришел к нам абсолютно UNHAPPY, в отчаянии от безысходности. Мы должны понять, "приютить, приласкать, обогреть&lt;strike&gt; и обобрать&lt;/strike&gt;", держать его в курсе, не дать потратить лишних денег, даже если они просто "осваиваются" впустую. И будет нам вселенское счастье, респект и уважуха. &lt;br /&gt;
&lt;br /&gt;
Алексей Булат&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-51436276938277718?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=ynABQzblbRI:XNveJOh7pmo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=ynABQzblbRI:XNveJOh7pmo:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=ynABQzblbRI:XNveJOh7pmo:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=ynABQzblbRI:XNveJOh7pmo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/ynABQzblbRI" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-06T13:35:50.603+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2011/06/happy-vs-unhappy.html</feedburner:origLink></item><item><title>Бизнес процессы! Дмитрий Потапенко - О рознице</title><link>http://feedproxy.google.com/~r/protesting/~3/Wt7Uo3z8Xig/blog-post.html</link><category>Процессы</category><category>менеджмент</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 06 Jun 2011 04:21:50 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-6967499085239303797</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ltpSC6J4HZhJgaAAfb64qZQS6WU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ltpSC6J4HZhJgaAAfb64qZQS6WU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ltpSC6J4HZhJgaAAfb64qZQS6WU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ltpSC6J4HZhJgaAAfb64qZQS6WU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Посмотрел недавно очень неплохое видео и решил поделитсья с общественностью!&lt;br /&gt;
&lt;br /&gt;
Итак прошу любить и жаловать - "Дмитрий Потапенко - О рознице":&lt;br /&gt;
&lt;br /&gt;
&lt;iframe width="425" height="349" src="http://www.youtube.com/embed/ru150vjRG5s" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-6967499085239303797?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=Wt7Uo3z8Xig:rSgr0EH7t2k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=Wt7Uo3z8Xig:rSgr0EH7t2k:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=Wt7Uo3z8Xig:rSgr0EH7t2k:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=Wt7Uo3z8Xig:rSgr0EH7t2k:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/Wt7Uo3z8Xig" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-06T13:21:50.111+02:00</app:edited><media:thumbnail url="http://img.youtube.com/vi/ru150vjRG5s/default.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2011/06/blog-post.html</feedburner:origLink></item><item><title>Рекомендации молодым багоборцам.</title><link>http://feedproxy.google.com/~r/protesting/~3/SlOThPCrm_8/blog-post.html</link><category>тестирование ПО</category><category>Обеспечение качества. Контроль качества. Тестирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Wed, 18 May 2011 07:54:22 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-2560281940380833483</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2E_wtE9xSVocrYl91R9uA17eQQg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2E_wtE9xSVocrYl91R9uA17eQQg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2E_wtE9xSVocrYl91R9uA17eQQg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2E_wtE9xSVocrYl91R9uA17eQQg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Несколько советов молодым от умудренного опытом &lt;strike&gt;горе&lt;/strike&gt;, т.е. гуру тестера...&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Изучайте баг репорты, написанные своими коллегами.&lt;br /&gt;
&lt;blockquote style="font-style: italic"&gt;Очень часто, прочтя баг репорт, написанный кем-то, задумываешься: “Интересно... А что если мне проверить такое?” Проверяешь и действительно, находишь багу.&lt;/blockquote&gt;&lt;/li&gt;
&lt;span class="fullpost"&gt;
&lt;li&gt;Утром после вечернего, ночного, выходного продакшн деплоя, первым делом проверьте работоспособность приложения, даже если никто из пользователей не сообщил о проблемах.&lt;br /&gt;
&lt;blockquote style="font-style: italic"&gt;Были случаи, когда сразу после деплоя все работало как часы, а на утро - бац и отвалилось. Либо утром ты проснулся с идеей прогнать тест, который ты не проводил на фазе тестирования. Сделал - и действительно нашел критическую багу. Либо как часто бывает в реальной жизни - нагрузочное тестирование проводили на тестовой платформе, отличающейся по конфигурации от используемой в продакшине, в “тесте” все ОК, а в “проде” - в силу каких-то причин тормозит... У всего этого итог один - &lt;b&gt;Rollback&lt;/b&gt;. &lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Пишите шпаргалки неофициальные короткие инструкции, пометки и комментарии, чек листы, логи прохождения тест кейсов. Иногда они будут полезнее, чем официальные документы.&lt;br /&gt;
&lt;blockquote style="font-style: italic"&gt;Вы думаете, перерабатываете, прогоняете информацию через себя и выдаете её в более понятной форме. Своими записями вы оптимизируете процесс своей работы, выбрасываете не нужное, добавляете необходимое. &lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Задавайте вопросы и уточняйте нюансы даже когда для Вас все кажется очевидным. Читайте спецификации, спрашивайте у бизнес аналитиков, разработчиков, менеджеров и пользователей.  &lt;br /&gt;
&lt;blockquote style="font-style: italic"&gt;Обладая информацией, полученной из разных источников, Вы будете писать более качественные тест кейсы и тем самым цена, написанных Вами, баг репортов будет намного выше. &lt;/blockquote&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-2560281940380833483?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=SlOThPCrm_8:sROG61yiTDc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=SlOThPCrm_8:sROG61yiTDc:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=SlOThPCrm_8:sROG61yiTDc:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=SlOThPCrm_8:sROG61yiTDc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/SlOThPCrm_8" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-18T16:54:22.379+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2011/05/blog-post.html</feedburner:origLink></item><item><title>Основные аспекты создания скриптов для нагрузочного тестирования</title><link>http://feedproxy.google.com/~r/protesting/~3/sSlhvP6c-sM/record-playback.html</link><category>Автоматизированное тестирование</category><category>Нагрузочное тестирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 16 May 2011 10:45:03 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-342825063400172663</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xDu3F_puVjS0HcBd5nVvTT6wXng/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xDu3F_puVjS0HcBd5nVvTT6wXng/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xDu3F_puVjS0HcBd5nVvTT6wXng/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xDu3F_puVjS0HcBd5nVvTT6wXng/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Введение&lt;/h2&gt;&lt;br /&gt;
&lt;p&gt;Напомним, что само по себе &lt;strong&gt;нагрузочное тестирование&lt;/strong&gt; - это &lt;strong&gt;автоматизированное тестирование&lt;/strong&gt;, а значит это разработка, отладка, контрольный запуск и анализ результатов, а не просто запись и запуск (Record &amp; Playback). В данной статье мы постараемся рассмотреть &lt;strong&gt;основные аспекты создания набора тест скриптов для нагрузочного тестирования&lt;/strong&gt;, не углубляясь в технические особенности инструментов, языков программирования и технологий. Итак приступим.&lt;/p&gt;&lt;p&gt;Если мы хотим получить удобный для пользования и сопровождения &lt;b&gt;набор тестовых скриптов&lt;/b&gt;, нам необходимо будет внедрить &lt;a href="http://www.protesting.ru/qa/startqa.html"&gt;приемы обеспечения качества: использование стандартов, шаблонов и инструкций&lt;/a&gt;. Необходимо договориться об общем использовании одинаковой структуры каталогов, архитектуры скриптов, именовании функций, переменных, и транзакций. В итоге каждый участник группы, отвечающей за нагрузочное тестирование, будет знать архитектуру  тестового набора, а также без труда сможет прочитать и внести необходимые изменения в скрипт, написанный другим тестировщиком.&lt;/p&gt;&lt;br /&gt;
&lt;span class="fullpost"&gt;&lt;br /&gt;
&lt;h2&gt;Содержание&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="#2"&gt;Стандартизация тестового набора для тестирования производительности&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#2.1"&gt;Структура каталогов тестового набора&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2.2"&gt;Архитектура тест скриптов&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2.3"&gt;Соглашение об именовании&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#2.3.1"&gt;Названия тест скриптов&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2.3.2"&gt;Названия параметров&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2.3.3"&gt;Название транзакций&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3"&gt;Порядок действий при разработке скриптов для тестирования производительности&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#3.1"&gt;Подготовка&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3.2"&gt;Создание и отладка&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3.3"&gt;Хранение&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4"&gt;Конфигурация тестового набора для тестирования производительности&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5"&gt;Вывод&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6"&gt;Литература&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;a name="2"&gt;&lt;/a&gt;    &lt;h2&gt;Стандартизация тестового набора для тестирования производительности&lt;/h2&gt;&lt;p&gt;Разрабатывая скрипты для нагрузочного тестирования, мы выполняем работу присущую программисту/разработчику, и поэтому должны следовать их правилам, выполняя все для обеспечения качества и надежности кода тестов. Очень часто для этого стоит провести консультации с разработчиками и с их помощью выработать &lt;b&gt;основные правила создания тестовых скриптов&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;В любом случае, свое внимание стоит обратить на следующие аспекты:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Структура каталогов&lt;/li&gt;
&lt;li&gt;Архитектура (структура) тест скриптов&lt;/li&gt;
&lt;li&gt;Именование объектов&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;a name="2.1"&gt;&lt;/a&gt;    &lt;h3&gt;Структура каталогов тестового набора&lt;/h3&gt;&lt;p&gt;Наличие одинаковой структуры каталогов значительно облегчает работу (&lt;a href="#lit1"&gt;[1] Страница 5&lt;/a&gt;). Вы всегда будете знать, где и что находится. Вам не придется искать, где же находятся, к примеру, параметры для тестового набора, написанного другим тестировщиком. Предлагаем Вам следующую структуру каталогов:&lt;/p&gt;&lt;br /&gt;
&lt;p class="center"&gt;&lt;img src="http://www.protesting.ru/img/perf_suite_dir.png" alt="Структура каталогов тестового набора"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;parameters&lt;/b&gt; - директорий глобальных параметров тестового сценария (более подробное описание глобальных параметров смотрите ниже в разделе "&lt;a href="#2.3.2"&gt;название параметров&lt;/a&gt;")&lt;/li&gt;
&lt;li&gt;&lt;b&gt;scripts&lt;/b&gt; - директорий хранения тестовых скриптов&lt;/li&gt;
&lt;li&gt;&lt;b&gt;scenarios&lt;/b&gt; - директорий хранения сценариев или тестовой модели&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;a name="2.2"&gt;&lt;/a&gt;    &lt;h3&gt;Архитектура тест скриптов&lt;/h3&gt;&lt;p&gt;Аналогично со структурой тест кейсов, скрипты для нагрузочного тестирования так же рекомендуется разделять на 3 части: precondition, test case action, postcondition. Данное разделение очень удобно, т.к. разные части тестов имеют разную частоту выполнения.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Тестовые скрипты в HP LoadRunner&lt;/b&gt; изначально разделены на 3 части:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Init&lt;/b&gt; - используется для инициализации VUser, т.е. в него целесообразно помещать те части скрипта, которые не требуют постоянных повторений, такие как вход в тестируемую систему, конечно если мы не тестируем именно эту часть приложения. &lt;i&gt;(Может быть пустым)&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Action&lt;/b&gt; - рабочая часть скрипта. В него помещают те действия, которые будут выполняться, и результаты которых будут измеряться и сохраняться, а в последствии анализироваться. (Количество блоков Action может быть разным, в зависимости от архитектуры тестового скрипта)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;End&lt;/b&gt; - корректное завершение теста.&lt;i&gt;(Может быть пустым)&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;a name="2.3"&gt;&lt;/a&gt;    &lt;h3&gt;Соглашение об именовании&lt;/h3&gt;&lt;p&gt;Программируя на разных языках, мы используем правила наименования (объектов, переменных, функций) присущие данному языку. В качестве примера рекомендуем ознакомиться с таковыми правилами для Java &lt;a href="#lit4"&gt;[4] (Ch. 3  Naming Conventions)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;В автоматизированном тестирование, а в частности в тестировании производительности, есть некоторые специфические сущности, которые необходимо подвести под единую систему наименований. Рассмотрим основные:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;название скриптов&lt;/li&gt;
&lt;li&gt;названия параметров&lt;/li&gt;
&lt;li&gt;название транзакций&lt;/li&gt;
&lt;/ol&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;: при написании скриптов для автоматизированного тестирования вам необходимо будет пользоваться правилами наименования как используемого языка программирования, так и правилами наименований дополнительных сущностей, выработанными в вашей команде. &lt;/p&gt;&lt;br /&gt;
&lt;a name="2.3.1"&gt;&lt;/a&gt;    &lt;h4&gt;Названия тест скриптов&lt;/h4&gt;&lt;p&gt;Для удобства работы с скриптами рекомендуется всем членам команды использовать одинаковый формат названий скриптов:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;формат - начинается с названия тестируемого действия, затем компонента. Каждое слово начинается с большой буквы, без пробелов&lt;/li&gt;
&lt;li&gt;символы - английский алфавит, цифры, подчеркивание&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;b&gt;Пример&lt;/b&gt;: название скрипта по созданию компаний будет &lt;i&gt;AddCompaign&lt;/i&gt;. Если компании надо создавать для заранее заданного количества пользователей (предположим - 100), то название будет следующим: &lt;i&gt;AddCompaign_100&lt;/i&gt;&lt;/p&gt;&lt;br /&gt;
&lt;a name="2.3.2"&gt;&lt;/a&gt;    &lt;h4&gt;Названия параметров&lt;/h4&gt;&lt;p&gt;Очень часто разные скрипты содержат одинаковые параметры. А если учесть, что параметры хранятся в файлах, то мы можем получить некоторое количество одинаковых файлов для нескольких VUser-ов. От этого можно и даже нужно избавляться, т.к. дублирование одинаковой информации не лучший паттерн.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Условно разобьем параметры на 2 типа:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;глобальные&lt;/b&gt; - параметры, использующиеся в большом количестве скриптов внутри сценария, например: хост тестируемого приложения, параметры доступа к БД и т.д. Глобальные параметры хранятся в каталоге parameters проектной директории. В скрипте же, путь к файлу параметров зададим относительно папки скрипта, а именно: "&lt;b&gt;..\parameters\&lt;/b&gt;"&lt;/li&gt;
&lt;li&gt;&lt;b&gt;локальные&lt;/b&gt; - параметры конкретного тестового скрипта. Хранятся внутри директории каждого конкретного скрипта VUser-а.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Названия параметрам рекомендуем давать с маленькой буквы, с возможным подчеркиванием как разделителем кейвордов.&lt;/p&gt;&lt;br /&gt;
&lt;a name="2.3.3"&gt;&lt;/a&gt;    &lt;h4&gt;Название транзакций&lt;/h4&gt;&lt;p&gt;Для измерения производительности, необходимо определить необходимые транзакции. Каждая транзакция измеряет время, необходимое для получения ответа сервера на запрос виртуального пользователя. Для удобства чтения рекомендуется транзакции называть с большой буквы, начинается с кейворда TX &lt;a href="#lit5"&gt;[5]&lt;/a&gt;, каждый последующий кейворд разделен подчеркиванием.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Пример&lt;/b&gt;: по аналогии с примером из пункта &lt;a href="#2.3.1"&gt;2.3.1 Названия тест скриптов&lt;/a&gt;, название транзакций будет TX_ADD_COMPAIGN и TX_ADD_COMPAIGN_100 соответственно.&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name="3"&gt;&lt;/a&gt;    &lt;h2&gt;Порядок действий при разработке скриптов для тестирования производительности&lt;/h2&gt;&lt;p&gt;Условно разобьем процесс разработки тестового набора на 3 фазы:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Подготовка&lt;/li&gt;
&lt;li&gt;Создание и отладка&lt;/li&gt;
&lt;li&gt;Хранение&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;На каждой фазе перед разработчиком скриптов для тестирования будет стоять ряд задач, только после решения которых можно перейти к следующей стадии.&lt;/p&gt;&lt;p&gt;Далее рассмотрим более подробное описание фаз разработки тестовых скриптов для нагрузочного тестирования.&lt;/p&gt;&lt;br /&gt;
&lt;a name="3.1"&gt;&lt;/a&gt;    &lt;h3&gt;Подготовка&lt;/h3&gt;&lt;p&gt;Задачи:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;анализ тестовой модели нагрузки&lt;/li&gt;
&lt;li&gt;анализ функциональной части скрипта, с целью понять, что тест должен делать и как&lt;/li&gt;
&lt;li&gt;выбор варианта создания скрипта:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;ручной, когда разработчик сам пишет функции, использующиеся в скрипте&lt;/li&gt;
&lt;li&gt;автоматический, когда скрипт записывается специальным инструментом&lt;/li&gt;
&lt;li&gt;комбинированный, когда скрипт сначала записывается, а потом параметризируется и усовершенствуется вручную&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;a name="3.2"&gt;&lt;/a&gt;    &lt;h3&gt;Создание и отладка&lt;/h3&gt;&lt;p&gt;Задачи:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;создание шаблона скрипта (под шаблоном подразумевается не параметризованный скрипт, без каких-либо проверок)&lt;/li&gt;
&lt;li&gt;параметризация параметров скрипта&lt;/li&gt;
&lt;li&gt;добавление проверок в скрипт&lt;/li&gt;
&lt;li&gt;настройки параметров VUser-ов (скриптов) и окружения&lt;/li&gt;
&lt;li&gt;отладка при 1 итерации&lt;/li&gt;
&lt;li&gt;отладка при Х итерациях&lt;/li&gt;
&lt;li&gt;добавление скрипта в общий сценарий&lt;/li&gt;
&lt;li&gt;обновление глобальных параметров (при необходимости)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;a name="3.3"&gt;&lt;/a&gt;    &lt;h3&gt;Хранение&lt;/h3&gt;&lt;p&gt;Задачи:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;сохранение глобальных параметров - папка &lt;b&gt;\parameters\&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;сохранение сценариев- папка &lt;b&gt;\scenarios\&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;сохранение скриптов - папка &lt;b&gt;\scripts\&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;: готовый тестовый набор должен быть доступен всем участникам проектной группы, для этого он должен быть сохранен в системе контроля версий (либо на совместно используемом сервере).&lt;/p&gt;&lt;p&gt;При использовании SVN &lt;a href="#lit6"&gt;[6]&lt;/a&gt; в качестве системы контроля версий, рекомендуется воспользоваться общепринятой организацией репозитория &lt;a href="#lit7"&gt;[7]&lt;/a&gt;:&lt;/p&gt;&lt;br /&gt;
&lt;p class="remark"&gt;&lt;b&gt;/trunk&lt;/b&gt;  - актуальная (последняя) версия тестового набора&lt;br /&gt;
&lt;b&gt;/branches&lt;/b&gt; - тестовые наборы, находящиеся в разработке&lt;br /&gt;
&lt;b&gt;/tags&lt;/b&gt; - завершенные тестовые наборы&lt;/p&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;: Для получения более детальной и точной информации о системе контроля версий рекомендуется обратиться к команде разработчиков. По работе с репозиторием любой программист будет рад провести короткий мастер-класс для QA.&lt;/p&gt;&lt;p&gt;В двух словах, порядок работы, используя репозиторий, будет следующий: создается новый &lt;i&gt;branch&lt;/i&gt; для тестового набора, сохраняются в него новые тестовые скрипты или изменения, после завершения работы сливается (merge) все в &lt;i&gt;trunk&lt;/i&gt;. Когда все участники команды залили результаты своей работы (скрипты, сценарии, параметры) в &lt;i&gt;trunk&lt;/i&gt;, создается новый &lt;i&gt;tag&lt;/i&gt;, как показатель завершенности некоторой версии тестового набора.&lt;/p&gt;&lt;p&gt;В итоге, структура каталогов репозитория будет следующая:&lt;/p&gt;&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;b&gt;/perfSuite1&lt;/b&gt;
     &lt;b&gt;/trunk&lt;/b&gt;
         /parameters
         /scenarios
         /scripts
     &lt;b&gt;/branches&lt;/b&gt;
        &lt;b&gt;/branch1&lt;/b&gt;
         /parameters
         /scenarios
         /scripts
       &lt;b&gt;/branch2&lt;/b&gt;
         /parameters
         /scenarios
         /scripts
       ...
     &lt;b&gt;/tags&lt;/b&gt;
       &lt;b&gt;/v0.1&lt;/b&gt;
         /parameters
         /scenarios
         /scripts
       &lt;b&gt;/v0.2&lt;/b&gt;
         /parameters
         /scenarios
         /scripts
       ...
    &lt;b&gt;/perfSuite2&lt;/b&gt;
     &lt;b&gt;/trunk&lt;/b&gt;
      ...
     &lt;b&gt;/branches&lt;/b&gt;
      ...
     &lt;b&gt;/tags&lt;/b&gt;
      ...    &lt;/pre&gt;&lt;a name="4"&gt;&lt;/a&gt;    &lt;h2&gt;Конфигурация тестового набора для тестирования производительности&lt;/h2&gt;&lt;p&gt;&lt;b&gt;Тестовые наборы&lt;/b&gt; или &lt;b&gt;сценарии тестирования&lt;/b&gt; конфигурируются на основании имеющихся &lt;a href="./work_load_model.html"&gt;моделей нагрузки&lt;/a&gt;. Для этого, хранящиеся в репозитории скрипты, группируют в сценарии и назначают требуемое количество виртуальных пользователей, для получения нужной нагрузки (&lt;i&gt;в &lt;b&gt;HP LoadRunner&lt;/b&gt; для этих целей используется &lt;b&gt;Controller&lt;/b&gt;&lt;/i&gt;). Полученные файлы с конфигурацией сценариев сохраняют, также как и скрипты, в репозитории - папка &lt;b&gt;\scenarios\&lt;/b&gt;.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Заметим, что &lt;b&gt;предусловием для конфигурации тестового набора&lt;/b&gt; является подготовка необхдимых скриптов.&lt;/p&gt;&lt;p&gt;Задача:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;создание тестового набора (сценария) для нагрузочного тестирования&lt;/li&gt;
&lt;li&gt;конфигурация тестового набора&lt;/li&gt;
&lt;li&gt;отладка работы сценария&lt;/li&gt;
&lt;li&gt;сохранение тестового набора в репозитории&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;a name="5"&gt;&lt;/a&gt;    &lt;h2&gt;Вывод&lt;/h2&gt;&lt;p&gt;Воспользовавшись, вышеуказанными рекомендациями по созданию тестового набора для нагрузочного тестирования, вы получите четкую, простую и понятную структуру тестовых скриптов, упростите себе задачу по написанию и поддержке их в рабочем состоянии, а также, используя общий репозиторий, вы получите доступ не только к готовым тестам, но и к тем, что находятся в разработке.&lt;/p&gt;&lt;br /&gt;
&lt;a name="6"&gt;&lt;/a&gt;    &lt;h2&gt;Литература&lt;/h2&gt;&lt;a name="lit1"&gt;&lt;/a&gt;     &lt;p&gt;[1] HP LoadRunner software—tips and tricks for configuration, scripting and execution (&lt;a target="_blank" href="https://h10078.www1.hp.com/bto/download/loadrunner-configuration.pdf"&gt;https://h10078.www1.hp.com/bto/download/loadrunner-configuration.pdf&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;[2] Блог Алексея Булата “Про Тестинг” -  &lt;a target="_blank" href="http://alexeybulat.blogspot.com/2007/12/loadrunner.html"&gt;стандартизируем нагрузочные тесты на LoadRunner&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[3] Блог Алексея Булата “Про Тестинг” - &lt;a target="_blank" href="http://alexeybulat.blogspot.com/2007/12/blog-post_25.html"&gt;методика создания нагрузочных тест-скриптов&lt;/a&gt;&lt;/p&gt;&lt;a name="lit4"&gt;&lt;/a&gt;     &lt;p&gt;[4] Java Coding Style Guide (&lt;a target="_blank" href="http://www.cs.bilgi.edu.tr/pages/standards_project/java_CodingStyle.pdf"&gt;http://www.cs.bilgi.edu.tr/pages/standards_project/java_CodingStyle.pdf&lt;/a&gt;)&lt;/p&gt;&lt;a name="lit5"&gt;&lt;/a&gt;     &lt;p&gt;[5] tx=transaction (&lt;a target="_blank" href="http://www.proz.com/kudoz/english_to_polish/finance_general/1859198-tx.html"&gt;http://www.proz.com/kudoz/english_to_polish/finance_general/1859198-tx.html&lt;/a&gt;)&lt;/p&gt;&lt;a name="lit6"&gt;&lt;/a&gt;     &lt;p&gt;[6] Subversion - version control system (&lt;a target="_blank" href="http://subversion.apache.org/"&gt;http://subversion.apache.org/&lt;/a&gt;) &lt;/p&gt;&lt;a name="lit7"&gt;&lt;/a&gt;     &lt;p&gt;[7] Subversion - Branch Maintenance - Chapter 4. Branching and Merging - Repository Layout (&lt;a target="_blank" href="http://svnbook.red-bean.com/en/1.1/ch04s07.html"&gt;http://svnbook.red-bean.com/en/1.1/ch04s07.html&lt;/a&gt;)&lt;/p&gt;&lt;br /&gt;
Информация взята с сайта Про Тестинг: &lt;a href="http://www.protesting.ru/automation/practice/load_scripts_writing.html"&gt;Статья "Основные аспекты создания скриптов для нагрузочного тестирования"&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&lt;b&gt;ЗЫ Комментарии приветствуются, критика тоже... жду отзывов...&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-342825063400172663?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=sSlhvP6c-sM:NQmtMAVXDQA:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=sSlhvP6c-sM:NQmtMAVXDQA:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=sSlhvP6c-sM:NQmtMAVXDQA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/sSlhvP6c-sM" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-16T19:45:03.054+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><enclosure url="https://h10078.www1.hp.com/bto/download/loadrunner-configuration.pdf" length="528921" type="application/pdf" /><media:content url="https://h10078.www1.hp.com/bto/download/loadrunner-configuration.pdf" fileSize="528921" type="application/pdf" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Введение Напомним, что само по себе нагрузочное тестирование - это автоматизированное тестирование, а значит это разработка, отладка, контрольный запуск и анализ результатов, а не просто запись и запуск (Record &amp; Playback). В данной статье мы постараемся </itunes:subtitle><itunes:author>noreply@blogger.com (Алексей Булат)</itunes:author><itunes:summary>Введение Напомним, что само по себе нагрузочное тестирование - это автоматизированное тестирование, а значит это разработка, отладка, контрольный запуск и анализ результатов, а не просто запись и запуск (Record &amp; Playback). В данной статье мы постараемся рассмотреть основные аспекты создания набора тест скриптов для нагрузочного тестирования, не углубляясь в технические особенности инструментов, языков программирования и технологий. Итак приступим. Если мы хотим получить удобный для пользования и сопровождения набор тестовых скриптов, нам необходимо будет внедрить приемы обеспечения качества: использование стандартов, шаблонов и инструкций. Необходимо договориться об общем использовании одинаковой структуры каталогов, архитектуры скриптов, именовании функций, переменных, и транзакций. В итоге каждый участник группы, отвечающей за нагрузочное тестирование, будет знать архитектуру тестового набора, а также без труда сможет прочитать и внести необходимые изменения в скрипт, написанный другим тестировщиком. СодержаниеСтандартизация тестового набора для тестирования производительности Структура каталогов тестового набора Архитектура тест скриптов Соглашение об именовании Названия тест скриптов Названия параметров Название транзакций Порядок действий при разработке скриптов для тестирования производительности Подготовка Создание и отладка Хранение Конфигурация тестового набора для тестирования производительности Вывод Литература Стандартизация тестового набора для тестирования производительности Разрабатывая скрипты для нагрузочного тестирования, мы выполняем работу присущую программисту/разработчику, и поэтому должны следовать их правилам, выполняя все для обеспечения качества и надежности кода тестов. Очень часто для этого стоит провести консультации с разработчиками и с их помощью выработать основные правила создания тестовых скриптов. В любом случае, свое внимание стоит обратить на следующие аспекты:Структура каталогов Архитектура (структура) тест скриптов Именование объектов Структура каталогов тестового набора Наличие одинаковой структуры каталогов значительно облегчает работу ([1] Страница 5). Вы всегда будете знать, где и что находится. Вам не придется искать, где же находятся, к примеру, параметры для тестового набора, написанного другим тестировщиком. Предлагаем Вам следующую структуру каталогов: parameters - директорий глобальных параметров тестового сценария (более подробное описание глобальных параметров смотрите ниже в разделе "название параметров") scripts - директорий хранения тестовых скриптов scenarios - директорий хранения сценариев или тестовой модели Архитектура тест скриптов Аналогично со структурой тест кейсов, скрипты для нагрузочного тестирования так же рекомендуется разделять на 3 части: precondition, test case action, postcondition. Данное разделение очень удобно, т.к. разные части тестов имеют разную частоту выполнения. Тестовые скрипты в HP LoadRunner изначально разделены на 3 части:Init - используется для инициализации VUser, т.е. в него целесообразно помещать те части скрипта, которые не требуют постоянных повторений, такие как вход в тестируемую систему, конечно если мы не тестируем именно эту часть приложения. (Может быть пустым) Action - рабочая часть скрипта. В него помещают те действия, которые будут выполняться, и результаты которых будут измеряться и сохраняться, а в последствии анализироваться. (Количество блоков Action может быть разным, в зависимости от архитектуры тестового скрипта) End - корректное завершение теста.(Может быть пустым) Соглашение об именовании Программируя на разных языках, мы используем правила наименования (объектов, переменных, функций) присущие данному языку. В качестве примера рекомендуем ознакомиться с таковыми правилами для Java [4] (Ch. 3 Naming Conventions) В автоматизированном тестирование, а в частности в тестировании производительности, есть некоторые специфические сущности, которые необходимо подвести под единую систему наименований. Рассмотрим основные:название</itunes:summary><itunes:keywords>Автоматизированное тестирование, Нагрузочное тестирование</itunes:keywords><feedburner:origLink>http://alexeybulat.blogspot.com/2011/05/record-playback.html</feedburner:origLink></item><item><title>Домино, Рыба или Кошка в горошек...</title><link>http://feedproxy.google.com/~r/protesting/~3/xvuxpgtluZg/blog-post.html</link><category>интересные баги</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Fri, 18 Feb 2011 04:08:48 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-2942906112137637353</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YK1pfq6EDY2Rf2Nej4OoWwXO_0k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YK1pfq6EDY2Rf2Nej4OoWwXO_0k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YK1pfq6EDY2Rf2Nej4OoWwXO_0k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YK1pfq6EDY2Rf2Nej4OoWwXO_0k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Они уже среди нас, баги везде, баги вокруг, баги, баги, баги...&lt;br /&gt;
&lt;br /&gt;
Играл сегодня с дочкой в детское домино и ненароком нашел багу :) На первый взгляд все хорошо, но если присмотреться...&lt;br /&gt;
&lt;span class="fullpost"&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" height="240" width="320" src="http://1.bp.blogspot.com/-T5lugjai2yM/TV5HJo5S88I/AAAAAAAACGU/Lepv1ksbAHw/s320/IMG_2957.JPG" /&gt;&lt;/div&gt;&lt;br /&gt;
Если вы не заметили ничего необычного, то вот вам еще одна картинка:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" height="240" width="320" src="http://2.bp.blogspot.com/-TCOixjCqwNw/TV5HdJABs_I/AAAAAAAACGc/_EZDJodVaj8/s320/IMG_2958.JPG" /&gt;&lt;/div&gt;&lt;br /&gt;
Если ли же и на этот раз для Вас все в норме, то есть варианты:&lt;br /&gt;
1. Вы еще не до конца тестер&lt;br /&gt;
2. Вы счастливый обладатель замыленного глаза&lt;br /&gt;
3. Посмотрите еще внимательнее на картинки домино!!! (Подсказка: надо смотреть на кошку на средней доминошке)&lt;br /&gt;
&lt;br /&gt;
С уважением,&lt;br /&gt;
Алексей Булат&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-2942906112137637353?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=xvuxpgtluZg:VZ6PuiIskII:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=xvuxpgtluZg:VZ6PuiIskII:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=xvuxpgtluZg:VZ6PuiIskII:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=xvuxpgtluZg:VZ6PuiIskII:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/xvuxpgtluZg" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-18T13:08:48.990+01:00</app:edited><media:thumbnail url="http://1.bp.blogspot.com/-T5lugjai2yM/TV5HJo5S88I/AAAAAAAACGU/Lepv1ksbAHw/s72-c/IMG_2957.JPG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2011/02/blog-post.html</feedburner:origLink></item><item><title>Конфигурация тестового стенда для нагрузочного тестирования</title><link>http://feedproxy.google.com/~r/protesting/~3/ffOD8AZLr8E/blog-post.html</link><category>Нагрузочное тестирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Thu, 28 Oct 2010 11:26:21 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-4082548577094589889</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QJN5PopHZ5cNFujmC6U6SuAUoMo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QJN5PopHZ5cNFujmC6U6SuAUoMo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QJN5PopHZ5cNFujmC6U6SuAUoMo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QJN5PopHZ5cNFujmC6U6SuAUoMo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;h1&gt;Введение&lt;/h1&gt;&lt;br /&gt;
&lt;p&gt;В предыдущей статье мы говорили о &lt;a target="_blank" href="http://www.protesting.ru/automation/practice/work_load_model.html"&gt;создании модели нагрузочного тестирования&lt;/a&gt;, теперь давайте разберем "по полочкам" &lt;b&gt;конфигурацию тестового стенда&lt;/b&gt;. Постараемся понять, каким он должен быть, для чего он должен быть как можно больше приближен к реальной эксплуатируемой конфигурации, как производить анализ результатов в случае, если тестовый стенд отличается от реального.&lt;/p&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;
&lt;h1&gt;Содержание&lt;/h1&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="#confvsperf"&gt;Конфигурация vs Производительность&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conf"&gt;Конфигурация тестового стенда&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#analysis"&gt;Анализ результатов при разных конфигурациях&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#koef"&gt;Использование переходного коэффициента&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#expert"&gt;Использование экспертной оценки&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#finish"&gt;Выводы&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#litr"&gt;Литература&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a name="confvsperf"&gt;&lt;/a&gt;&lt;h1&gt;Конфигурация vs Производительность&lt;/h1&gt;&lt;br /&gt;
&lt;p&gt;На &lt;strong&gt;результаты нагрузочного тестирования&lt;/strong&gt; могут влиять разные факторы, такие как &lt;strong&gt;конфигурация тестового стенда&lt;/strong&gt;, загруженность сети, заполненность базы данных и многие другие. Причем влияние их на производительность приложения может быть значительным и иметь нелинейную зависимость, поэтому выразить её формулой будет практически невозможно. Следовательно, чем меньше будут разниться параметры тестовой и реальной инфраструктуры, тем меньше будет погрешность в полученных результатах.&lt;/p&gt;&lt;br /&gt;
&lt;a name="conf"&gt;&lt;/a&gt;&lt;h1&gt;Конфигурация тестового стенда&lt;/h1&gt;&lt;br /&gt;
&lt;p&gt;Отметим те части конфигурации, которые требуют особого внимания:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Hardware&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li/&gt;процессор (тип, частота, количество ядер и т.д)&lt;br /&gt;
&lt;li/&gt;оперативная память (тип, объем, тайминг, эффективная частота и т.д.)&lt;br /&gt;
&lt;li/&gt;жесткие диски (тип, скорость и т.д.)&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Software&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li/&gt;Операционная система&lt;br /&gt;
&lt;li/&gt;Драйвера&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Network&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li/&gt;топология сети&lt;br /&gt;
&lt;li/&gt;пропускная способность&lt;br /&gt;
&lt;li/&gt;протокол передачи данных&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Application&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li/&gt;Архитектура&lt;br /&gt;
&lt;li/&gt;База данных (структура + данные)&lt;br /&gt;
&lt;li/&gt;программное обеспечение, необходимое для работы приложения (например, для Java приложений - JVM)&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;В самом идеальном случае &lt;b&gt;тестовый стенд один к одному дублирует конфигурацию реального сервера&lt;/b&gt;, на котором работает или же будет работать приложение. Однако, как мы с вами знаем, идеальных случаев практически не бывает (то памяти мало, то процессора такой частоты нет в наличии, то операционная система не той версии, то стоимость некоторого серверного ПО не укладывается в бюджете). Перечислим основные причины, по которым не всегда получается продублировать конфигурацию системы на тестовом стенде:&lt;/p&gt;&lt;ol&gt;&lt;li/&gt;Сложность дублирования дорогого серверного железа для тестовых нужд&lt;br /&gt;
&lt;li/&gt;Ограничения на использование лицензий требуемого программного обеспечения&lt;br /&gt;
&lt;li/&gt;Закрытость архитектуры приложения со стороны заказчика по соображениям безопасности&lt;br /&gt;
&lt;li/&gt;Трудность воссоздания или транспортировки базы данных приложения&lt;br /&gt;
&lt;li/&gt;Сложность воссоздания требуемой архитектуры сети&lt;br /&gt;
&lt;li/&gt;и многое другое (всё перечислить крайне сложно из-за большого количества нюансов, влияющих на конфигурацию системы)&lt;br /&gt;
&lt;/ol&gt;&lt;p&gt;Целесообразность же воссоздания инфраструктуры необходимо оценить с учетом выделенных ресурсов, времени и усилий, так как не всегда результат будет оправдывать средства.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Приведем пример&lt;/b&gt; (придуманный из головы и вполне возможно нереальный) для того, чтобы показать сложность сравнения результатов на двух разных системах:&lt;/p&gt;&lt;p&gt;Требуется конфигурация: Proc Intel Clarkdale Core I5, 16 Gb памяти DDR3-800, OS SLES11&lt;/p&gt;&lt;p&gt;Конфигурация тестового стенда: Proc AMD Deneb Phenom II X4, 16 Gb DDR2-800, OS SLES10&lt;/p&gt;&lt;p&gt;Казалось бы отличия незначительны, однако есть нюансы:&lt;/p&gt;&lt;ol&gt;&lt;li/&gt;Разные типы процессоров&lt;br /&gt;
&lt;li/&gt;Разный тип памяти&lt;br /&gt;
&lt;li/&gt;Разные версии операционной системы&lt;br /&gt;
&lt;/ol&gt;&lt;p&gt;Итак:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Cравним процессоры&lt;/b&gt; &lt;a href="#proc"&gt;[3]&lt;/a&gt;:&lt;/p&gt;&lt;table  border="1" cellpadding="3" cellspacing="0"&gt;&lt;tr&gt;         &lt;td&gt;Название ядра&lt;/td&gt;         &lt;td&gt;Intel Clarkdale Core I5&lt;/td&gt;         &lt;td&gt;AMD Deneb Phenom II X4&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;Тактовые частоты, Мгц&lt;/td&gt;         &lt;td&gt;2800-3600&lt;/td&gt;         &lt;td&gt;2800-3000&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;Частоты системной шины, Мгц&lt;/td&gt;         &lt;td&gt;2500&lt;/td&gt;         &lt;td&gt;2000-1800&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;Пропускная способность шины процессор-чипсет&lt;/td&gt;         &lt;td&gt;2 ГБ/сек (1 ГБ/сек в одном направлении)&lt;/td&gt;         &lt;td&gt;14.4-16 ГБ/сек (7.2-8 ГБ/сек в одном направлении)&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;Размер кэша L1, Кб&lt;/td&gt;         &lt;td&gt;64 х2&lt;/td&gt;         &lt;td&gt;128 х4&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;Размер внутреннего кэша L2, Кб&lt;/td&gt;         &lt;td&gt;256 x2&lt;/td&gt;         &lt;td&gt;512 х4&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;Ширина шины L2 кеша, бит&lt;/td&gt;         &lt;td&gt;256 (двунаправленная)&lt;/td&gt;         &lt;td&gt;256 (по 128 в каждом направлении)&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;...&lt;/td&gt;         &lt;td&gt;...&lt;/td&gt;         &lt;td&gt;...&lt;/td&gt;     &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;&lt;b&gt;Примечание&lt;/b&gt;: Неправда ли, не просто будет сравнивать без помощи специалистов? Тем более вывести коэффициент на сколько какой процессор быстрее и по каким параметрам.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Cравним память&lt;/b&gt; &lt;a href="#mem"&gt;[4]&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;Стандартная задержка (latency) типичная для DDR2 5-5-5-15, а  для DDR3 памяти 7-7-7-15. Однако даже с большей задержкой DDR3 память (в отличие от старого стандарта DDR2) обладает большей пропускной способностью (bandwidth) из-за  более высокой тактовой частоты (clock speed). Что становится причиной того, что DDR3 память работает немного медленнее, чем DDR2 с такой же частотой 800MHz.&lt;/p&gt;&lt;p&gt;Таким образом, память на тестовом стенде будет немного быстрее чем в требуемой конфигурации.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Cравним операционные системы&lt;/b&gt;&lt;/p&gt;&lt;p&gt;По мнению экспертов, какой-либо существенной разницы в производительности из-за версии ОС не будет, однако небольшой прирост может быть только из-за того, что в более свежих ядрах чуть оптимальнее код.&lt;/p&gt;&lt;p&gt;Таким образом предположим, что SLES 11 будет незначительно быстрее SLES 10.&lt;/p&gt;&lt;p&gt;&lt;i&gt;Удивлены таким большим количеством различий? (Причем это только для трех элементов конфигурации: процессора, памяти и операционной системы. В реальности их намного больше) Легко ли будет сделать выводы о том, как будет работать приложение на требуемой конфигурации? (Я думаю, что практически невозможно) Однако далее мы попробуем все таки найти пути для решения этой проблемы, рассмотрев некоторые практические приемы.&lt;/i&gt;&lt;/p&gt;&lt;a name="analysis"&gt;&lt;/a&gt;&lt;h1&gt;Анализ результатов при разных конфигурациях&lt;/h1&gt;&lt;p&gt;Как же быть с тем фактом, что приложение будет протестировано на одной платформе, а работать ему придется на другой? Как провести анализ результатов? Как сделать окончательные выводы и спрогнозировать работу приложения под нагрузкой в будущем?&lt;/p&gt;&lt;a name="koef"&gt;&lt;/a&gt;&lt;h3&gt;Использование переходного коэффициента&lt;/h3&gt;&lt;p&gt;В своей статье &lt;a href="#berzin"&gt;[1]&lt;/a&gt; Вячеслав Берзин, предложил при анализе результатов использовать “переходный коэффициент”, показывающий численно отличие производительности тестовой платформы от промышленной:&lt;/p&gt;&lt;blockquote style="font-style:italic;"&gt;"Если существует отличие в конфигурациях тестового стенда и тестируемой системы, необходима оценка переходного  коэффициента для производительности тестовой и промышленной систем. На основании этого коэффициента, проводится масштабирование  полученных результатов. Для получения погрешности оценки, не превышающей 5-10%, рекомендуется проведение оценки переходного коэффициента несколькими независимыми способами, например, на основании анализа независимых данных о производительности  используемых аппаратных платформ."&lt;/blockquote&gt;&lt;p&gt;Использование данного подхода, значительно облегчает создание и конфигурацию тестового стенда, но прибавляет работы на этапе анализа результатов. Так что вам придется решать самим: либо пытаться один к одному (100%) скопировать промышленную систему, либо сделать её максимально приближенной и с помощью переходного коэффициента анализировать и делать прогнозы на будущий рост производительности.&lt;/p&gt;&lt;p&gt;Однако, не всегда возможно точно получить значение переходного коэффициента из-за нелинейных зависимостей между компонентами системы, а примерный расчет может дать слишком большую погрешность. Поэтому использование данного подхода видится реальным, когда тестовая и реальная конфигурации системы практически идентичны.&lt;/p&gt;&lt;a name="expert"&gt;&lt;/a&gt;&lt;h3&gt;Использование экспертной оценки&lt;/h3&gt;&lt;p&gt;Рассмотрим мнение Андрея Широбокова &lt;a href="#shirobokov"&gt;[2]&lt;/a&gt; (сертифицированный специалист в области нагрузочного тестирования, имеющий более 15 лет рабочего опыта в IT):&lt;/p&gt;&lt;blockquote style="font-style:italic;"&gt;&lt;p&gt;"Идеально ключевые моменты должны совпадать, пишу по убыванию важности:&lt;/p&gt;&lt;ol&gt;&lt;li/&gt;конфигурация (кол-во и тип процессоров х память)&lt;br /&gt;
&lt;li/&gt;версия ОС и статс паки&lt;br /&gt;
&lt;li/&gt;версия и тип СУБД&lt;br /&gt;
&lt;li/&gt;версия серверов приложений и патчей&lt;br /&gt;
&lt;/ol&gt;&lt;p&gt;Естественно, что версия тестируемого приложения должна быть актуальна.&lt;/p&gt;&lt;p&gt;Если совпадает платформа (ОС и тип процессоров), то допускается "пропустить" конфигурацию, например, в случае если проведены эксперименты на конфигурациях 8х16 (8 прц х 16 Гб) и 32х64 (32 прц х 64 Гб), то можно "аппроксимировать" недостающую конфигурацию 24х48 (24 прц х 48 Гб). Обратим внимание, что памяти для такой методики должно пропорционально быть в 2 раза больше во всех случаях.&lt;/p&gt;&lt;p&gt;Если не совпадает платформа, ОС, типы процессоров, объемы памяти, то можно делать только очень общие выводы, наподобие: "В реальности будет не хуже". Но времена откликов и другие детали могут быть малозначимы."&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Как видим, как при использовании переходного коэффициента, так и при использовании экспертной оценки, анализ результатов и прогнозирование роста производительности при тестировании на разных конфигурациях стендов (тестового и реального) становится затруднительным, и либо требует дополнительных перерасчетов по сложным нелинейным формулам с большим количеством параметров, либо не обеспечивает должной точности результатов.&lt;/p&gt;&lt;a name="finish"&gt;&lt;/a&gt;&lt;h1&gt;Выводы&lt;/h1&gt;&lt;p&gt;В данной статье мы попытались описать основные моменты связанные с конфигурацией тестового стенда для нагрузочного тестирования. В результате мы имеем следующее:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;в идеальном случае тестовый стенд должен один к одному дублирует конфигурацию реального промышленного сервера,&lt;br /&gt;
&lt;li/&gt;проводя тестирование на тестовом стенде, имеющем отличную от реальной инфраструктуру, мы не всегда можем дать точную оценку производительности реальной системы,&lt;br /&gt;
&lt;li/&gt;для анализа результатов при небольших отклонениях в конфигурациях возможно использовать переходных коэффициент.&lt;br /&gt;
&lt;/ul&gt;&lt;a name="litr"&gt;&lt;/a&gt;&lt;h1&gt;Литература&lt;/h1&gt;&lt;ol&gt;&lt;li&gt;&lt;a name="berzin"&gt;&lt;/a&gt;Технология нагрузочного тестирования информационных систем с большим объемом данных , Вячеслав Берзин, Oracle Magazine, [01.12.04]&lt;/li&gt;
&lt;li&gt;&lt;a name="shirobokov"&gt;&lt;/a&gt;Блог Андрея Широбокова (&lt;a target="_blank" href="http://ashirobokov.blogspot.com"&gt;http://ashirobokov.blogspot.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a name="proc"&gt;&lt;/a&gt;&lt;a target="_blank" href="http://www.nix.ru/support/compare_tables_builder.html?item[10]=992&amp;item[44]=1088"&gt;Сравнение характеристик процессоров&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a name="mem"&gt;&lt;/a&gt;&lt;a target="_blank" href="http://infoteknotainment.com/ddr3-memory-ddr2-memory"&gt;DDR3 RAM and DDR2 Memory Comparison&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Информация взята с сайта Про Тестинг: &lt;a target="_blank" href="http://www.protesting.ru/automation/practice/test_stand_configuration.html"&gt;Статья "Конфигурация тестового стенда для нагрузочного тестирования"&lt;/a&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-4082548577094589889?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=ffOD8AZLr8E:HXYCljt4JMs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=ffOD8AZLr8E:HXYCljt4JMs:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=ffOD8AZLr8E:HXYCljt4JMs:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=ffOD8AZLr8E:HXYCljt4JMs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/ffOD8AZLr8E" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-28T20:26:21.868+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/10/blog-post.html</feedburner:origLink></item><item><title>Модель нагрузки, как отправная точка при тестировании производительности</title><link>http://feedproxy.google.com/~r/protesting/~3/WVvWe8vER2s/blog-post.html</link><category>Нагрузочное тестирование</category><category>тест план</category><category>планирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Wed, 27 Oct 2010 05:12:21 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-3982079179269448858</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7xxJPKdr3oGk2Vdxj4OfY3l5wn0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7xxJPKdr3oGk2Vdxj4OfY3l5wn0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7xxJPKdr3oGk2Vdxj4OfY3l5wn0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7xxJPKdr3oGk2Vdxj4OfY3l5wn0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;h1&gt;Введение&lt;/h1&gt;&lt;p&gt;В настоящее время, с постоянно растущим числом интернет пользователей и пользователей ПК в общем, серьезно встает задача создания систем способных работать под колоссальными нагрузками без видимых замедлений и сбоев.&lt;/p&gt;&lt;p&gt;Любого рода проблемы связанные с плохой производительностью могут стать причиной отказа клиентов от использования Вашего программного обеспечения, даже если функционально оно их устраивало. В связи с этим, проведение качественного нагрузочного тестирования должно стать обязательным, для обеспечения стабильности работы ваших приложений.&lt;/p&gt;&lt;span class="fullpost"&gt;&lt;h1&gt;Содержание&lt;/h1&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="#perf"&gt;Что же такое нагрузочное тестирование?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#req0"&gt;Анализ требований&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#req1"&gt;Анализ требований в зависимости от типа проекта&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#user"&gt;Анализ целевой аудитории&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#base"&gt;Определение базового профиля нагрузки&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mod0"&gt;Разработка моделей нагрузки&lt;/a&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="#mod1"&gt;Модель тестирования производительности&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mod2"&gt;Модель стрессового тестирования&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mod3"&gt;Модель объемного тестирования&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mod4"&gt;Модель тестирования стабильности или надежности&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#sum"&gt;Выводы&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#lit"&gt;Литература&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;a name="perf"&gt;&lt;/a&gt;&lt;h1&gt;Что же такое нагрузочное тестирование?&lt;/h1&gt;&lt;p&gt;Нагрузочное тестирование или тестирование производительности - это автоматизированное тестирование, имитирующее работу определенного количества бизнес пользователей на каком либо общем (разделяемом ими) ресурсе.&lt;/p&gt;&lt;p&gt;Основные виды нагрузочных тестов:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;Тестирование производительности&lt;br /&gt;
&lt;li/&gt;Стрессовое тестирование&lt;br /&gt;
&lt;li/&gt;Объемное тестирование&lt;br /&gt;
&lt;li/&gt;Тестирование стабильности или надежности&lt;br /&gt;
&lt;/ul&gt;&lt;p&gt;Говоря ранее о качественном нагрузочном тестировании, я имел ввиду проведение полного цикла работ:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;разработка моделей нагрузки&lt;br /&gt;
&lt;li/&gt;конфигурация тестового стенда&lt;br /&gt;
&lt;li/&gt;разработку скриптов&lt;br /&gt;
&lt;li/&gt;проведение тестирования&lt;br /&gt;
&lt;li/&gt;анализ результатов&lt;br /&gt;
&lt;/ul&gt;&lt;p&gt;Далее в статье речь пойдет преимущественно о первом и на мой взгляд самом важном этапе – о разработке моделей нагрузки.&lt;/p&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;:  Согласно некоторым данным этот этап может занимать до 50% времени по нагрузочному тестированию.&lt;/p&gt;&lt;p&gt;Разобьем работу над моделью нагрузки на несколько частей и определим, что необходимо будет делать на каждой из них:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;анализ требований&lt;br /&gt;
&lt;li/&gt;анализ целевой аудитории&lt;br /&gt;
&lt;li/&gt;определение базового профиля нагрузки&lt;br /&gt;
&lt;li/&gt;разработка моделей нагрузки&lt;br /&gt;
&lt;/ul&gt;&lt;p&gt;А теперь более подробно рассмотрим каждый пункт, шаг за шагом.&lt;/p&gt;&lt;a name="req0"&gt;&lt;/a&gt;&lt;h1&gt;Анализ требований&lt;/h1&gt;&lt;p&gt;При анализе требований основной упор необходимо сделать на определение основных критериев успешности проведенных тестов. Для этого Вам необходимо будет выделить следующие характеристики:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Время отклика&lt;/b&gt; (время необходимое для открытия страницы или получения ожидаемого результата)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Интенсивность&lt;/b&gt; (число запросов в секунду – (Qps)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Используемые ресурсы&lt;/b&gt; (загрузка процессора, кол-во используемой памяти, дисковое и сетевой I/O)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Максимальное количество пользователей&lt;/b&gt; (определяет число пользователей, способных работать с системой в условиях заданной конфигурации)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;А также некоторые метрики связанные с работой бизнес сценариев (например, количество бизнес операций в единицу времени, время выполнения бизнес операции и т.д.)&lt;/p&gt;&lt;p&gt;Заданные в требованиях характеристики, будут являться &lt;b&gt;базовыми  нагрузочными точками&lt;/b&gt; тестируемого приложения. Все получаемые результаты будут сравниваться с ними для принятия решения о завершении тестирования либо дальнейшем профилировании производительности.&lt;/p&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;:  Основной проблемой при анализе требований будет являться их отсутствие! В связи с тем, что не всегда наши бизнес аналитики или люди ответственные за написание требований по производительности реально представляют как система должна работать под нагрузкой, какие именно требования должны быть предоставлены, очень часто цифры берутся просто «с потолка», поэтому нам приходится не только выделять имеющиеся требования, но и проводить их глубокий анализ на предмет их корректности.&lt;/p&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;:  В случае, когда требования заданы не полностью, базовая нагрузочная точка может быть рассчитана по имеющимся данным (см. &lt;a target="_blank" href="http://www.protesting.ru/automation/load/loadpoint.html"&gt;расчет нагрузочных точек&lt;/a&gt;), при условии наличия необходимых характеристик.&lt;/p&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;:  Характеристика “Максимальное количество пользователей” на самом деле является малоинформативной, в случае если для тестирования нам необходимо будет работать с несколькими группами пользователей. Поэтому крайне важно будет знать более менее точное количество пользователей в каждой группе.&lt;/p&gt;&lt;a name="req1"&gt;&lt;/a&gt;&lt;h2&gt;Анализ требований в зависимости от типа проекта&lt;/h2&gt;&lt;p&gt;При анализе требований необходимо учесть разрабатывается ли новое (startup project) или же проект направлен на профилирование нагрузки для уже находящегося в эксплуатации приложения (profiling project).&lt;/p&gt;&lt;p&gt;Рассмотрим на основании чего разрабатываются требования по производительности в зависимости от типа проекта.&lt;/p&gt;&lt;p&gt;Для startup проектов:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;анализ общепринятых критериев производительности&lt;br /&gt;
&lt;li/&gt;анализ производительности конкурирующих приложений&lt;br /&gt;
&lt;li/&gt;анализ экспертного мнения разработчиков, системных  и сетевых администраторов, администраторов баз данных и инженеров по нагрузочному тестированию.&lt;br /&gt;
&lt;li/&gt;анализ ожиданий целевых пользователей (групп пользователей)&lt;br /&gt;
&lt;/ul&gt;&lt;p&gt;Для profiling проектов:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;анализ общепринятых критериев производительности&lt;br /&gt;
&lt;li/&gt;анализ производительности конкурирующих приложений&lt;br /&gt;
&lt;li/&gt;анализ производительности эксплуатируемой версии приложения, с целью определения требующих профилирования функций, процессов, операций и т.д.&lt;br /&gt;
&lt;li/&gt;анализ экспертного мнения разработчиков, системных  администраторов и администраторов баз данных, инженеров по нагрузочному тестированию.&lt;br /&gt;
&lt;li/&gt;анализ мнения целевых пользователей (групп пользователей)&lt;br /&gt;
&lt;/ul&gt;&lt;p&gt;И уже после получения всех данных из всех источников можно получить более менее точные требования по производительности для тестируемого приложения.&lt;/p&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;:  В случае, если подобный анализ “имел место быть”, и в документации по проекту четко описаны все требования, то можно считать, что вам повезло. Так как в противном случае часть работы по разработке требований может лечь на Ваши плечи и будет включено во время отведенное на тестирование, которого и без того обычно не хватает.&lt;/p&gt;&lt;a name="user"&gt;&lt;/a&gt;&lt;h1&gt;Анализ целевой аудитории&lt;/h1&gt;&lt;p&gt;Общение непосредственно с пользователями, наблюдение за их действиями, помогает нам более точно понять как будет происходить работа с ПО, какие части приложения наиболее критичны и требуют особого внимания.&lt;/p&gt;&lt;p class="remark"&gt;&lt;b&gt;Примечание&lt;/b&gt;:  В случае, если тестируемая система уже находится в эксплуатации, пользовательские сценарии и распределенее запросов в течении дня, можно получить проанализировав логи  приложения и сервера.&lt;/p&gt;&lt;p&gt;В результате мы получим:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;Четко выделенные группы пользователей (например, администраторы, операторы, зарегистрированные клиенты, новые пользователи и т.д.)&lt;br /&gt;
&lt;li/&gt;Описание сценариев тестирования, на основе реального поведения  пользователей из каждой группы.&lt;br /&gt;
&lt;li/&gt;График распределение выполнения бизнес операций в течении дня.&lt;br /&gt;
&lt;/ul&gt;&lt;p class="remark"&gt;&lt;b&gt;Например&lt;/b&gt;:  Утром операторы проверяют журналы посещения, обрабатывают сообщения клиентов, после обеда вводят новые товары в базу, и в конце рабочего дня снова анализируют журналы и сообщения. Значит основная нагрузка на журналы посещения и базы сообщений будет в начале и в конце рабочего дня.&lt;/p&gt;&lt;a name="base"&gt;&lt;/a&gt;&lt;h1&gt;Определение базового профиля нагрузки&lt;/h1&gt;&lt;p&gt;Выделив, на предыдущем шаге группы пользователей, бизнес сценарии, требования к системе можем приступить к созданию профиля нагрузки – набор операций и интенсивность их выполнения для каждой пользовательской группы.&lt;/p&gt;&lt;p&gt;Зная количество пользователей в каждой группе, мы должны будем распределить их для выполнения  требуемых операций, сохранив необходимую интенсивность.&lt;/p&gt;&lt;b&gt;Например&lt;/b&gt;: &lt;p&gt;В группе “Администраторы” работает 10 админов. Они выполняют 2 основные операции - “добавить пользователя” и “забанить пользователя”.&lt;/p&gt;&lt;p&gt;Распределим выполнение операций следующим образом: 5 админов выполняют операцию добавления и 5 забанивают пользователей. Проведем перерасчет интенсивности выполнения операций:&lt;/p&gt;&lt;p&gt;В течении дня 10 администраторов добавляют 240 пользователей. Значит, интенсивность выполнения операции добавления для 1 администратора = 1 операция в час. Но в нашем случае только 5 админов будут выполнять операцию добавления, значит нам необходимо увеличить интенсивность так, чтобы количество добавленных пользователей осталось прежним. Итого, мы получим, что выполняя по 2 операции в час, 5 админов будут добавлять те же 240 пользователей. Проведя аналогичный перерасчет интенсивности для операции “забанить пользователя”, мы получим профиль нагрузки для группы Администраторы:&lt;/p&gt;&lt;table border="1" cellpadding="3" cellspacing="0"&gt;&lt;tr&gt;         &lt;th&gt;группа&lt;/th&gt;         &lt;th&gt;кол-во юзеров&lt;/th&gt;         &lt;th&gt;операция&lt;/th&gt;         &lt;th&gt;интенсивность опер./час&lt;/th&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;админы &lt;/td&gt;         &lt;td&gt;5&lt;/td&gt;         &lt;td&gt;добавить пользователя&lt;/td&gt;         &lt;td&gt;2&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;админы&lt;/td&gt;         &lt;td&gt;5&lt;/td&gt;         &lt;td&gt;забанить пользователя&lt;/td&gt;         &lt;td&gt;5&lt;/td&gt;     &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;Проведя аналогичный перерасчет для каждой группы пользователей, мы получим небольшую сводную таблицу со списком операций и интенсивностью их выполнения:&lt;/p&gt;&lt;table border="1" cellpadding="3" cellspacing="0"&gt;&lt;tr&gt;         &lt;th&gt;группа&lt;/th&gt;         &lt;th&gt;кол-во юзеров&lt;/th&gt;         &lt;th&gt;операция&lt;/th&gt;         &lt;th&gt;интенсивность опер./сек&lt;/th&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;админы &lt;/td&gt;         &lt;td&gt;Z&lt;/td&gt;         &lt;td&gt;добавить пользователя&lt;/td&gt;         &lt;td&gt;N&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;админы&lt;/td&gt;         &lt;td&gt;Z&lt;/td&gt;         &lt;td&gt;забанить пользователя&lt;/td&gt;         &lt;td&gt;N&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;...&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;покупатели &lt;/td&gt;         &lt;td&gt;Z&lt;/td&gt;         &lt;td&gt;вход/выход в систему&lt;/td&gt;         &lt;td&gt;N&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;покупатели&lt;/td&gt;         &lt;td&gt;Z&lt;/td&gt;         &lt;td&gt;поиск товара&lt;/td&gt;         &lt;td&gt;N&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;покупатели &lt;/td&gt;         &lt;td&gt;Z&lt;/td&gt;         &lt;td&gt;покупка товара&lt;/td&gt;         &lt;td&gt;N&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;...&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;продавцы&lt;/td&gt;         &lt;td&gt;Z&lt;/td&gt;         &lt;td&gt;просмотр посещения&lt;/td&gt;         &lt;td&gt;N&lt;/td&gt;     &lt;/tr&gt;
&lt;tr&gt;         &lt;td&gt;продавцы&lt;/td&gt;         &lt;td&gt;Z&lt;/td&gt;         &lt;td&gt;добавление/удаление/ товара&lt;/td&gt;         &lt;td&gt;N&lt;/td&gt;     &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;Именно это таблица и будет являться полным &lt;b&gt;базовым профилем нагрузки&lt;/b&gt; для тестируемого приложения.&lt;/p&gt;&lt;a name="mod0"&gt;&lt;/a&gt;&lt;h1&gt;Разработка моделей нагрузки&lt;/h1&gt;&lt;p&gt;В зависимости от вида проводимого тестирования и целей преследуемых им, нам придется разрабатывать разные модели нагрузки.&lt;/p&gt;&lt;p&gt;Так разным может быть:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;количество пользователей и интенсивность запросов&lt;br /&gt;
&lt;li/&gt;старт самих пользователей: последовательно по одному, ступенчато группами или же запуск всех сразу.&lt;br /&gt;
&lt;li/&gt;длительность сценария от 10 минут до нескольких часов или даже дней.&lt;br /&gt;
&lt;/ul&gt;&lt;p&gt;Проще всего изменения проводить, варьируя параметрами в базовом профиле нагрузки и инструменте для тестирования производительности (например, в HP LoadRunner Controller).&lt;/p&gt;&lt;a name="mod1"&gt;&lt;/a&gt;&lt;h2&gt;Модель тестирования производительности&lt;/h2&gt;&lt;p&gt;Постепенное увеличение нагрузки, добавляя новых пользователей с некоторым интервалом времени, позволяет нам определить:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;измерение времени выполнения выбранных операций при определенных интенсивностях выполнения этих операций&lt;br /&gt;
&lt;li/&gt;количество пользователей, способных одновременно работать с приложением&lt;br /&gt;
&lt;li/&gt;границы приемлемой производительности при увеличении нагрузки&lt;br /&gt;
&lt;li/&gt;производительность при разных нагрузках&lt;br /&gt;
&lt;/ul&gt;&lt;a name="mod2"&gt;&lt;/a&gt;&lt;h2&gt;Модель стрессового тестирования&lt;/h2&gt;&lt;p&gt;Увеличивая интенсивность операций выше пиковых (максимально разрешенных) значений либо увеличивая количество пользователей, до тех пор пока нагрузка не станет выше максимально допустимых значений, проверяем, что система работоспособна в условиях стресса. Далее, опустив нагрузку до средних значений, проверяем (способность системы к регенерации), что система вернулась к нормальному состоянию (основные нагрузочные характеристики не превышают базовые).&lt;/p&gt;&lt;a name="mod3"&gt;&lt;/a&gt;&lt;h2&gt;Модель объемного тестирования&lt;/h2&gt;&lt;p&gt;Можно использовать ту же модель что и для тестирования производительности однако целью будет проверка работы системы с прогнозом на будущий рост объема данных. Следовательно одним и самым важным предусловием теста будет увеличение объемов базы данных приложения до требуемых размеров. Таким образом мы сможем проверить и оценить производительность, прогнозируя рост системы на год, два или три вперед.&lt;/p&gt;&lt;a name="mod4"&gt;&lt;/a&gt;&lt;h2&gt;Модель тестирования стабильности или надежности&lt;/h2&gt;&lt;p&gt;Используя базовый нагрузочный профиль, запускаем тест длительностью от нескольких часов до нескольких дней, с целью выявления утечек памяти, перезапуска серверов и других аспектов влияющих на нагрузку.&lt;/p&gt;&lt;a name="sum"&gt;&lt;/a&gt;&lt;h1&gt;Выводы&lt;/h1&gt;&lt;p&gt;Четкое следование всем вышеописанным инструкциям по разработке моделей нагрузки, позволит нам:&lt;/p&gt;&lt;ul&gt;&lt;li/&gt;провести дополнительный анализ и тестирование требований по производительности&lt;br /&gt;
&lt;li/&gt;уточнить параметры и характеристики производительности&lt;br /&gt;
&lt;li/&gt;получить более четкого представления о работе системы в целом&lt;br /&gt;
&lt;li/&gt;получить на выходе план предстоящих работ связанных с нагрузочным тестированием&lt;br /&gt;
&lt;li/&gt;определить предельный объем данных системы (с сохранением приемлемой производительности)&lt;br /&gt;
&lt;li/&gt;определить предельное количество пользователей (групп) системы (с сохранением приемлемой производительности)&lt;br /&gt;
&lt;li/&gt;определить ресурсоёмкие операции или сценарии (для дальнейшего профилирования системы)&lt;br /&gt;
&lt;li/&gt;отслеживать эффект от вводимых оптимизаций системы  при регулярных измерениях производительности, используя разработанные и проверенные модели нагрузки,&lt;br /&gt;
&lt;/ul&gt;&lt;p&gt;В итоге, имея на руках готовые разработанные модели нагрузки, можно смело переходить к следующему этапу подготовки к нагрузочному тестированию - конфигурации тестового стенда. Но это уже совершенно другая статья.&lt;/p&gt;&lt;a name="lit"&gt;&lt;/a&gt;&lt;h1&gt;Литература&lt;/h1&gt;&lt;ol&gt;&lt;li&gt;Технология нагрузочного тестирования информационных систем с большим объемом данных , Вячеслав Берзин, Oracle Magazine, [01.12.04]&lt;/li&gt;
&lt;li&gt;Блог “Нагрузочное тестирование ПО” (&lt;a target="_blank" href="http://ashirobokov.blogspot.com"&gt;http://ashirobokov.blogspot.com&lt;/a&gt;), Андрей Широбоков&lt;/li&gt;
&lt;li&gt;Сайт “ПроТестинг.RU” (&lt;a href="http://www.protesting.ru/automation/performance.html"&gt;http://www.protesting.ru/automation/performance.html&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Performance Testing Guidance for Web Applications, J.D. Meier, Carlos Farre, Prashant Bansode, Scott Barber, and Dennis Rea; Microsoft Corporation; September 2007&lt;/li&gt;
&lt;/ol&gt;
&lt;br/&gt;
Информация взята с сайта Про Тестинг: &lt;a target="_blank" href="http://www.protesting.ru/automation/practice/work_load_model.html"&gt;Статья "Модель нагрузки, как отправная точка при тестировании производительности"&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-3982079179269448858?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=WVvWe8vER2s:7f5xLmBAxKs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=WVvWe8vER2s:7f5xLmBAxKs:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=WVvWe8vER2s:7f5xLmBAxKs:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=WVvWe8vER2s:7f5xLmBAxKs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/WVvWe8vER2s" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-27T14:12:21.277+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/09/blog-post.html</feedburner:origLink></item><item><title>Пишем систему автоматизированных тестов "с нуля"</title><link>http://feedproxy.google.com/~r/protesting/~3/IeZ_tF7BgXk/blog-post_28.html</link><category>Автоматизированное тестирование</category><category>планирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 27 Sep 2010 05:31:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-7852010351997334703</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/T7Pl-JfbZn57j0Zl9XlrffPpM6E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T7Pl-JfbZn57j0Zl9XlrffPpM6E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/T7Pl-JfbZn57j0Zl9XlrffPpM6E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T7Pl-JfbZn57j0Zl9XlrffPpM6E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Добрый день, &lt;br /&gt;
&lt;br /&gt;
На сайте протестинг была выложена статья &lt;a target="_blank"  href="http://www.protesting.ru/automation/practice/automation_from_scratch.html"&gt;Пишем систему автоматизированных тестов "с нуля"&lt;/a&gt; (автор мой коллега Владимир Антонов). Было бы не плохо, если бы всевидящее око тестировщиков ознакомилось с ней и оставило здесь в моем блоге свои комментарии :)&lt;br /&gt;
&lt;br /&gt;
Заранее спасибо,&lt;br /&gt;
Алексей Булат&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-7852010351997334703?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=IeZ_tF7BgXk:j0zmGf2qkWo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=IeZ_tF7BgXk:j0zmGf2qkWo:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=IeZ_tF7BgXk:j0zmGf2qkWo:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=IeZ_tF7BgXk:j0zmGf2qkWo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/IeZ_tF7BgXk" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-27T14:31:00.227+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">12</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/07/blog-post_28.html</feedburner:origLink></item><item><title>Автоматизированное тестирование: работа со статическими ресурсами</title><link>http://feedproxy.google.com/~r/protesting/~3/8RRyXOkPFl4/blog-post_23.html</link><category>Автоматизированное тестирование</category><category>тесты</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Wed, 08 Dec 2010 04:43:59 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-9056535314673539162</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8iM20H3WiwqdHGT63QCxGLS24io/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8iM20H3WiwqdHGT63QCxGLS24io/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8iM20H3WiwqdHGT63QCxGLS24io/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8iM20H3WiwqdHGT63QCxGLS24io/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Под статическим ресурсами понимаются те виды ресурсов, которые не изменяются в процессе тестирования или работы с приложением. К ним можно отнести названия и атрибуты элементов страниц, текст внутри элементов на странице, статусы документов и т.д.&lt;/p&gt;&lt;p&gt;Важной задачей при написании автоматических тестов и фреймворков является организация работы со статическими ресурсами, а именно: способ доступа и чтения необходимых данных.&lt;/p&gt;&lt;p&gt;Существует 2 основных варианта организации работы со статическими данными, которые имеют свои преимущества и недостатки:&lt;/p&gt;&lt;span class="fullpost"&gt;&lt;p&gt;&lt;ol&gt;&lt;li&gt;Прописывание данных внутри кода - hardcode (см. использование &lt;a target="_blank" href="http://alexeybulat.blogspot.com/2009/06/java-const.html"&gt;констант в Java&lt;/a&gt;)&lt;br /&gt;
Недостатки:&lt;br /&gt;
&lt;ul&gt;&lt;li/&gt;при изменении данных необходимо будет по-новой пере-собирать тесты&lt;br /&gt;
&lt;li/&gt;все статические ресурсы загружаются и хранятся в памяти и не могут быть освобождены.&lt;br /&gt;
&lt;/ul&gt;Преимущества: &lt;ul&gt;&lt;li/&gt;доступ к данным максимально упрощен&lt;br /&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Вынесение статических значений из кода (в БД, в файлы и т.д.)&lt;br /&gt;
Недостатки:&lt;br /&gt;
&lt;ul&gt;&lt;li/&gt;операция чтения из БД или файлов занимает определенное время и может значительно замедлить выполнение тестов.&lt;br /&gt;
&lt;li/&gt;файл или таблица БД может "залочиться", в случае одновременного использования одних и тех же ресурсов&lt;/ul&gt;Преимущества: &lt;ul&gt;&lt;li/&gt;возможность структурирования статических ресурсов в БД или файловой системе&lt;br /&gt;
&lt;li/&gt;возможность изменения статических ресурсов без последующего изменения в коде и пере-собирания тестов&lt;br /&gt;
&lt;li&gt;ресурсы из файла могу быть прочитаны, использованы тестом, удалены из памяти, а затем при необходимости снова прочитаны&lt;/li&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/ul&gt;&lt;/ol&gt;&lt;/p&gt;&lt;p&gt;По правде говоря, я не являюсь большим поклонником жесткого прописывания статических ресурсов в коде, хотя сторонников этого подхода хватает и у них есть веские причины следовать ему (неудобства и ограничения внутри IDE при работе с именами параметров, необходимость быстрого и максимально упрощенного доступа к данным).&lt;/p&gt;&lt;p&gt;Имея достаточное количество наработок при использовании файловой системы, в качестве контейнера для хранения статических ресурсов, я хотел бы поделиться своим методом работы с ними на базе Java Properties файлов.&lt;/p&gt;&lt;p&gt;Несколько слов о том, что такое проперти файл (Properties).&lt;/p&gt;&lt;p&gt;Это обычный текстовый файл, данные в котором хранятся в виде key = value Пример: &lt;b&gt;LoginPage.properties&lt;/b&gt;&lt;p&gt;&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;----------------
field.username.id = UserName
field.password.id = Password
button.login.id = LoginButton
----------------&lt;/pre&gt;&lt;p&gt;Пример Java кода, который читает LoginPage.properties файл и получает необходимую информацию:&lt;/p&gt;&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;----------------
// инициализация LoginPage.properties
Properties properties = new Properties();
File propertyFile = new File(LoginPage.properties);
properties.load(new FileReader(propertyFile));
// чтение данных
String userNameID = properties.getProperty("field.username.id");
String passwordID = properties.getProperty("field.password.id");
String loginButtonID = properties.getProperty("button.login.id");
----------------&lt;/pre&gt;&lt;p&gt;Конечно избавиться от хардкода нам не удастся на все 100%, однако в последнем случае жестко прописаны ключи к для доступа к данным, а не сами данные. Что является уже не хардкодом, а скажем "параметризацией".&lt;/p&gt;&lt;p&gt;Теперь на базе этого я расскажу, как построен тестовый фреймворк основанный на примере описанном в предыдущей статье &lt;a href="http://alexeybulat.blogspot.com/2010/07/pageobject-pattern-selenium-java.html"&gt;PageObjects pattern + Selenium (Java)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Основными принципами работы со статическими ресурсами в нашем приложении является то, то для каждого объекта страницы создается отдельный проперти файл с идентичным именем, хранящимися в проектном каталоге resources. Таким образом нам необходимо создать 3 файла и заполнить в них статическую информацию:&lt;/p&gt;&lt;b&gt;LoginPage.properties&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;----------------
field.username.locator = id
field.username.arg = UserName
field.password.locator = id
field.password.arg = Password
button.login.locator = id
button.login.arg = LoginButton
----------------&lt;/pre&gt;&lt;b&gt;HomePage.properties&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;----------------
text.username.locator = id
text.username.arg = userName
link.logout.locator = id
link.logout.arg = LogoutLink
----------------&lt;/pre&gt;&lt;b&gt;ErrorLoginPage.properties&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;----------------
text.errormessage.locator = id
text.errormessage.arg = ErrorMessage
link.backtologin.locator = id
link.backtologin.arg = BackLink
----------------&lt;/pre&gt;&lt;p&gt;Создав все необходимые ресурсы, перейдем к написанию Java кода, который будет осуществлять загрузку, хранение и чтение данных. Для хранения загруженных ресурсов создадим класс DataStorage. В нем будет храниться Map данных (Map&lt;String, Properties&gt; propertiesMap), ключом в котором будет являться название объекта страницы, а значением объект Properties со списком статических данных. &lt;/p&gt;&lt;b&gt;DataStorage.java&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class DataStorage {
   private Map&lt;String, Properties&gt; propertiesMap;

   private DataStorage() {
       this.propertiesMap = new HashMap&lt;String, Properties&gt;();
   }

   public static DataStorage getInstance() {
       return new DataStorage();
   }

   public void setProperty(String key, Properties properties) {
       propertiesMap.put(key, properties);
   }

   public Properties getProperty(String key) {
       return propertiesMap.get(key);
   }

   public boolean exists(String key) {
       return propertiesMap.get(key) != null;
   }
}&lt;/pre&gt;&lt;p&gt;Добавим ссылку на него в рабочем контексте, а также несколько сервисных методов для работы с ним (выделено жирным в листинге класса):&lt;/p&gt;&lt;b&gt;Context.java&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class Context {
   public static final String BROWSER_IE = "*iexplore";
   public static final String BROWSER_FF = "*firefox";
   public static final String BROWSER_CH = "*chrome";
   &lt;b&gt;private static final String RESOURCES_PATH = "resources/${NAME}.properties";&lt;/b&gt;    

   public static String siteUrl;
   private static Context context;
&lt;b&gt;   private DataStorage dataStorage;&lt;/b&gt;
   private Selenium selenium;
   private SeleniumServer seleniumServer;

   private Context() {
       &lt;b&gt;this.setDataStorage(DataStorage.getInstance());&lt;/b&gt;
   }

   public static void initInstance(String browserType, String siteURL) {
       context = new Context();
       siteUrl = siteURL;
       context.setSelenium(new DefaultSelenium("localhost", 4444, browserType, siteURL));
       context.start();
   }

   public static Context getInstance() {
       if (context == null) {
           throw new IllegalStateException("Context is not initialized");
       }
       return context;
   }

   public Selenium getSelenium() {
       if (selenium != null) {
           return selenium;
       }
       throw new IllegalStateException("WebBrowser is not initialized");
   }

   public void start() {
       try {
           seleniumServer = new SeleniumServer();
           seleniumServer.start();
       } catch (Exception e) {
           e.printStackTrace();
       }
       selenium.start();
   }

   public void close() {
       selenium.close();
       selenium.stop();
       seleniumServer.stop();
   }

   public String getSiteUrl() {
       return siteUrl;
   }

   public void setSelenium(Selenium selenium) {
       this.selenium = selenium;
   }

&lt;b&gt;   public String getResourcesPath(String name) {
       return RESOURCES_PATH.replaceAll("\\$\\{NAME\\}", name);
   }

   private void setDataStorage(DataStorage dataStorage) {
       this.dataStorage = dataStorage;
   }

   public DataStorage getDataStorage() {
       return dataStorage;
   }
&lt;/b&gt;}&lt;/pre&gt;&lt;p&gt;Теперь добавим в класс Page инициализацию ресурсов и сервисные методы для загрузки и чтения данных из файлов. Наиболее интересным из них будет являться метода initProperties(), который анализируя иерархию классов объекта страницы загружает необходимый проперти файл.&lt;/p&gt;&lt;b&gt;Page.java&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public abstract class Page {
   private Context context;
   private String currentPage;
&lt;b&gt;   private Properties properties;&lt;/b&gt;
   
   protected Page(String pageUrl) {
       this.currentPage = pageUrl;
       setContext(Context.getInstance());
       &lt;b&gt;initProperties();&lt;/b&gt;
       init();
       parsePage();
   }

&lt;b&gt;   private void initProperties() {
       String className = getClass().getSimpleName();
       if (!getContext().getDataStorage().exists(className)) {
           this.properties = new Properties();
           List superClasses = ClassUtils.getAllSuperclasses(getClass());
           File file = null;
           for (int i = superClasses.size() - 2; i &gt;= 0 ; i--) {
               Class aClass = (Class) superClasses.get(i);
               file = new File(getResourcesPath(aClass.getSimpleName()));
               if (getContext().getDataStorage().getProperty(aClass.getSimpleName())== null) {
                   if (file.exists()) {
                       putAllProperties(file);
                       updateStogare(aClass.getSimpleName(), getProperties());
                   }
               } else {
                   putAllProperties(getContext().getDataStorage().getProperty(aClass.getSimpleName()));
               }
           }
           file = new File(getResourcesPath(className));
           putAllProperties(file);
           updateStogare(this, getProperties());
       } else {
           setProperties(getContext().getDataStorage().getProperty(getClass().getSimpleName()));
       }
   }&lt;/b&gt;
   
   protected abstract void init();
   protected abstract void parsePage();

   private void setContext(Context instance) {
       this.context = instance;
   }

&lt;b&gt;   public Context getContext() {
       return context;
   }
&lt;/b&gt;
   public String getCurrentPage() {
       return context.getSiteUrl() + this.currentPage;
   }

   protected Selenium getSelenium() {
       return context.getSelenium();
   }

&lt;b&gt;   private String getResourcesPath(String name) {
       return getContext().getResourcesPath(name);
   }
   
   private Properties getProperties() {
       return properties;
   }
   
   private void setProperties(Properties properties) {
       this.properties = properties;
   }
   
   protected String getProperty(String key) {
       return properties.getProperty(key);
   }
   
   private void putAllProperties(File proertiesFile) {
       try {
           this.properties.load(new FileReader(proertiesFile));
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
   
   private void putAllProperties(Properties properties) {
       this.properties.putAll(properties);
   }

   private void updateStogare(Object parentKeyObj, Properties properties) {
       updateStogare(parentKeyObj.getClass().getSimpleName(), properties);
   }

   private void updateStogare(String className, Properties properties) {
       getContext().getDataStorage().setProperty(className, (Properties)properties.clone());
   }

   protected String buildLocator(String type, String arg) {
       // Сервисный метода для создания Selenium локатора 
       // по двум параметрам тип и аргумент
       return type + "=" + arg;
   }
&lt;/b&gt;
   // ....
   // service methods...
   // ....
}&lt;/pre&gt;&lt;p&gt;Заменив в объектах станиц, конкретные значения статических ресурсов на чтение их значений из объектов Properties мы получаем их следующую реализацию:&lt;/p&gt;&lt;b&gt;LoginPage.java&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class LoginPage extends Page {
   public static final String PAGE_URL = "http://www.testlogin.com/login.html";

    protected LoginPage() {
        super(PAGE_URL);
    }

    public static LoginPage openLoginPage() {
        LoginPage loginPage = new LoginPage();
        loginPage.getSelenium().open(PAGE_URL);
        return loginPage;
    }

    private void setUserName(String userName) {
        // код для заполнения поля Username
        &lt;b&gt;getSelenium().type(buildLocator(getProperty("field.username.locator"),getProperty("field.username.arg")), userName);
&lt;/b&gt;   }

    private void setPassword(String password) {
        // код для заполнения поля Password
&lt;b&gt;        getSelenium().type(buildLocator(getProperty("field.password.locator"), getProperty("field.password.arg")), password);
&lt;/b&gt;   }

    private void pushLoginButton() {
        // код для нажатия на кнопку Login
&lt;b&gt;        getSelenium().click(buildLocator(getProperty("button.login.locator"), getProperty("button.login.arg")));
&lt;/b&gt;   }

    protected void parsePage() {
        // Разбор элементов страницы
        // Заполнение необходимых переменных данными со страницы
    }

    protected void init() {
        // Инициализация страницы
        // Проверка корректности загрузки
        if(!getSelenium().getLocation().equals(PAGE_URL)) {
            throw new IllegalStateException("Invalid page is opened");
        }
    }

    private void loginAs(String userName, String password) {
        setUserName(userName);
        setPassword(password);
        pushLoginButton();
    }

    public HomePage login(String userName, String password) {
        loginAs(userName, password);
        return new HomePage();
    }

    public ErrorLoginPage loginInvalid(String userName, String password) {
        loginAs(userName, password);
        return new ErrorLoginPage();
    }
}&lt;/pre&gt;&lt;b&gt;HomePage.java&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class HomePage extends Page {
    public static final String PAGE_URL = "http://www.testlogin.com/home.html";
    private String loggedinUserName;

    protected HomePage() {
        super(PAGE_URL);
    }

    protected void init() {
// Инициализация страницы
    }

    protected void parsePage() {
// Разбор элементов страницы
&lt;b&gt;        this.loggedinUserName = getSelenium().getText(buildLocator(getProperty("text.username.locator"), getProperty("text.username.id")));
&lt;/b&gt;   }

    public String getLoggedinUserName() {
        return loggedinUserName;
    }

    public LoginPage logout() {
&lt;b&gt;        getSelenium().click(buildLocator(getProperty("link.logout.locator"), getProperty("link.logout.id")));
&lt;/b&gt;       return new LoginPage();
    }
}&lt;/pre&gt;&lt;b&gt;ErrorLoginPage.java&lt;/b&gt; &lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class ErrorLoginPage extends Page {
    public static final String PAGE_URL = "http://www.testlogin.com/loginError.html";
    private String errorMessage;

    protected ErrorLoginPage() {
        super(PAGE_URL);
    }

    protected void init() {
// Инициализация страницы
    }

    protected void parsePage() {
&lt;b&gt;        this.errorMessage = getSelenium().getText(buildLocator(getProperty("text.errormessage.locator"), getProperty("text.errormessage.id")));
&lt;/b&gt;   }

    public String getErrorMessage() {
        return this.errorMessage;
    }

    public LoginPage backToLoginPage() {
&lt;b&gt;        getSelenium().click(buildLocator(getProperty("link.backtologin.locator"), getProperty("link.backtologin.id")));
&lt;/b&gt;       return new LoginPage();
    }
}
&lt;/pre&gt;&lt;p&gt;Скачать &lt;a href="http://www.protesting.ru/automation/practice/staticResources.zip"&gt;исходный код примеров по работе со статическими ресурсами&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Обратите внимание, что в теперешней реализации мы вынесли все статические ресурсы в файлы. И теперь в случае, если какие-то данные будут изменены, например, id  “UserName” изменится на “user_name” и нужно будет изменить тип локатора для поиска c “id” на “xpath”, то нам всего навсего надо будет заменить значение в файле, оставив код фреймворка без изменения:&lt;/p&gt;&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;field.username.locator = xpath
field.username.arg = //input[@id=’user_name’]&lt;/pre&gt;&lt;p&gt;Описанный выше подход при работе со статическими ресурсами, используется уже на протяжении двух лет, и значит он в полевых условиях доказал свое право на существование. Надеюсь, что после внимательного прочтения кому-то тоже захочется реализовать у себя что-то похожее, либо абсолютно такое же. &lt;/p&gt;&lt;p&gt;З&lt;b&gt;Ы Комментарии приветствуются, критика тоже... жду отзывов...&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Да приумножится Ваша Автоматизация, Алексей Булат&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-9056535314673539162?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=8RRyXOkPFl4:R4dtRlFDXNU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=8RRyXOkPFl4:R4dtRlFDXNU:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=8RRyXOkPFl4:R4dtRlFDXNU:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=8RRyXOkPFl4:R4dtRlFDXNU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/8RRyXOkPFl4" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-08T13:43:59.519+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><enclosure url="http://www.protesting.ru/automation/practice/staticResources.zip" length="6562" type="application/zip" /><media:content url="http://www.protesting.ru/automation/practice/staticResources.zip" fileSize="6562" type="application/zip" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> Под статическим ресурсами понимаются те виды ресурсов, которые не изменяются в процессе тестирования или работы с приложением. К ним можно отнести названия и атрибуты элементов страниц, текст внутри элементов на странице, статусы документов и т.д. Важной</itunes:subtitle><itunes:author>noreply@blogger.com (Алексей Булат)</itunes:author><itunes:summary> Под статическим ресурсами понимаются те виды ресурсов, которые не изменяются в процессе тестирования или работы с приложением. К ним можно отнести названия и атрибуты элементов страниц, текст внутри элементов на странице, статусы документов и т.д. Важной задачей при написании автоматических тестов и фреймворков является организация работы со статическими ресурсами, а именно: способ доступа и чтения необходимых данных. Существует 2 основных варианта организации работы со статическими данными, которые имеют свои преимущества и недостатки: Прописывание данных внутри кода - hardcode (см. использование констант в Java) Недостатки: при изменении данных необходимо будет по-новой пере-собирать тесты все статические ресурсы загружаются и хранятся в памяти и не могут быть освобождены. Преимущества: доступ к данным максимально упрощен Вынесение статических значений из кода (в БД, в файлы и т.д.) Недостатки: операция чтения из БД или файлов занимает определенное время и может значительно замедлить выполнение тестов. файл или таблица БД может "залочиться", в случае одновременного использования одних и тех же ресурсовПреимущества: возможность структурирования статических ресурсов в БД или файловой системе возможность изменения статических ресурсов без последующего изменения в коде и пере-собирания тестов ресурсы из файла могу быть прочитаны, использованы тестом, удалены из памяти, а затем при необходимости снова прочитаны По правде говоря, я не являюсь большим поклонником жесткого прописывания статических ресурсов в коде, хотя сторонников этого подхода хватает и у них есть веские причины следовать ему (неудобства и ограничения внутри IDE при работе с именами параметров, необходимость быстрого и максимально упрощенного доступа к данным). Имея достаточное количество наработок при использовании файловой системы, в качестве контейнера для хранения статических ресурсов, я хотел бы поделиться своим методом работы с ними на базе Java Properties файлов. Несколько слов о том, что такое проперти файл (Properties). Это обычный текстовый файл, данные в котором хранятся в виде key = value Пример: LoginPage.properties ---------------- field.username.id = UserName field.password.id = Password button.login.id = LoginButton ---------------- Пример Java кода, который читает LoginPage.properties файл и получает необходимую информацию:---------------- // инициализация LoginPage.properties Properties properties = new Properties(); File propertyFile = new File(LoginPage.properties); properties.load(new FileReader(propertyFile)); // чтение данных String userNameID = properties.getProperty("field.username.id"); String passwordID = properties.getProperty("field.password.id"); String loginButtonID = properties.getProperty("button.login.id"); ---------------- Конечно избавиться от хардкода нам не удастся на все 100%, однако в последнем случае жестко прописаны ключи к для доступа к данным, а не сами данные. Что является уже не хардкодом, а скажем "параметризацией". Теперь на базе этого я расскажу, как построен тестовый фреймворк основанный на примере описанном в предыдущей статье PageObjects pattern + Selenium (Java) Основными принципами работы со статическими ресурсами в нашем приложении является то, то для каждого объекта страницы создается отдельный проперти файл с идентичным именем, хранящимися в проектном каталоге resources. Таким образом нам необходимо создать 3 файла и заполнить в них статическую информацию:LoginPage.properties ---------------- field.username.locator = id field.username.arg = UserName field.password.locator = id field.password.arg = Password button.login.locator = id button.login.arg = LoginButton ----------------HomePage.properties ---------------- text.username.locator = id text.username.arg = userName link.logout.locator = id link.logout.arg = LogoutLink ----------------ErrorLoginPage.properties ---------------- text.errormessage.locator = id text.errormessage.arg = ErrorMessage link.backtologin.locator = id link.backtologin.arg = BackLink </itunes:summary><itunes:keywords>Автоматизированное тестирование, тесты</itunes:keywords><feedburner:origLink>http://alexeybulat.blogspot.com/2010/07/blog-post_23.html</feedburner:origLink></item><item><title>PageObjects pattern + Selenium (Java)</title><link>http://feedproxy.google.com/~r/protesting/~3/4BHLHLEQG6c/pageobject-pattern-selenium-java.html</link><category>Автоматизированное тестирование</category><category>тесты</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Wed, 10 Nov 2010 04:28:22 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-5735575204959153112</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EZgmlfxrAGrxgo4XkufMdJLHrhI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EZgmlfxrAGrxgo4XkufMdJLHrhI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EZgmlfxrAGrxgo4XkufMdJLHrhI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EZgmlfxrAGrxgo4XkufMdJLHrhI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Попробуем на небольшом примере показать как, используя &lt;a target="_blank" href="http://alexeybulat.blogspot.com/2010/07/pageobjects-pattern.html"&gt;PageObjects pattern&lt;/a&gt; и &lt;a target="_blank" href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; (Java), можно достаточно быстро реализовать фреймоворк для автоматизированного тестирования, и начать писать понятные, легко поддерживаемые, а главное работающие тесты.&lt;/p&gt;&lt;b&gt;Пример: &lt;/b&gt;&lt;br /&gt;
&lt;p&gt;Страница LoginPage состоит из двух полей ввода User и Password, кнопки Login. При отправке корректного логина и пароля открывается страница Home на которой есть имя пользователя и ссылка Logout.  При отправке НЕкорректного логина и пароля открывается страница ErrorLogin, на которой есть сообщение об ошибке и ссылка Back To Login Page.  &lt;/p&gt;&lt;br /&gt;
&lt;b&gt;Задание:&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;Написать тестовые скрипты:&lt;br /&gt;
1. Корректный Login -&gt; проверка имени пользователя -&gt; Logout&lt;br /&gt;
2. Некорректный Login -&gt; проверка сообщения об ошибке -&gt; Back To Login Page&lt;/p&gt;&lt;br /&gt;
&lt;b&gt;Решение:&lt;/b&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;
&lt;p&gt;1. Создаем рабочий контекст на базе Selenium&lt;/p&gt;&lt;b&gt;Context.java:&lt;/b&gt;&lt;br /&gt;
&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class Context {
    public static final String BROWSER_IE = "*iexplore";
    public static final String BROWSER_FF = "*firefox";
    public static final String BROWSER_CH = "*chrome";
    
    private static Context context;
    private static String siteUrl;
   
    private Selenium browser;
    private SeleniumServer seleniumServer;

    private Context() {
    }

    public static void initInstance(String browserType, String siteURL) {
        context = new Context();
        siteUrl = siteURL;
        context.setBrowser(new DefaultSelenium("localhost", 4444, browserType, siteURL));
        context.start();
    }

    public static Context getInstance() {
        if (context == null) {
            throw new IllegalStateException("Context is not initialized");
        }
        return context;
    }

    public Selenium getBrowser() {
        if (browser != null) {
            return browser;
        }
        throw new IllegalStateException("WebBrowser is not initialized");
    }
    
    public String getSiteUrl() {
       return siteUrl;
    }

    public void start() {
        try {
            seleniumServer = new SeleniumServer();
            seleniumServer.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
        browser.start();
    }
    
    public void close() {
        browser.close();
        browser.stop();
        seleniumServer.stop();
    }
        
    public void setBrowser(Selenium browser) {
        this.browser = browser;
    }
}&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;2. Добавляем в абстрактный суперкласс Page ссылку на рабочий контекст context, а также сервисный метод для получения из него объекта Selenium getBrowser().&lt;/p&gt;&lt;br /&gt;
&lt;b&gt;Page.java:&lt;/b&gt;&lt;br /&gt;
&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public abstract class Page {
    private Context context;
    private String currentPage; 
    
    protected Page(String pageUrl) {
        this.currentPage = pageUrl;
        setContext(Context.getInstance());
        init();
        parsePage();
    }

    private void setContext(Context instance) {
        this.context = instance;
    }

    protected abstract void init();
    protected abstract void parsePage();

    public String getCurrentPage() {
  return context.getSiteUrl() + this.currentPage;
    }
   
    protected Selenium getBrowser() {
        return context.getBrowser();
    }

    // ....
    // service methods...
    // ....
}&lt;/pre&gt;&lt;p&gt;3. Реализуем классы страниц, необходимые при написании тестов для нашего примера, а именно: LoginPage, HomePage и ErrorLoginPage. И добавляем в сервисные методы реальный ввод данных в поля, нажатие кнопок и клики на ссылки&lt;/p&gt;&lt;br /&gt;
&lt;b&gt;LoginPage.java:&lt;/b&gt;&lt;br /&gt;
&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class LoginPage extends Page {
   public static final String PAGE_URL = "/login.html";

   protected LoginPage() {
       super(PAGE_URL);
   }

   public static LoginPage openLoginPage() {
       LoginPage loginPage = new LoginPage();
       loginPage.getBrowser().open(PAGE_URL);
       return loginPage;
   }

   private void setUserName(String userName) {
       // код для заполнения поля Username
       getBrowser().type("id=UserName", userName);
   }

   private void setPassword(String password) {
       // код для заполнения поля Password
       getBrowser().type("id=Password", password);
   }

   private void pushLoginButton() {
       // код для нажатия на кнопку Login
       getBrowser().click("id=LoginButton");
   }

   protected void parsePage() {
       // Разбор элементов страницы
       // Заполнение необходимых переменных данными со страницы
   }

   protected void init() {
       // Инициализация страницы, например проверка адреса (URL) страницы:   
       if(!getBrowser().getLocation().equals(PAGE_URL)) {
           throw new IllegalStateException("Invalid page is opened");
       }
       // Можно также добавить проверки наличия необходимых для дальнейшей работы 
       // объектов и т.д.
   }

   private void loginAs(String userName, String password) {
       setUserName(userName);
       setPassword(password);
       pushLoginButton();
   }

   public HomePage login(String userName, String password) {
       loginAs(userName, password);
       return new HomePage();
   }

   public ErrorLoginPage loginInvalid(String userName, String password) {
       loginAs(userName, password);
       return new ErrorLoginPage();
   }
}&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;HomePage.java:&lt;/b&gt;&lt;br /&gt;
&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class HomePage extends Page {
   public static final String PAGE_URL = "/home.html";
   private String loggedinUserName;

   protected HomePage() {
       super(PAGE_URL);
   }

   protected void init() {
       // Инициализация страницы
   }

   protected void parsePage() {
       // Разбор элементов страницы
       this.loggedinUserName = getBrowser().getText("id=userName");
   }

   public String getLoggedinUserName() {
       return loggedinUserName;
   }

   public LoginPage logout() {
       getBrowser().click("id=LogoutLink");
       return new LoginPage();
   }
}&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;ErrorLoginPage.java:&lt;/b&gt;&lt;br /&gt;
&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class ErrorLoginPage extends Page {
   public static final String PAGE_URL = "/loginError.html";
   private String errorMessage;
 
   protected ErrorLoginPage() {
       super(PAGE_URL);
   }

   protected void init() {
       // Инициализация страницы
   }

   protected void parsePage() {
       // Разбор элементов страницы
       this.errorMessage = getBrowser().getText("id=ErrorMessage");
   }

   public String getErrorMessage() {
       return this.errorMessage;
   }

   public LoginPage backToLoginPage() {
       getBrowser().click("id=BackLink");
       return new LoginPage();
   }
}&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;4. Пишем тесты на базе &lt;a target="_blank" href="http://www.junit.org/"&gt;JUnit&lt;/a&gt;:&lt;/p&gt;&lt;pre style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class TestLogin extends TestCase {
   public void setUp() {
        // Инициализация контекста. 
        Context.initInstance(Context.BROWSER_IE, "http://www.testtesttestlogin.com");
    }

   public void testLoginLogout() {
        String userName = "tester";
        String password = "testPass";
        LoginPage loginPage = LoginPage.openLoginPage();
        HomePage homePage = loginPage.login(userName, password);
        assertEquals(userName, homePage.getLoggedinUserName());
        homePage.logout();
    }

    public void testInvalidLogin() {
        String userName = "$tester@#";
        String password = "********";
        String expectedMessage = "Invalid username or password"; 
        LoginPage loginPage = LoginPage.openLoginPage();
        ErrorLoginPage errorLoginPage = loginPage.loginInvalid(userName, password);
        assertEquals(expectedMessage, errorLoginPage.getErrorMessage());
        errorLoginPage.backToLoginPage();
    }

    protected void tearDown() throws Exception {
        // закрытие браузера
       Context.getInstance().close(); 
    }
}&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Скачать &lt;a href="http://www.protesting.ru/automation/practice/pageObjectPattern.zip"&gt;исходный код примеров по PageObjectPattern&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Вот все и готово - первые объекты страниц, первые тесты. Попробуйте, может и Вам подойдет подобная архитектура. В любом случае всегда все можно обсудить - любые комментарии с вопросами и конструктивной критикой приветствуются. Вопросы “отвечаются” быстро, критика анализируется... :)&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Алексей Булат&lt;br /&gt;
Да прибудет с Вами автотестинг.&lt;/p&gt;&lt;br /&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-5735575204959153112?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=4BHLHLEQG6c:uIKlAgQJNe8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=4BHLHLEQG6c:uIKlAgQJNe8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=4BHLHLEQG6c:uIKlAgQJNe8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=4BHLHLEQG6c:uIKlAgQJNe8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/4BHLHLEQG6c" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-10T13:28:22.963+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><enclosure url="http://www.protesting.ru/automation/practice/pageObjectPattern.zip" length="4353" type="application/zip" /><media:content url="http://www.protesting.ru/automation/practice/pageObjectPattern.zip" fileSize="4353" type="application/zip" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> Попробуем на небольшом примере показать как, используя PageObjects pattern и Selenium (Java), можно достаточно быстро реализовать фреймоворк для автоматизированного тестирования, и начать писать понятные, легко поддерживаемые, а главное работающие тесты.</itunes:subtitle><itunes:author>noreply@blogger.com (Алексей Булат)</itunes:author><itunes:summary> Попробуем на небольшом примере показать как, используя PageObjects pattern и Selenium (Java), можно достаточно быстро реализовать фреймоворк для автоматизированного тестирования, и начать писать понятные, легко поддерживаемые, а главное работающие тесты.Пример: Страница LoginPage состоит из двух полей ввода User и Password, кнопки Login. При отправке корректного логина и пароля открывается страница Home на которой есть имя пользователя и ссылка Logout. При отправке НЕкорректного логина и пароля открывается страница ErrorLogin, на которой есть сообщение об ошибке и ссылка Back To Login Page. Задание: Написать тестовые скрипты: 1. Корректный Login - проверка имени пользователя - Logout 2. Некорректный Login - проверка сообщения об ошибке - Back To Login Page Решение: 1. Создаем рабочий контекст на базе SeleniumContext.java: public class Context { public static final String BROWSER_IE = "*iexplore"; public static final String BROWSER_FF = "*firefox"; public static final String BROWSER_CH = "*chrome"; private static Context context; private static String siteUrl; private Selenium browser; private SeleniumServer seleniumServer; private Context() { } public static void initInstance(String browserType, String siteURL) { context = new Context(); siteUrl = siteURL; context.setBrowser(new DefaultSelenium("localhost", 4444, browserType, siteURL)); context.start(); } public static Context getInstance() { if (context == null) { throw new IllegalStateException("Context is not initialized"); } return context; } public Selenium getBrowser() { if (browser != null) { return browser; } throw new IllegalStateException("WebBrowser is not initialized"); } public String getSiteUrl() { return siteUrl; } public void start() { try { seleniumServer = new SeleniumServer(); seleniumServer.start(); } catch (Exception e) { e.printStackTrace(); } browser.start(); } public void close() { browser.close(); browser.stop(); seleniumServer.stop(); } public void setBrowser(Selenium browser) { this.browser = browser; } } 2. Добавляем в абстрактный суперкласс Page ссылку на рабочий контекст context, а также сервисный метод для получения из него объекта Selenium getBrowser(). Page.java: public abstract class Page { private Context context; private String currentPage; protected Page(String pageUrl) { this.currentPage = pageUrl; setContext(Context.getInstance()); init(); parsePage(); } private void setContext(Context instance) { this.context = instance; } protected abstract void init(); protected abstract void parsePage(); public String getCurrentPage() { return context.getSiteUrl() + this.currentPage; } protected Selenium getBrowser() { return context.getBrowser(); } // .... // service methods... // .... } 3. Реализуем классы страниц, необходимые при написании тестов для нашего примера, а именно: LoginPage, HomePage и ErrorLoginPage. И добавляем в сервисные методы реальный ввод данных в поля, нажатие кнопок и клики на ссылки LoginPage.java: public class LoginPage extends Page { public static final String PAGE_URL = "/login.html"; protected LoginPage() { super(PAGE_URL); } public static LoginPage openLoginPage() { LoginPage loginPage = new LoginPage(); loginPage.getBrowser().open(PAGE_URL); return loginPage; } private void setUserName(String userName) { // код для заполнения поля Username getBrowser().type("id=UserName", userName); } private void setPassword(String password) { // код для заполнения поля Password getBrowser().type("id=Password", password); } private void pushLoginButton() { // код для нажатия на кнопку Login getBrowser().click("id=LoginButton"); } protected void parsePage() { // Разбор элементов страницы // Заполнение необходимых переменных данными со страницы } protected void init() { // Инициализация страницы, например проверка адреса (URL) страницы: if(!getBrowser().getLocation().equals(PAGE_URL)) { throw new IllegalStateException("Invalid page is opened"); } // Можно также добавить проверки наличия необходимых для дальнейшей работы // объектов и т.д</itunes:summary><itunes:keywords>Автоматизированное тестирование, тесты</itunes:keywords><feedburner:origLink>http://alexeybulat.blogspot.com/2010/07/pageobject-pattern-selenium-java.html</feedburner:origLink></item><item><title>PageObjects pattern или работаем по науке</title><link>http://feedproxy.google.com/~r/protesting/~3/cNHf2GDLJns/pageobjects-pattern.html</link><category>Автоматизированное тестирование</category><category>тесты</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Thu, 15 Jul 2010 09:24:44 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-8919874937337948093</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/l_kpDfk4MolNyczZtAbzpBC2dT8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l_kpDfk4MolNyczZtAbzpBC2dT8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/l_kpDfk4MolNyczZtAbzpBC2dT8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l_kpDfk4MolNyczZtAbzpBC2dT8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span id="internal-source-marker_0.8752963505685329" style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Хочется поговорить об автоматизированных тестах, а точнее даже об организации фреймворков для них, а если быть более точным об одном из самых распространенных подходов в автоматизации тестирования через GUI - о &lt;/span&gt;&lt;a href="http://code.google.com/p/selenium/wiki/PageObjects?redir=1" target="_blank"&gt;&lt;span style="background-color: transparent; color: #000099; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: bold; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt;PageObjects pattern&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Мое первое знакомство с ним состоялось 5 лет назад, когда ничего не подозревая, мой коллега предложил, организовать наш тестовый фреймворк таким образом, чтобы каждой странице соответствовал один класс, тогда мы называли его парсер (Page Parser). Идея прошла свое крещение и была воплощена, а самое главное, живет и до сих пор.&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;В двух словах про реализацию.&lt;/span&gt;&lt;/div&gt;&lt;span class="fullpost"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="fullpost"&gt;&lt;div style="background-color: transparent; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="fullpost"&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Есть абстрактный супер-класс Page, реализующий основные методы одинаковые для всех страниц тестируемого приложения (например logout), а также абстрактные методы инициализации и сбора необходимых данных со страницы, вызывающиеся из конструктора. &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public abstract class Page {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected Page() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;init();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;parsePage();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected abstract void init();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected abstract void parsePage();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// ....&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// service methods...&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 11px; white-space: pre-wrap;"&gt; // ....&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="fullpost"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 11px; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 11px;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="fullpost"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 11px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Далее, все классы реальных страниц наследуют супер-класс Page, реализует абстрактные и добавляет свои методы для функций выполняющихся на этой конкретной странице, причем методы взаимодействия с элементами управления, которые не содержат логики описываем как &lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;private void&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;, методы выполняющие действия пользователя, вызывающие открытие новой или обновление активной страницы - public с возвращением ожидаемого объекта (&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public HomePage&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;). &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;В итоге, при создании объекта страницы сначала она будет проинициализирована, а потом разобрана (parsed), что даст нам гарантию того, что открыта правильная страница и все необходимые данные собраны, т.е. объект готов к использованию.&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Пример:&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Страница Login Portal состоит из двух полей ввода User и Password, кнопки Login.&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Как будет выглядеть наш PageObject?&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class LoginPortalPage extends Page {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected LoginPortalPage() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;super();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void setUserName(String userName) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// код для заполнения поля Username&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void setPassword(String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// код для заполнения поля Password&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void pushLoginButton() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// код для нажатия на кнопку Login&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected void parsePage() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Разбор элементов страницы&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Заполнение необходимых переменных данными со страницы&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected void init() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Инициализация страницы&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Проверка корректности загрузки&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;}&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Из данного примера видно, что методы в данном классе &lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;LoginPortalPage &lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;соответствуют тем действиям, которые может делать пользователь на этой странице, а именно ввести имя (&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;setUserName&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;), пароль (&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;setPassword&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;), нажать кнопку Login (&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;pushLogin&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;).&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Но это еще не все. Данный пример никак не показывает, каким образом мы получаем следующую страницу, после нажатия кнопки Login. Добавим еще несколько сервисных методов, присущих только этого классу:&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void loginAs(String userName, String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;setUserName(userName);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;setPassword(password);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;pushLoginButton();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;public HomePage login(String userName, String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;loginAs(userName, password);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return new HomePage();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;public ErrorLoginPage loginInvalid(String userName, String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;loginAs(userName, password);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return new ErrorLoginPage();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;Таким образом в своем “окончательном” &amp;nbsp;варианте класс &lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;LoginPortalPage &lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;будет выглядеть следующим образом:&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;public class LoginPortalPage extends Page {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected LoginPortalPage() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;super();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void setUserName(String userName) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// код для заполнения поля Username&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void setPassword(String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// код для заполнения поля Password&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void pushLoginButton() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// код для нажатия на кнопку Login&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected void parsePage() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Разбор элементов страницы&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Заполнение необходимых переменных данными со страницы&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;protected void init() {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Инициализация страницы&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;// Проверка корректности загрузки&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private void loginAs(String userName, String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;setUserName(userName);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;setPassword(password);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;pushLoginButton();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;public HomePage login(String userName, String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;loginAs(userName, password);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return new HomePage();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;public ErrorLoginPage loginInvalid(String userName, String password) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;loginAs(userName, password);&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return new ErrorLoginPage();&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: 'Courier New'; font-size: 8pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;}&lt;/span&gt;&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"&gt;Вообще, вариантов реализации&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"&gt;PageObject-ов &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"&gt;может много в зависимости от предпочтений того или иного разработчика. Я лишь показал свой вариант, который прошел боевое крещение и показал свою состоятельность на практике. Надеюсь, что в дальнейшем я найду в себе силы и продолжу описание практических советов по использованию &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"&gt;PageObject pattern.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-8919874937337948093?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=cNHf2GDLJns:6wDcQEyA3Qg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=cNHf2GDLJns:6wDcQEyA3Qg:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=cNHf2GDLJns:6wDcQEyA3Qg:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=cNHf2GDLJns:6wDcQEyA3Qg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/cNHf2GDLJns" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-15T18:24:44.832+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/07/pageobjects-pattern.html</feedburner:origLink></item><item><title>Кириллические домены уже среди нас - УРА товарищи!!!</title><link>http://feedproxy.google.com/~r/protesting/~3/__U_J0BJgSo/blog-post.html</link><category>интересные баги</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 17 May 2010 09:31:56 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-59773590503546572</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kQg2iS8SLj29BnimVN9vJO72wq4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kQg2iS8SLj29BnimVN9vJO72wq4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kQg2iS8SLj29BnimVN9vJO72wq4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kQg2iS8SLj29BnimVN9vJO72wq4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;За прошедшей на днях конференцией &lt;a href="http://it-conf.ru/ru/content/242.htm?utm_source=Protesting&amp;amp;utm_medium=email&amp;amp;utm_campaign=Protesting"&gt;SQA Days 7&lt;/a&gt;, достаточно незаметно промелькнула новость, что Россия наконец-таки зарегистрировала первые кириллические домены: &lt;br /&gt;
&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;a href="http://xn--d1abbgf6aiiy.xn--p1ai/"&gt;президент.рф&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;a href="http://xn--80aealotwbjpid2k.xn--p1ai/"&gt;правительство.рф&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Странно, что сообщество тестировщиков обошло стороной это событие. Поэтому пользуясь тем, что пока еще никто не озвучил ничего по этому поводу, напишу некоторые свои&amp;nbsp;наблюдения:&lt;br /&gt;
&lt;span class="fullpost"&gt;1. &lt;b&gt;Google Chrome&lt;/b&gt; наотрез отказался открывать вышеупомянутые сайты при вводе адреса в вышеупомянутом виде:&amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;президент.рф&lt;/span&gt;. Однако, открыл их по полному адресу: &lt;span class="Apple-style-span" style="color: blue;"&gt;http://www.президент.рф&lt;/span&gt; или &lt;span class="Apple-style-span" style="color: blue;"&gt;http://президент.рф&lt;/span&gt;&lt;br /&gt;
2. &lt;b&gt;Safari&lt;/b&gt; и &lt;b&gt;FireFox&lt;/b&gt; - открыли,  но покосячили имя домена, заменив их на что-то подобное: &lt;a href="http://www.xn--d1abbgf6aiiy.xn--p1ai/"&gt;http://www.xn--d1abbgf6aiiy.xn--p1ai/ &lt;/a&gt;&lt;br /&gt;
3. &lt;b&gt;IE 8&lt;/b&gt; и &lt;b&gt;Opera&lt;/b&gt; - открыли нормально. Однако, при работе с подсказками в адресной строке, кириллическое доменное имя преобразуется в аналогичное указанному в пункте 2 (&lt;a href="http://www.xn--d1abbgf6aiiy.xn--p1ai/"&gt;http://www.xn--d1abbgf6aiiy.xn--p1ai/&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
Также я нашел еще одну недоработку, связанную уже с работой сайта:&lt;br /&gt;
домен на русском, а пути к файлам - на привычном всем английском языке. Именно поэтому мы видим вот такую мешанину:&lt;br /&gt;
&lt;br /&gt;
http://&lt;span class="Apple-style-span" style="color: blue;"&gt;правительство.рф&lt;/span&gt;/&lt;b&gt;online&lt;/b&gt;/&lt;br /&gt;
http://&lt;span class="Apple-style-span" style="color: blue;"&gt;президент.рф&lt;/span&gt;/&lt;b&gt;news&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Думаю, что если копнуть глубже, то будет найдено еще больше проблем, несоответствий и недоработок.&amp;nbsp;Таким образом могу резюмировать, что работы прибавилось и&amp;nbsp;прибавится&amp;nbsp;не только тестировщикам, но и создателям браузеров.&lt;br /&gt;
&lt;br /&gt;
С вами был,&lt;br /&gt;
Алексей Булат&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-59773590503546572?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=__U_J0BJgSo:8fKcfOYYBHE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=__U_J0BJgSo:8fKcfOYYBHE:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=__U_J0BJgSo:8fKcfOYYBHE:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=__U_J0BJgSo:8fKcfOYYBHE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/__U_J0BJgSo" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-17T18:31:56.112+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/05/blog-post.html</feedburner:origLink></item><item><title>Тестирование по факту или/и по предоплате</title><link>http://feedproxy.google.com/~r/protesting/~3/o6UdzyLoJGY/blog-post.html</link><category>тестирование ПО</category><category>Автоматизированное тестирование</category><category>Обеспечение качества. Контроль качества. Тестирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Thu, 15 Jul 2010 09:29:38 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-1697963820845937207</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zefVgvHWrzIRxMiAl2Fg48YQIm8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zefVgvHWrzIRxMiAl2Fg48YQIm8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zefVgvHWrzIRxMiAl2Fg48YQIm8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zefVgvHWrzIRxMiAl2Fg48YQIm8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Тестирование черного ящика - это по существу "&lt;b&gt;тестирование по факту"&lt;/b&gt;. Приложение уже собрали и положили нам на блюдечко с голубой каемочкой. Нам остается лишь найти баги, которые в нем есть. Уверен, именно так и теструется большинство программных продуктов. Делается это вручную или автоматизированно - это уже не важно, так как это делается по факту выдачи программы, хотя и в тестовую, но все же в эксплуатацию.&lt;br /&gt;
&lt;span class="fullpost"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="fullpost"&gt;- Да, с виду коробка прямоугольной формы, черного цвета, есть некоторые явные и видные невооруженным взглядом "дыры". Коробка может с легкостью выдержать большое давление (если на нее сесть) или удар (если её сбросить с большой высоты). Но вот что творится внутри неё, мы никогда не узнаем. А ведь могли бы, если бы знали как прочитать закорючки называемые "исходный код". Осталось немного - это выучить язык программирования и часто используемые новомодные фреймоврки.&lt;br /&gt;
И... Мы переходим на новый уровень! Уау - новые фичи, новые приемы.&lt;br /&gt;
Мы смотрим в код и уже видим не закорючки, а вполне понятные операторы, методы, класссы. Мы понимаем откуда все берется и куда кладется. Прокачивая свой уровень в программировании, нас может ждать два пути: &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;мы перейдем в разработчики, пытаясь не повторять уже известные нам ошибки.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;мы останемся в тестировании, НО не ограничимся "тестированием по факту", а начнем работать по "&lt;b&gt;предоплате&lt;/b&gt;", т.е. с белым ящиком или комбинируя - с серым. &lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;При этом основным бонусом будет не нахождение багов в готовом продукте, а предотвращение их появления в нем. Для этого существует большое количество статических техник, таких как: ревизия дизайна, кода, анализ причин ошибок. Либо автоматизированное тестирование на уровне модулей, объектов, систем перед сборкой приложения. &lt;br /&gt;
Конечно, работа по "предоплате" не удовлетворит все наши нужды на 100%, поэтому людям, занимающимся тестированием по факту, всегда будет место, но вот улов багов у них будет совершенно иной.&lt;br /&gt;
P.S. Навеяно требованиями к &lt;a href="http://googletesting.blogspot.com/2010/03/google-is-hiring-sets.html"&gt;Software Engineer in Test в компании google&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-1697963820845937207?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=o6UdzyLoJGY:FWGDrXadrug:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=o6UdzyLoJGY:FWGDrXadrug:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=o6UdzyLoJGY:FWGDrXadrug:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=o6UdzyLoJGY:FWGDrXadrug:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/o6UdzyLoJGY" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-15T18:29:38.923+02:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">14</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/04/blog-post.html</feedburner:origLink></item><item><title>Разработка тест кейсов или практическое применение тест дизайна</title><link>http://feedproxy.google.com/~r/protesting/~3/nGRQqKnjaOU/blog-post.html</link><category>тесты</category><category>тест кейс</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Thu, 18 Mar 2010 07:58:21 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-4955558629912957827</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/OTxLzp_K-tFCtPY9vDk2S4L7bRg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OTxLzp_K-tFCtPY9vDk2S4L7bRg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/OTxLzp_K-tFCtPY9vDk2S4L7bRg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OTxLzp_K-tFCtPY9vDk2S4L7bRg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Добрый день, мы с коллегой выложили сегодня на сайте новую статью по практическому применению некоторых техник тест дизайна. Думаю, что она будет полезна для новичков и вполне возможно для более опытных специалистов.&lt;br /&gt;&lt;br /&gt;Мы постарались коротко, на небольшом примере, описать процесс разработки тест кейсов для небольшой формы приема заявок.&lt;br /&gt;&lt;br /&gt;Ах, да, вот ссылка на статью: &lt;a target="_blank" href="http://www.protesting.ru/testing/testdesign_practice.html"&gt;Практическое применение техник тест дизайна при разработке тест кейсов&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Хотелось бы послушать Ваши комментарии и предложения по улучшению материала.&lt;br /&gt;&lt;br /&gt;С уважением,&lt;br /&gt;Алексей Булат&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-4955558629912957827?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=nGRQqKnjaOU:p-nKwSpJ8b0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=nGRQqKnjaOU:p-nKwSpJ8b0:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=nGRQqKnjaOU:p-nKwSpJ8b0:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=nGRQqKnjaOU:p-nKwSpJ8b0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/nGRQqKnjaOU" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-18T15:58:21.301+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/03/blog-post.html</feedburner:origLink></item><item><title>А судьи кто?</title><link>http://feedproxy.google.com/~r/protesting/~3/6PBuc4-Bjw4/blog-post.html</link><category>собеседование специалистов</category><category>менеджмент</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 01 Mar 2010 08:22:22 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-8627834553780061540</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ogIJndxHDj-x5eG9kg5f4mGw4dA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ogIJndxHDj-x5eG9kg5f4mGw4dA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ogIJndxHDj-x5eG9kg5f4mGw4dA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ogIJndxHDj-x5eG9kg5f4mGw4dA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="right"&gt;Читать всем, кто связан с проведением собеседований, &lt;br /&gt;наматывать на ус всем, кто хочет улучшить этот процесс!&lt;/p&gt;&lt;br /&gt;Давно уже вынашивал мысль описания некоторых, по-моему весьма серьезных ошибок, при проведении интервью. &lt;br /&gt;&lt;br /&gt;Во многих компаниях собеседование на позицию Test or QA Manager мало чем отличается от интервью на позицию Software Tester (или QA Engineer). Причем, как мне показалось, люди назначенные проводить интервью,  не всегда умеют это делать. Кто в итоге страдает? Конечно же - компания. &lt;span class="fullpost"&gt;&lt;br /&gt;&lt;i&gt;-- Поручайте проведение собеседований правильным людям.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Часто от друзей слашу: "О, сегодня собеседуем крутого тестера, надо его покруче поспрашивать!" - А какой смысл-то? Завалить можно кого угодно, а потом сказать, что он не знал элементарных вещей. А в итоге компания не получит хорошего работника, и все потому что те кто собеседуют, в зависимости от уровня кандидата, варьируют сложность и количество вопросов. (Это как в школе, ты, учась в спецклассе, получаешь 4, решая задачи повышенной сложности, а твой кореш Вася из реального класса, получает 5, решив пару элементарных примеров).&lt;br /&gt;&lt;i&gt;-- На одну и ту же позицию требования к кандидатам должны быть одинаковыми. В случае если он с легкостью отвечает на все Ваши вопросы, не значит ли это, что кандидат overqualified? Но тут могут быть нюансы, которые сложно предположить...&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;А вот еще история из курилки наших девелоперов. (Коротко о проекте: веб приложение = Jboss, Spring, DB2...) Пришел к ним на интервью парень с очень толстым резюме. Читает наш собеседователь его и видит там слово WebSphere и думает: "О, крутой чувак - вебсферу знает". И давай его про эту саму сферу и спрашивать, в итоге заваливает и парня не берут к нам. Вывод, зачем было его  гонят по технологиям, не используемым в компании? - Да просто так, чтобы удовлетворить свое самолюбие. &lt;br /&gt;&lt;i&gt;-- Вопросы на собеседовании должны быть тесто связаны с тем, чем кандидату придется заниматься, в случае положительного исхода интервью. Конечно это не означает, что не должно быть и других вопросов - ДОЛЖНЫ, но вот при принятии решения нужно опираться на основные требуемые знания, а не второстепенные. &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Или еще ситуация, которая меня постоянно "улыбает". На позицию тестера интервью проводят 2 разработчика, причем не самых грамотных с точки зрения процессов и понимания принципов тестирования. Как результат: тестера - не берут, а берут "так себе" разработчика, который согласился тестировать. &lt;br /&gt;&lt;i&gt;-- Собеседование должны проводить специалисты, знающие все тонкости и нюансы присущие для соискомой позиции. &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Недавно столкнулся еще с одним интересным подходом. Короткий диалог:&lt;br /&gt;- Здравствуйте, мы представляем компанию YYY, хотим с вами побеседовать&lt;br /&gt;- Хорошо, давайте&lt;br /&gt;- А расскажите нам вот это. А расскажите нам вот то....&lt;br /&gt;... &lt;br /&gt;(далее следует куча вопросов с их стороны и ответов со стороны кандидата)&lt;br /&gt;...&lt;br /&gt;- Спасибо, что ответили на все вопросы - до свидания. &lt;br /&gt;Вроде все хорошо, но извините, кандидату не сказали ни на какую позицию его рассматривают, ни рассказали о проекте, не дали возможности что-то вообще узнать о компании (коллектив, атмосфера, распорядок и т.д.). Все это оставляет негативные чувства прежде всего о компании, а не о тех, кто проводил это интервью.&lt;br /&gt;&lt;i&gt;-- Интервью - это двухсторонний диалог, на котором не только представители компании делают свои выводы, но и кандидат тоже. Поэтому нельзя лишать его возможности подробнее узнать о месте работы.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Еще один неприятный момент уже после прохождения интервью это то, что в случае отказа, Вам просто об этом не сообщают. Мелочь конечно, но очень неприятно. Пообещали сообщить "в течении 3-ех рабочих дней", будьте любезны, иначе нечего болтать попусту. Опять же, такие проколы плохо сказываются на репутации компании.&lt;br /&gt;&lt;i&gt;-- не забывайте информировать кандидатов о результатах интервью. Мир тесен, и репутация компании очень важный фактор при выборе будущей работы. Может так случиться, что забытый Вами кандидат не посоветует, Вашу компанию именно из-за невнимательности с Вашей стороны.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ВЫВОД&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Немного подитожим описанное выше.&lt;br /&gt;&lt;br /&gt;Советы:&lt;br /&gt;- собеседование должны проводить люди стоящие на позиции либо выше либо аналогичной, той на которую ищут специалиста. &lt;br /&gt;- к интервью нужно готовиться не только кандидатам, но и тем, кто его проводит. т.к. одни и теже вопросы на разные позиции имеют разный вес (так к примеру QA менеджеру не обязательно разбираться в тонкостях языков программирования или обычному тестеру знать во всех тонкостях процедуру деплоймента приложения).&lt;br /&gt;- по результатам интервью пишите отчеты, тщательно отображая в них почему кандидат не подошел и какие его качества подходят.&lt;br /&gt;- не забывайте информировать кандидата в случае отказа. &lt;br /&gt;&lt;br /&gt;С моей точки зрения самый логичный вариант проведения интервью следующий:&lt;br /&gt;1. Знакомство (обе стороны представляются, озвучивается позиция на которую будет проводиться собеседование и отведенные на беседу временные рамки)&lt;br /&gt;2. Себеседователи задают интересующие вопросы. (когда они закончили и "не имеют больше что спросить", кандидату дается возможность узнать интересующую его информацию)&lt;br /&gt;3. Кандидат задает вопросы&lt;br /&gt;4. Кандидату сообщают о том в каком виде и когда будут доступны результаты собеседования. Если собеседование многоуровневое и возможно еще несколько раундов - имеет смысл сообщить об этом кандидату заранее&lt;br /&gt;5. При получении положительного результата, Вам назначается следующий этап интервью, либо делается окончательное предложение. (При получении отказа Вы плачете в подушку.)&lt;br /&gt;6. Вы либо принимаете предложение, либо вежливо отказываетесь.&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;br /&gt;P.S. В компании, где я когда-то работал очень серьезно относились к процессу подбора специалистов. Бывали случаи, когда мы говорили "НЕТ, не берем" кандидата с 10-15 годами опыта, из головного офиса, нас просили дать письменные объяснения, почему именно мы не берем человека с резюме весомее наших всех вместе взятых. И поверьте мне отмазки в стиле "он нам лично не понравился" не прокатывали. &lt;br /&gt;&lt;br /&gt;P.S.S. Иногда, проводящие интервью специалисты относятся к кандидатам как соперники, опираясь на следующие принципы: &lt;br /&gt;- брать кого-то умней себя опасно - в последствии можно не получить повышение. &lt;br /&gt;- брать кого-то на должность выше своей тоже не очень хочется, &lt;b&gt;вдруг&lt;/b&gt;, если никого не найдут -  &lt;b&gt;тебя назначат&lt;/b&gt;? &lt;br /&gt;БУДЬТЕ БДИТЕЛЬНЫ: Не допускайте таких людей к процессу проведения интервью.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-8627834553780061540?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=6PBuc4-Bjw4:bu64MUfvrfY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=6PBuc4-Bjw4:bu64MUfvrfY:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=6PBuc4-Bjw4:bu64MUfvrfY:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=6PBuc4-Bjw4:bu64MUfvrfY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/6PBuc4-Bjw4" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-01T17:22:22.839+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/02/blog-post.html</feedburner:origLink></item><item><title>Встречают по одежке, а провожают по уму</title><link>http://feedproxy.google.com/~r/protesting/~3/aJ1urLJiIKM/blog-post.html</link><category>интервью с тестировщиком</category><category>собеседование специалистов</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 25 Jan 2010 12:07:22 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-7458949461367836470</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/IK0ORYjq0WrXv0IWZlwPeaKMvTQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IK0ORYjq0WrXv0IWZlwPeaKMvTQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/IK0ORYjq0WrXv0IWZlwPeaKMvTQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IK0ORYjq0WrXv0IWZlwPeaKMvTQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Недавно за кофе подняли вопрос: "В чем ходить на интервью?". Многие хором сказали, что только в костюме,  что типа респектабельный вид и т.д. Соглашусь вид респектабельный, но как выглядит интервью, если вы пришли в костюме, а вас собеседуют "&lt;span style="font-style:italic;"&gt;чуваки&lt;/span&gt;" в байках и майках? Если Вы выглядите респектабельно, то они явная Ваша противоположность. &lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;Конечно тут многое зависит от компании и позиции, которую вам предлагают. Если это серьезная организация типа NASA и позиция заместитель генерального директора, то костюмчик подыскать все же придется, а если это IT компания из 30 человек и позиция младший помощник старшего администратора, то "на кой ляд Вам этот &lt;span style="font-style:italic;"&gt;пинжак&lt;/span&gt;"? Вы его оденете 1 раз, повесите в шкаф и забудете про него до следующего интервью (а когда оно еще будет-то?)&lt;br /&gt;&lt;br /&gt;Если так все просто, то в чем на интервью идти &lt;span style="font-weight:bold;"&gt;QA инженеру / руководителю группы / менеджеру&lt;/span&gt;? В костюме или просто нужно быть опрятно одетым? Как перед интервью определить в чем на него идти?&lt;br /&gt;&lt;br /&gt;Лично я придерживаюсь мнения, что на интервью надо идти одетым в том стиле, в котором ты будешь обычно ходить на работу. Чтобы работодатель видел тебя таким какой ты будешь в реальной жизни. Иначе это будет своеобразный развод как в рекламе стирального порошка - по ТВ отстирывает, а в жизни нет. Конечно же "встречают по одежке, а провожают по уму", поэтому нужно одеваться так, чтобы первое мнение на счет Вас не испортило дальнейшего интервью, и вы не получили в "&lt;span style="font-style:italic;"&gt;зачетку оценку 2 еще до начала экзамена&lt;/span&gt;"... (и кстати, на сайте ПроТестинг есть бесплатный сервис "&lt;a href="http://www.protesting.ru/service/interview.html"&gt;Виртуальное интервью&lt;/a&gt;", который может в какой-то мере подготовить Вас к теоретической части собеседования, так что милости просим).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Приметы:&lt;/span&gt;&lt;br /&gt;- если Ваш коллега по работе покупает новый костюм, значит либо его пригласили на свадьбу, либо он ищет работу.&lt;br /&gt;- если у Вас нет подходящего костюма, значит все Ваши друзья давно женаты, и Вы вполне были довольны работой и заработной платой последние несколько лет.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;- можете предложить свои...&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-7458949461367836470?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=aJ1urLJiIKM:wLbJShnqruI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=aJ1urLJiIKM:wLbJShnqruI:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=aJ1urLJiIKM:wLbJShnqruI:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=aJ1urLJiIKM:wLbJShnqruI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/aJ1urLJiIKM" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-25T21:07:22.293+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/01/blog-post.html</feedburner:origLink></item><item><title>Ошибки вместо отображения исходного кода страницы в Google Chrome</title><link>http://feedproxy.google.com/~r/protesting/~3/EVwVKCPM5IY/google-chrome.html</link><category>интересные баги</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 15 Feb 2010 11:42:51 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-8857307191527653847</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9BywK0dJPEiPEc9jLluD3-ROzkY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9BywK0dJPEiPEc9jLluD3-ROzkY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9BywK0dJPEiPEc9jLluD3-ROzkY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9BywK0dJPEiPEc9jLluD3-ROzkY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Случайно натолкнулся на багу в сравнительно молодом, но очень перспективном браузере Google Chrome.&lt;br /&gt;&lt;br /&gt;Не теряя времени перейду к делу!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Шаги для воспроизведения&lt;/b&gt;:&lt;br /&gt;1. Открываем страницу http://protesting-jft.appspot.com/&lt;br /&gt;2. Заполняем Number of Fields: 1&lt;br /&gt;3. Кликаем Next &lt;br /&gt;--&gt; Страница High Level Initialization открыта &lt;br /&gt;4. Просматриваем Исходных Код Страницы&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;И что мы имеем? А вот что:&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_w6oo72jT1HU/S0yVbzxpAtI/AAAAAAAAB-I/CCGb1B1Vks8/s1600-h/chrome.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 122px;" src="http://3.bp.blogspot.com/_w6oo72jT1HU/S0yVbzxpAtI/AAAAAAAAB-I/CCGb1B1Vks8/s320/chrome.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5425875956062028498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ничего странного не замечаете??? :)&lt;br /&gt;&lt;br /&gt;В FF, IE, Safari все работает и код страницы отображается верно... &lt;br /&gt;&lt;br /&gt;P.S. надеюсь, что данная бага будет пофикшена в скором будущем!&lt;br /&gt;&lt;br /&gt;Да прибудет с Вами Source Code.&lt;br /&gt;Алексей Булат&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-8857307191527653847?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=EVwVKCPM5IY:J9QtgK7RNzY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=EVwVKCPM5IY:J9QtgK7RNzY:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=EVwVKCPM5IY:J9QtgK7RNzY:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=EVwVKCPM5IY:J9QtgK7RNzY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/EVwVKCPM5IY" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-15T20:42:51.249+01:00</app:edited><media:thumbnail url="http://3.bp.blogspot.com/_w6oo72jT1HU/S0yVbzxpAtI/AAAAAAAAB-I/CCGb1B1Vks8/s72-c/chrome.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2010/01/google-chrome.html</feedburner:origLink></item><item><title>Интервью с тестировщиком: "Тестирование изменит подход к жизни раз и навсегда"</title><link>http://feedproxy.google.com/~r/protesting/~3/wjLalmaSfo0/blog-post.html</link><category>интервью с тестировщиком</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Wed, 02 Dec 2009 01:55:57 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-245366685795693154</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MJ8fxQhMc0sGY4mwExkFJOnwh_E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MJ8fxQhMc0sGY4mwExkFJOnwh_E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MJ8fxQhMc0sGY4mwExkFJOnwh_E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MJ8fxQhMc0sGY4mwExkFJOnwh_E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Добрый день, многоуважаемые читатели. &lt;br /&gt;&lt;br /&gt;Всегда приятно поговорить с красивой девушкой, тем более если она работает в тестировании и еще является &lt;span style="font-weight:bold;"&gt;заместителем председателя Белорусской национальной коллегии тестировщиков&lt;/span&gt; (&lt;a href="http://www.bystqb.org/"&gt;BySTQB&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Приветствуем в нашей студии Ирину Тетерук.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[АПЛОДИСМЕНТЫ]&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.protesting.ru/img/it1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 165px; height: 220px;" src="http://www.protesting.ru/img/it1.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ирина, добрый день, надеюсь ты добралась до студии без приключений и можешь ответить на некоторые вопросы? Итак начнем. :)&lt;br /&gt;&lt;br /&gt;Где ты сейчас работаешь и чем конкретно занимаешься?&lt;/span&gt;&lt;br /&gt;- Я работаю на позиции инженера по обеспечению качества в небольшой IT компании, которая разрабатывает банковский софт.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;В данный момент ты работаешь в маленькой IT компании, а как же твоя громкая позиция "заместителем председателя Белорусской национальной коллегии тестировщиков"?&lt;/span&gt;&lt;br /&gt;- В своё время скучая в компании, где я на тот моент работала, заинтересовалась вопросом сертификации для тестировщиков, т.к. программисты постоянно "хвастались" новыми "бумажками" + хотелось изучить тестирование на основе книжек, т.к. к тому моменту у меня был только опыт и знания, полученные на основе практики. Сдать на сертификт я смогла только в России, естественно стало интересно организовать у нас возможность прохождения сертификации + донести информацию до людей. Нужен ли сертификат вопрос спорный, но то, что подготовка к нему время полезное думаю никто спорить не будет. После того как состоялся первый экзамен в Минске - начали думать над официальным представлением ISTQB в Минске, я была среди тех, кто всё организовывал. Название позиции громкое и как часто бывает за названием ничего не стоит кроме человека, который хочет, чтобы у тестировщика был не только практический опыт, но и теоретические знания.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Были ли трудности при организации коллегии тестировщиков?&lt;/span&gt;&lt;br /&gt;- Трудностей особых не было, только на этапе рассмотрения нашей заявки выяснилось, что от одной немецкой компанией, конкурирующей с нашей, было сделано предложение белорусским компаниям организовать ISTQB представительство в РБ. Но всегда можно найти компромисс. Да и деятельность носит волонтерский характер.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Получается, что вы все работаете в BySTQB, ничего не получая за это?&lt;/span&gt;&lt;br /&gt;- кроме морального удовлетворения - нет :-) но это уже приятно.  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Каковы твои основные обязанности как председателя BySTQB?&lt;/span&gt;&lt;br /&gt;- зампред ;-) . А если серьезно, то мы работаем в команде, поэтому подменяем друг друга, распределение должностей было формальностью, чтобы зарегистрировать белорусский board. Я участвую в организации экзаменов, веду переписку с людьми, у которых есть вопросы, перевожу на русский язык Силабус (Syllabus), а сейчас ещё нужно разрабатывать программу деятельности на будущий год. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Как много человек участвует в Вашей работе?&lt;/span&gt;&lt;br /&gt;- нас 8 человек, энтузиазм то приходит, то уходит, но в целом всегда есть пару человек "на подъеме" волонтерского духа и "на спаде". Самое приятное, что нам пишут люди из других компаний и предлагают помощь, например, с переводом того же силабуса. В такие моменты понимаешь, что всё не зря.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Когда состоится следующий сертификаионный экзамен на BySTQB?&lt;/span&gt;&lt;br /&gt;- экзамен будет в эту субботу 5 декабря, по поводу следующих пока не ясно. Будем разговаривать с представителем немецкой стороны.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.bystqb.org/index.php?option=com_content&amp;view=article&amp;id=1&amp;Itemid=16"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 468px; height: 60px;" src="http://www.protesting.ru/info/Bystqb.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Пожелаем удачи всем, кто в эту субботу будет сдавать экзамен. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Возвращаясь к истокам, что же все-таки привело тебя в тестирование?&lt;/span&gt;&lt;br /&gt;- Думаю как и многие, в тестирование я попала по стечению обстоятельств, на 4-м курсе я решила найти работу - сразу был небольшой опыт работы техническим писателем, мне не понравилось, затем практика в банке, которая тоже не воодушевила, и наконец появилось 2 предложения - БА и QA. Бизнес-анализ интересовал больше, но совмещать с учебой не представлялось возможным т.к. офис и универ находились в разных частях города и на дорогу приходилось бы тратить более часа, что для меня было неприемлемым на тот момент - поэтому остановила свой выбор на QA.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;А если вспомнить прошлые проекты, что ты можешь выделить и почему?&lt;/span&gt;&lt;br /&gt;- Самым ярким был проект автоматизации проведения тендеров, работала очень хорошая команда, работала ради единой цели, работали сутками, я никогда не была более счастливой в работе, наизнос, но потом это оказалось никому не нужно, и сама сильно перегорела. Многому научилась. Другой проект - небольшой рекламный портал связанный с регистрацией доменов, да и то он запомнился потому что была классная команда тестировщиков и был лидер, за которым хотелось идти, и у которого хотелось учиться. Остальные проекты - серость. Всё чаще в последнее время думаю, что я переросла свою профессию.  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ты считаешь тестирование "командной игрой" и почему?&lt;/span&gt;&lt;br /&gt;- Я думаю, это личностные особенности, кому-то класснно работать одному и он может положится только на себя, хотя я такая же - но в любом случае приходится взаимодействовать с программистами и ПМ-ом и лучше, чтобы эти люди были авторитетны и с ними можно было развивать себя.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ира, с высоты опыта, который уже есть у тебя, что ты можешь посоветовать всем, кто только начинает работать в тестировании?&lt;/span&gt;&lt;br /&gt;- Посоветовать только могу искать людей, с которыми интересно и хочется работать. Тестирование изменит подход к жизни раз и навсегда! Вы будете всякий раз пытаться "подвесить" инфокиоск на вокзале или "подкорректировать" работу лифта, или проверить не выдаст ли банкомат лишнюю купюрку. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;С купюрками лучше не экспериментировать - ПРЕСЛЕДУЕТСЯ ЗАКОНОМ, а в остальном я с тобой согласен. Большое спасибо за время проведенное с нами, удачи тебе во всех начинаниях...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Напомню, что с нами была инженер по обеспчению качества, заместитель председателя Белорусской национальной коллегии тестировщиков Ирина Тетерук. &lt;br /&gt;До новых встреч.&lt;br /&gt;&lt;br /&gt;[АПЛОДИСМЕНТЫ]&lt;br /&gt;&lt;br /&gt;Алексей Булат,&lt;br /&gt;Ведущий рубрики "Интервью с тестировщиком".&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-245366685795693154?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=wjLalmaSfo0:XqSCnpvN31o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=wjLalmaSfo0:XqSCnpvN31o:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=wjLalmaSfo0:XqSCnpvN31o:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=wjLalmaSfo0:XqSCnpvN31o:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/wjLalmaSfo0" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-02T10:55:57.493+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2009/12/blog-post.html</feedburner:origLink></item><item><title>Интервью с тестировщиком: "В общем, я попал в яблочко"</title><link>http://feedproxy.google.com/~r/protesting/~3/PDpyKEfthnc/blog-post_25.html</link><category>интервью с тестировщиком</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Wed, 25 Nov 2009 09:18:46 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-1600893794301278930</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1k-nTwzuEH7Ims6igMuv48nGd74/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1k-nTwzuEH7Ims6igMuv48nGd74/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1k-nTwzuEH7Ims6igMuv48nGd74/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1k-nTwzuEH7Ims6igMuv48nGd74/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Надоело слушать интервью разных гуру, и тех представителей IT, чьи книги и блоги ты зачитываешь до дыр. Хочется увидеть тех, кого мы замечаем редко, и в основном в случаях когда наши проекты терпят неудачу, тех кого многие обвиняют во всех смертных и бессмертных грехах, а именно хочется поговорить с рядовым тестировщиком, который не ищет славы, которому просто нравится делать свою работу. Итак, приветствуем в нашей студии Алексея Лемешева, &lt;span style="font-style:italic;"&gt;считающего тестирование своей родной стихией&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;[АПЛОДИСМЕНТЫ]&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Привет, Алексей, как настроение?&lt;/span&gt;&lt;br /&gt;- Привет. В последнее время выше среднего&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Это не может не радовать, на это есть какие-то конкретные причины?&lt;/span&gt;&lt;br /&gt;- Ну хотя бы достаточно только того, что не случается ничего плохого и получается делать то, что запланировал. И к тому же новый год наступает - а наступление НГ всегда лучше, чем сам НГ.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Сказывается ли наступление НГ на твоей работе?&lt;/span&gt;&lt;br /&gt;- Ну, может быть, сказывается лишь в том, что очень  хочется сдать все текущие проекты к новому году, чтобы уже в следующем году можно было начать работать над новыми. Но, видимо, одного "хочется" мало)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;А возросла ли нагрузка к концу года?&lt;/span&gt;&lt;br /&gt;- Я бы не сказал. Все идет в таком же темпе, как и раньше. Заказчики, что удивительно, не давят&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Я слышал, что не так давно ты сдал на ISTQB сертификат, помогает ли это в твоей повседневной работе?&lt;/span&gt;&lt;br /&gt;- К сожалению сейчас не помогает совсем, т.к. кризис и обстоятельства заставили временно перепрофилироваться в проектные менеджеры. Но тестирование мне больше по душе, и я обязательно вернусь в родную стихию.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Мне кажется, что менеджер проекта тоже достаточно интересная позиция, почему же ты хочешь "вернуться"?&lt;/span&gt;&lt;br /&gt;- Это может показаться кому-то странным, но мне нравится находить ошибки, составлять тест планы, писать тест кейсы и т.д. В конце концов, очень хочется поприменять те знания, которые были получены в ходе подготовки к сертификату ISTQB, на практике. А вообще, чтобы понять нравится тебе что-либо или нет, достаточно просто попробовать. И тестирование мне однозначно нравится больше. Ведь это официально признанный способ указывать людям на их ошибки.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;А как ты пришел в тестирование? Что повлияло на твой выбор? С чего все началось?&lt;/span&gt;&lt;br /&gt;- Хм, в тестирование меня привел случай, может даже и банальный. Вернувшись из штатов и просидев несколько месяцев дома, я подумал, что неплохо было бы и работу найти. Но чем именно заняться я не знал - на тот момент меня интересовало одновременно всё и ничего. И волею случая моя знакомая предложила мне попробовать тестирование, т.к. такому зануде как я это непременно должно было понравиться. Немножко почитав основы, я ринулся в кузницу кадров - Белхард, прошел собеседование и приступил к работе. И тут случилось то, что я еще никогда не испытывал в жизни - я шёл на работу с радостью. Скорее даже не шёл, а бежал. После окончания рабочего дня я всегда думал о том, чем я займусь завтра. В общем, я попал в яблочко.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;На данный момент, ты считаешь себя опытным специалистом?&lt;/span&gt;&lt;br /&gt;- О, это каверзный вопрос, и я не смогу на него ответить, т.к. в данном случае все очень сильно относительно. Скорее всего опытность в данном случае определяется багажом знаний и умением эти знания применять на практике. Т.е. не факт, что человек с 5-летним опытом в тестировании, проработавший все эти 5 лет на одном проекте, будет опытнее, чем человек со стажем в 2 года и успевшим сменить уже 3 разносторонних проекта. При всей этой относительности, я себя считаю себя достаточно опытным специалистом, но для профессионального роста предела нет....&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Как ты думаешь, что необходимо для того, чтобы стать "Специалистом" с большой буквы?&lt;/span&gt;&lt;br /&gt;- Нужно поддерживать себя "в форме" - т.е. не забывать то, что уже умеешь и постоянно стремиться узнавать что-то новое. Ну и общечеловеческие качества, естественно, никто не отменял.  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Помимо работы, как по-твоему, можно повышать свой профессиональный уровень?&lt;/span&gt;&lt;br /&gt;- Всегда нужно оставлять хотя бы немного времени на самообразование, при условии что ты хочешь действительно чего-то достичь. И тут возможны разные варианты: чтение книг, общение на форумах, дискуссии, да и просто встречи с коллегами после работы за бокалом чая :)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;В последнее время стало модно проводить разного рода конференции, тренинги, воркшопы и т.д., что ты думаешь об этом? Принимал ли ты участие в подобных мероприятиях?&lt;/span&gt;&lt;br /&gt;- Честно признаться, я пока не был ни на одной конференции, хотя и пытался попасть на одну из SQA Days. В данный момент мое мнение о конференциях состоит из суждений моих друзей и коллег. Кто-то говорит, что это полезно, кто-то - что это просто вытягивание денег. Истина, как всегда, наверняка где-то посередине. Просто надо знать, что ты хочешь получить от этой конференции и ходить не на всё подряд, а лишь на те темы, которые действительно тебя интересуют. И еще: говорят, что общение и знакомство с людьми до и после конференции часто бывает куда полезней, чем сама конференция.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Кем ты видишь себя допустим через 10 лет?&lt;/span&gt;&lt;br /&gt;- Ну из наиболее вероятных вариантов: хочется видеть себя руководителем отдела тестирования в солидной компании, а так же опытным специалистом, консультирующим по различным вопросам моей сферы деятельности. А вообще, всё может повернуться как угодно. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;А через 20?&lt;/span&gt;&lt;br /&gt;- А через 20 я уже буду состоятельным человеком в счастливом браке, с огромным счетом банке и несколькими виллами... И что-нибудь в духе: "А может быть в притонах Сан-Франциско лиловый негр вам подавал манто...". Шучу.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;А через 30?&lt;br /&gt;...&lt;br /&gt;шучу, можно не отвечать...&lt;br /&gt;Ну а если честно, Алексей, ты связываешь свое будущее с IT?&lt;/span&gt;&lt;br /&gt;- Да связываю, но до какого-то определенного момента. Почему-то сложно представить себя 60тилетним QA менеджером. Но в ближайшие лет 10 лет я скорей всего продолжу работать в этой сфере - мне же это нравится.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Что да, то да - нужно заниматься тем, что нравится, иначе это только будет разрушать тебя изнутри и ничего кроме стресса не принесет... &lt;br /&gt;Скажи, что ты можешь посоветовать  тем, кто только начинает задумываться о выборе будущей профессии?&lt;/span&gt;&lt;br /&gt;Составить список того, что привлекает больше всего и затем пробовать этим заниматься. И ни в коем случае не бояться менять работу - надо найти то, что действительно нравится делать. Это может всё очень сильно изменить в вашей жизни.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Спасибо, Алексей за потраченное время, удачного тебе дня и побед в будущих сражениях.&lt;/span&gt;&lt;br /&gt;- Спасибо и тебе, Алексей за интересные вопросы. Только вот время было не потрачено, а проведено с пользой.&lt;br /&gt;&lt;br /&gt;[АПЛОДИСМЕНТЫ]&lt;br /&gt;&lt;br /&gt;С Вами был Алексей Булат,&lt;br /&gt;Ведущий рубрики "Интервью с тестировщиком".&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-1600893794301278930?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=PDpyKEfthnc:wDE9j_owr7k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=PDpyKEfthnc:wDE9j_owr7k:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=PDpyKEfthnc:wDE9j_owr7k:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=PDpyKEfthnc:wDE9j_owr7k:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/PDpyKEfthnc" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-25T18:18:46.602+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2009/11/blog-post_25.html</feedburner:origLink></item><item><title>ВОЛОСАТУЮ руку искать надо...</title><link>http://feedproxy.google.com/~r/protesting/~3/Wq0e4z7pE9E/blog-post_24.html</link><category>Обеспечение качества. Контроль качества. Тестирование</category><category>opensource</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Mon, 07 Dec 2009 04:03:10 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-8592323340611712915</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6x3lcwnxNrVc5eSyeav7ermhWH0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6x3lcwnxNrVc5eSyeav7ermhWH0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6x3lcwnxNrVc5eSyeav7ermhWH0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6x3lcwnxNrVc5eSyeav7ermhWH0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Месяц поиска проектов в интернете закончился. Можно отметить, что результаты есть как хорошие, так и не очень. А самое главное были сделаны выводы...&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Итак начнем:&lt;/b&gt; &lt;span class="fullpost"&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;За месяц был выполнен целый 1 заказ. (Протестили сайтик ~30 страниц, в IE6,7,8, FF, Opera, Chrome, Safari. Потратили времени ~5 человекочасов. Найдено ~40 багов разных severity. За все это получили честно заработанные 12 WMZ :) &lt;/li&gt;&lt;li&gt;Вели переговоры еще по 1-му достаточно интересному проекту написанному на C++ .Net. Неделю заказчик мурыжил нас, а в итоге после личной встречи ушел в молчанку, наверное осознав, что то что он хочет - это не тестирование, а дебаг. &lt;/li&gt;&lt;li&gt;Выслали запросы на проведение работа по ~10 проектам, в итоге - ни ответа ни привета.&lt;/li&gt; &lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Выводы:&lt;/b&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://alexeybulat.blogspot.com/2009/11/blog-post_24.html"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 265px; height: 320px;" src="http://4.bp.blogspot.com/_w6oo72jT1HU/SwvoBBDyfNI/AAAAAAAAB9Q/btvn_JVvQ68/s320/feelance.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5407670881750252754" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;В основном заказчики ищут "манки-кликеров" или тех, кто готов работать за хлеб и воду. &lt;/li&gt;&lt;li&gt;Обеспечение качества никого не интересует. Всем нужно лишь проверить работоспособность, а также отсутствие легкообнаруживаемых багов и уязвимостей в безопасности. &lt;/li&gt;&lt;li&gt;Высокооплачиваемые специалисты, ценящие свой труд и время будут мало востребованы. В итоге, чтобы выжить им придется снижать расценки и увеличивать объемы, снижая, тем самым, качество выполняемой работы.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;С уважением,&lt;br /&gt;Алексей Булат&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-8592323340611712915?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=Wq0e4z7pE9E:2JylSDLNBlQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=Wq0e4z7pE9E:2JylSDLNBlQ:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=Wq0e4z7pE9E:2JylSDLNBlQ:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=Wq0e4z7pE9E:2JylSDLNBlQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/Wq0e4z7pE9E" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-07T13:03:10.418+01:00</app:edited><media:thumbnail url="http://4.bp.blogspot.com/_w6oo72jT1HU/SwvoBBDyfNI/AAAAAAAAB9Q/btvn_JVvQ68/s72-c/feelance.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">11</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2009/11/blog-post_24.html</feedburner:origLink></item><item><title>Оглядываясь назад, под монотонный стук дождя...</title><link>http://feedproxy.google.com/~r/protesting/~3/vwS0GVg0JUk/blog-post.html</link><category>кризис</category><category>Обеспечение качества. Контроль качества. Тестирование</category><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Tue, 24 Nov 2009 06:08:25 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-2913656406941890216</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gDAd6hstveUgNzSP2PYWa7V08os/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gDAd6hstveUgNzSP2PYWa7V08os/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gDAd6hstveUgNzSP2PYWa7V08os/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gDAd6hstveUgNzSP2PYWa7V08os/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;index&gt;Недавно меня спросили: &lt;br /&gt;- Назови три проекта, которыми ты гордишься, и которые ты бы хотел выделить из всей кучи сданных тобой.&lt;br /&gt;&lt;br /&gt;Я и подумать не мог, что такой простой вопрос вызовет во мне такую бурю разнообразных эмоций. Вспомнил все от начала и до конца. Вспомнил все проекты начиная с первой работы и до сегодняшнего дня. Везде было по своему сложно, увлекательно и в тоже время круто. Первый опыт первые шишки, первые шаги как автоматизатора, первые баги, найденные скриптами, первые завалы сервера под обычной нагрузкой, первые &lt;a href="http://alexeybulat.blogspot.com/2008/10/memory-leak.html"&gt;OutOfMemory&lt;/a&gt; после 48-ми часового теста... Эх... все было круто. Но что именно выделить? Вот в чем вопрос...&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;Почему-то захотелось выделить "первые" значимые проекты в моей карьере. Все-таки "первое" вспомнить всегда приятнее чем то, что уже успело поднадоесть. Как говорил один мой знакомый IBM-овец:&lt;br /&gt;- Проект это поезд, едущий по рельсам. Я беру сложный проект, ставлю его на рельсы, и дальше он едет по накатанной... &lt;br /&gt;&lt;br /&gt;Я с ним согласен, но хочу сказать, что начало - это приключение, которое тебе предстоит пережить, далее идет работа, а в конце удовлетворение или упаси Боже - разочарование... И чтобы стать специалистом, просто необходимо пройти все эти стадии и испытать всю гамму чувств.&lt;br /&gt;&lt;br /&gt;Но все-таки самое главное это то, что есть что вспомнить. Так как никто кроме Вас не поймет, чем вам понравился тот или ной проект, что он Вам дал, и чем он Вам так дорог.&lt;br /&gt;&lt;br /&gt;Поэтому, ЦЕНИТЕ вашу работу и ЛЮБИТЕ то, что вы делает, и будет Вам счастье. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/index&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-2913656406941890216?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=vwS0GVg0JUk:zcDs_s2W5M8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=vwS0GVg0JUk:zcDs_s2W5M8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=vwS0GVg0JUk:zcDs_s2W5M8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=vwS0GVg0JUk:zcDs_s2W5M8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/vwS0GVg0JUk" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-24T15:08:25.266+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2009/11/blog-post.html</feedburner:origLink></item><item><title>"Не ходите дети в Африку гулять" или "неудачная попытка фриланса"</title><link>http://feedproxy.google.com/~r/protesting/~3/HsHvQD4pomQ/blog-post.html</link><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Fri, 13 Nov 2009 07:08:22 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-8515037427753009559</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ON4X4y4iK0aqHNVJLXfU4gZHSco/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ON4X4y4iK0aqHNVJLXfU4gZHSco/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ON4X4y4iK0aqHNVJLXfU4gZHSco/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ON4X4y4iK0aqHNVJLXfU4gZHSco/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;index&gt;&lt;p align="right"&gt;Есть такая профессия - людей кидать&lt;br /&gt;...&lt;br /&gt;&lt;b&gt;Дмитрий Олейников&lt;/b&gt; - дальше по тексту Заказчик&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Говорила мне мама: "Не верь никому кроме самого себя". Не послушал я её.&lt;br /&gt;А вот как все начиналось...&lt;br /&gt;&lt;br /&gt;Решил я немного подработать, в простонародье заняться фрилансом. Сами понимаете, копейка лишней быть не может. Нашел на просторах инета сайтик по фрилансингу, зарегистрировался и давай искать проекты. Как по заказу, именно в этот день выложили там объявление: "тест и проверка сайт" ...&lt;span class="fullpost"&gt;&lt;br /&gt;Ну и решил я попытать судьбу. Сделал свое предложение (тогда оно не показалось мне двусмысленным): &lt;br /&gt;&lt;blockquote&gt;oт 3 до 4 часов&lt;br /&gt;от $10 до $12&lt;br /&gt;Alexey Bulat [boltick] [23.10 2009 | 19:19]&lt;br /&gt;Оплата почасовая. Сделаем все быстро и качественно.&lt;/blockquote&gt;&lt;br /&gt;Я был весьма удивлен, что уже на следующий день именно его выбрали среди многих других. Далее я пол дня потратил на тестирование, достаточно медленного и перегруженного скриптами сайта. Нашел и идентифицировал 39 багов (северти от 2 до 5). Ну и как и было договорено, отправил заказчику отчет о проделанной работе. &lt;br /&gt;&lt;br /&gt;Весь следующий день от заказчика не было никакой реакции. Ближе к вечеру я ему написал: &lt;br /&gt;- Получили ли Вы мое письмо с отчетом по работе?&lt;br /&gt;Ответ последовал незамедлительно: &lt;br /&gt;- все отлично куда кидать деньги?&lt;br /&gt;Оставил я номер своего кошелька и жду... через минут 20 получаю на счет ровно 12 уе, а не 12 умножить на 4 часа работы, как рассчитывал. &lt;br /&gt;Пишу заказчику:&lt;br /&gt;&lt;blockquote&gt;boltick, 23.10.2009 17:25:34:&lt;br /&gt;Хм... я так понял мы немного не правильно поняли друг друга... &lt;br /&gt;&lt;br /&gt;на счет я получил только 12 уе, в то время как мое предложение на сайте было:&lt;br /&gt;Alexey Bulat [boltick] [23.10 2009 | 19:19]&lt;br /&gt;Оплата почасовая. Сделаем все быстро и качественно."&lt;br /&gt;и т.д.&lt;br /&gt;&lt;br /&gt;Оплата почасовая означает что 10-12 уе за час&lt;br /&gt;&lt;br /&gt;И сегодня я уточнил это еще раз:&lt;br /&gt; 23.10.2009, 16:33&lt;br /&gt;ну мы договаривались на 3-4 часа... но получилось 5 с хвостиком... :(&lt;br /&gt;по деньгам говорили 10 - 12 за час... давайте усредним 11 уе...&lt;br /&gt;------------------------&lt;/blockquote&gt;Ответ в принципе уже был мне очевиден, не буду приводить полную историю переписки, но в сокращенной форме она такова:&lt;br /&gt;&lt;blockquote&gt;Demon©, 23.10.2009 17:26:13:&lt;br /&gt;хмм за час&lt;br /&gt;Demon©, 23.10.2009 17:26:31:&lt;br /&gt;5 часов по 11 это 55 дол что ли?&lt;br /&gt;Demon©, 23.10.2009 17:28:44:&lt;br /&gt;зачем такие подставы кидать я же спросил какая сумма у меня было куча более дешевых предложений&lt;br /&gt;boltick, 23.10.2009 17:29:30:&lt;br /&gt;спасибо на счет подстав...&lt;br /&gt;но в данном случае подставлен я, т.к. выполнил работу и не получил того на что рассчитывал&lt;/blockquote&gt;&lt;br /&gt;И в конце концов последовало вот такое предложение:&lt;br /&gt;&lt;blockquote&gt;Demon©, 23.10.2009 17:32:47:&lt;br /&gt;я в ближайшее время вам подгоняю еще одну работу что бы компенсировать эту ситуацию&lt;/blockquote&gt;&lt;br /&gt;Скорее всего из-за эмоционального наплыва, для меня это прозвучало: "я кинул вас 1 раз хотите еще раз кину?"&lt;br /&gt;Именно поэтому я вежливо отказался от выполнения новой работы...&lt;br /&gt;&lt;br /&gt;Дальше заказчик повел себя достаточно некрасиво - закрыл на сайте проектную вакансию с пометкой &lt;i&gt;"&lt;b&gt;Вы получили отказ. Ваше предложение не подошло заказчику. Причина — не указана.&lt;/b&gt;"&lt;/i&gt; Странно, ведь именно к работе претензий не было - вопрос возник по оплате. Понятно, что заказчик рассчитывал на определенный бюджет и на определенный объем, но ведь сверхбюджетных денег заплачено не было, а объем работы явно превышал оплату. В этом контексте реакция "спасти свою репутацию любой ценой и подставить партнера" понятна, но не одобряема. (Взрослые дела так не делаются).&lt;br /&gt;Собственно, если работа сделана быстрее и качественнее, чем ожидалось, я не вижу проблем в частичной доплате - это один из вежливых способов урегулировать ситуацию, так как "двусмысленность" была пропущена обеими сторонами и скидывать с себя ответственность - неправильно. В конце концов на работу было потрачено время и силы. Если разобраться - можно было просто оставить хороший отзыв о работе, если не было возможностей доплаты.&lt;br /&gt;&lt;br /&gt;В заключении как мораль: &lt;blockquote&gt;&lt;b&gt;ЗАРАНЕЕ ЧЕТКО ОГОВАРИВАЙТЕ ВСЕ УСЛОВИЯ ОПЛАТЫ ВАШЕЙ РАБОТЫ&lt;/b&gt;.&lt;/blockquote&gt;Далее публикую все контакты человека, который меня вполне возможно "кинул", ну или повел себя не очень правильно в конце нашего общего дела:&lt;br /&gt;Имя - &lt;b&gt;Дмитрий Олейников&lt;/b&gt;&lt;br /&gt;ICQ - &lt;b&gt;96870096&lt;/b&gt;&lt;br /&gt;Email - &lt;b&gt;oleinikov@gmail.com&lt;/b&gt;&lt;br /&gt;Vkontakte - &lt;b&gt;http://vkontakte.ru/id565811&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Если вы знаете его или может быть думаете иметь с ним дело, то будьте осторожны, иначе вас может постичь моя участь...&lt;br /&gt;&lt;br /&gt;Всегда Ваш,&lt;br /&gt;Алексей Булат&lt;br /&gt;&lt;/span&gt;&lt;/index&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-8515037427753009559?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=HsHvQD4pomQ:0Gy_qRla88M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=HsHvQD4pomQ:0Gy_qRla88M:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=HsHvQD4pomQ:0Gy_qRla88M:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=HsHvQD4pomQ:0Gy_qRla88M:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/HsHvQD4pomQ" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-13T16:08:22.183+01:00</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">14</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2009/10/blog-post.html</feedburner:origLink></item><item><title>it4business.ru ушёл в DOWN</title><link>http://feedproxy.google.com/~r/protesting/~3/4K0BYckyWqI/it4businessru-down.html</link><author>noreply@blogger.com (Алексей Булат)</author><pubDate>Wed, 14 Oct 2009 05:44:40 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-2877410536371661916.post-4945857706099848547</guid><description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SlRFeEXtqXb4yEGf7CSXMOqDuVA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SlRFeEXtqXb4yEGf7CSXMOqDuVA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SlRFeEXtqXb4yEGf7CSXMOqDuVA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SlRFeEXtqXb4yEGf7CSXMOqDuVA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Голландское время 14:33. Умираю от желания почитать форум тестеровщиков. Выбираю адресок из закладок и... получаю вот что:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_w6oo72jT1HU/StXHo8uyTNI/AAAAAAAAB8Y/X4CO4oLjojo/s1600-h/it4.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 76px;" src="http://1.bp.blogspot.com/_w6oo72jT1HU/StXHo8uyTNI/AAAAAAAAB8Y/X4CO4oLjojo/s320/it4.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5392435635157093586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;"Верните форум на родину!!!" - закричал я от неожиданности... А в ответ тишина... Беспорядочно стал перебирать линки и играть с URL (ввожу чистый http://it4business.ru/), но опять ничего...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_w6oo72jT1HU/StXHdQK7d1I/AAAAAAAAB8Q/fjf0-utRQq0/s1600-h/it4-2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 76px;" src="http://4.bp.blogspot.com/_w6oo72jT1HU/StXHdQK7d1I/AAAAAAAAB8Q/fjf0-utRQq0/s320/it4-2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5392435434216978258" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Спасите, помогите, верните последний оплот качества на просторах интернета...&lt;br /&gt;Умираю но не сдаюсь...&lt;br /&gt;Верю в возрождение птицы Феникс-it4business.ru&lt;br /&gt;&lt;br /&gt;Всегда с Вами,&lt;br /&gt;Алексей Булат&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2877410536371661916-4945857706099848547?l=alexeybulat.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/protesting?a=4K0BYckyWqI:CYnahHr-qOE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=4K0BYckyWqI:CYnahHr-qOE:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?i=4K0BYckyWqI:CYnahHr-qOE:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/protesting?a=4K0BYckyWqI:CYnahHr-qOE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/protesting?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/protesting/~4/4K0BYckyWqI" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T14:44:40.533+02:00</app:edited><media:thumbnail url="http://1.bp.blogspot.com/_w6oo72jT1HU/StXHo8uyTNI/AAAAAAAAB8Y/X4CO4oLjojo/s72-c/it4.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://alexeybulat.blogspot.com/2009/10/it4businessru-down.html</feedburner:origLink></item><media:rating>nonadult</media:rating></channel></rss>

