<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-5296774367900969742</atom:id><lastBuildDate>Tue, 10 Sep 2024 17:43:40 +0000</lastBuildDate><category>баги</category><category>наблюдения</category><category>планирование</category><category>эффективность</category><category>Bolton</category><category>здравый смысл</category><category>оценки</category><category>переводы</category><category>тестирование</category><category>техники</category><category>how do i</category><category>tools</category><category>инструменты</category><category>linux</category><category>fun</category><category>process</category><category>Дорофеев</category><category>анализ</category><category>капитан О.</category><category>карьера</category><category>классификации</category><category>логи</category><category>начальство</category><category>обучение</category><category>развитие</category><category>списки</category><category>статистика</category><category>UX</category><category>agile</category><category>automation</category><category>common sense</category><category>communication</category><category>configuration</category><category>context</category><category>dependencies</category><category>dev</category><category>env</category><category>evidence</category><category>inode</category><category>iso</category><category>legacy</category><category>postmortem</category><category>quality</category><category>swap</category><category>teams</category><category>translation</category><category>апгрейд</category><category>аттестация</category><category>время</category><category>границы</category><category>документация</category><category>конференции</category><category>конфигурации</category><category>новичок</category><category>общение</category><category>оценка</category><category>принятие решений</category><category>процессы</category><category>скрипты</category><title>Not so critical</title><description>тестирование и окрестности&#xa;</description><link>http://notsocritical.blogspot.com/</link><managingEditor>noreply@blogger.com (Pavel )</managingEditor><generator>Blogger</generator><openSearch:totalResults>40</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-2738456735874632053</guid><pubDate>Tue, 12 Nov 2019 10:03:00 +0000</pubDate><atom:updated>2019-11-12T16:03:20.280+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Дорофеев</category><category domain="http://www.blogger.com/atom/ns#">анализ</category><category domain="http://www.blogger.com/atom/ns#">здравый смысл</category><category domain="http://www.blogger.com/atom/ns#">инструменты</category><category domain="http://www.blogger.com/atom/ns#">конференции</category><category domain="http://www.blogger.com/atom/ns#">принятие решений</category><title>Свой велосипед</title><description>&lt;br /&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;span lang=&quot;ru&quot;&gt;Был на
&lt;/span&gt;&lt;span lang=&quot;en-US&quot;&gt;Highload++&lt;/span&gt;&lt;span lang=&quot;ru&quot;&gt;, слушал доклады.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
В нескольких
докладах про изменение/развитие существующих систем заметил общий вполне понятный и разумный шаблон рассказа: встретили проблему -
осмотрелись вокруг - решили делать что-то своё - разработали свой
&quot;велосипед&quot;.&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;i&gt;* Здесь и далее буду
называть &quot;уникальные решения и разработки&quot; велосипедами. Не потому,
что в них есть что-то плохое (они, наоборот, как правило весьма достойны и
хороши), а во-первых для краткости; во-вторых чтобы различать в тексте
&quot;решения&quot;, которые ментальное усилие выбора из нескольких вариантов,
и &quot;решения&quot;, которые программные системы и разработки; в-третьих сами
докладчики их так называли.&lt;/i&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Доклады были совсем
не про механизм принятия решений, так что в них больше говорили про устройство
велосипедов, а не о том, почему решили их строить. Вот несколько мельком
озвученных причин (не дословно):&lt;/div&gt;
&lt;ul style=&quot;direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;&quot; type=&quot;disc&quot;&gt;
&lt;li style=&quot;margin-bottom: 0; margin-top: 0; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;calibri&amp;quot;; font-size: 11.0pt;&quot;&gt;Те, кто уже решил подобную
     задачу, не рассказывают подробности, так что приходится сочинять самим&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;margin-bottom: 0; margin-top: 0; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;calibri&amp;quot;; font-size: 11.0pt;&quot;&gt;Можно было выбрать из вот
     таких инструментов, один из них неплохо подходил, но мы решили сделать
     по-своему&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;margin-bottom: 0; margin-top: 0; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;calibri&amp;quot;; font-size: 11.0pt;&quot;&gt;Показалось, что людям будет
     трудно освоить новый инструмент, поэтому решили подпилить свои, всем уже
     знакомые&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Некоторые вообще
никаких причин не упоминали, а просто рассказывали про свой велосипед.&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Но мне стало
интересно, как/почему/в какой момент люди и компании решают, что лучшее
возможное решение для вот этой конкретной проблемы - свой велосипед.&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Как водится, причин
может быть несколько. Первые пришедшие в голову:&lt;/div&gt;
&lt;ul style=&quot;direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;&quot; type=&quot;disc&quot;&gt;
&lt;li style=&quot;margin-bottom: 0; margin-top: 0; vertical-align: middle;&quot;&gt;&lt;span lang=&quot;ru&quot; style=&quot;font-family: &amp;quot;calibri&amp;quot;; font-size: 11.0pt;&quot;&gt;Синдром &lt;/span&gt;&lt;span lang=&quot;en-US&quot; style=&quot;font-family: &amp;quot;calibri&amp;quot;; font-size: 11.0pt;&quot;&gt;not invented here&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;margin-bottom: 0; margin-top: 0; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;calibri&amp;quot;; font-size: 11.0pt;&quot;&gt;Люди недоразобрались с уже
     существующими велосипедами&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;margin-bottom: 0; margin-top: 0; vertical-align: middle;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;calibri&amp;quot;; font-size: 11.0pt;&quot;&gt;Люди действительно
     столкнулись со специфической проблемой требующей своего специфического
     велосипеда&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
На самом деле,
полагаю, чаще всего присутствуют все три причины в каких-то пропорциях.&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Прежде всего, без
сомнений, люди правда столкнулись со специфической проблемой, которую никогда
раньше не решали. Может, не решали в их отделе, или в их компании, а может и в
индустрии в целом. Как бы то ни было, на старте видно что надо что-то делать, но
совершенно непонятно что.&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Далее люди ищут
существующие инструменты, подходы, практики, идеи, решающие их проблемы. Это
довольно сложный процесс сам по себе. Нужно сформулировать проблему, посмотреть
на незнакомые инструменты, понять что они могут делать, а что нет. Понять,
могут ли они решать такого рода проблемы в принципе, и могут ли они решить
конкретную проблему в конкретных обстоятельствах. Короче, едва ли первая
страница в выдаче поиска даст готовый исчерпывающий ответ. &lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Нужно потратить
время и силы (вообще говоря - без гарантии успеха).&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;span lang=&quot;ru&quot;&gt;Есть
много этапов, где можно обессилеть и отказаться от дополнительных исследований.
Можно ничего не найти просто потому, что не получается правильно сформулировать
вопрос (а для новой проблемы это не так просто сделать). Можно даже наткнуться
на подходящий чужой велосипед, но не понять, что он может помочь в данной
ситуации. Если удалось найти что-то правдоподобно выглядящее, можно не суметь
приложить это к своей ситуации: новый инструмент ещё нужно освоить, понять его
устройство, идеологию и правильное использование. Можно вполне разобраться с
инструментом, но упереться в его объективные ограничения.&lt;/span&gt;&lt;span lang=&quot;en-US&quot;&gt; &lt;/span&gt;&lt;span lang=&quot;ru&quot;&gt;Наконец, можно, отказаться от существующих
велосипедов по каким-то нетехническим причинам.&lt;/span&gt;&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Плюс срочность
проблемы давит на людей, склоняя их использовать прежде всего знакомые
инструменты: если надо срочно, то трудно разбираться с новым и неизвестным,
особенно когда видны варианты, как допилить то, что уже имеется. В этом есть и
рациональное зерно: силы/средства так и так придётся потратить. И можно их
тратить на доработку чего-то знакомого, а можно на поиск и освоение чего-то
неизвестного (а потом всё равно доработку знакомого, чтоб новое и старое
работали вместе). Первое может быть объективно затратнее, но второе кажется
более рискованным и неопределённым.&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Есть старая шутка
про написание научных статей: &lt;span style=&quot;font-style: italic;&quot;&gt;вывод это то
место, где автор устал думать&lt;/span&gt;. Утрированно, но не лишено
правды.&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Полагаю, решение о
постройке своего велосипеда принимается отчасти похожим образом: мы решаем
строить своё, когда устали от исследований непонятного и чужого. Кто-то другой
(другой человек, другая компания) отказался бы от исследований ещё раньше;
кто-то разбирался бы дольше. Какой вариант правильнее в конкретной ситуации -
едва ли кто-то когда-то узнает.&lt;/div&gt;
&lt;div lang=&quot;ru&quot; style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Calibri; font-size: 11.0pt; margin: 0in;&quot;&gt;
Что можно понять - это на какой стадии исследований принималось решение. И, если нужно,
скорректировать этот момент в следующий раз. Скажем, если существующие
велосипеды вообще никто не искал, вероятно стоит всё же оглядеться, что уже
есть в индустрии. И наоборот, если долгое ковыряние в различных инструментах не
приносит полезного результата, то наверное уже пора отказаться от чужих золотых
молотков и перейти к созданию своей серебряной пули.&lt;/div&gt;
&lt;br /&gt;</description><link>http://notsocritical.blogspot.com/2019/11/own-bicycle.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-2166163781416400944</guid><pubDate>Sun, 23 Sep 2018 05:22:00 +0000</pubDate><atom:updated>2018-10-24T08:22:29.562+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">tools</category><title>XPath в картинках</title><description>XPath - язык запросов, позволяющий обращаться к элементам XML-документа.&lt;br /&gt;
XPath активно используется в мире автотестов веб (ибо веб-страница - частный случай XML-документа).&lt;br /&gt;
&lt;br /&gt;
В целом XPath штука несложная, если разобраться с двумя основными концепциями: осями и предикатами.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
XPath axes - оси XPath&lt;/h3&gt;
Оси - это направления поиска относительно текущего элемента. Они помогают разбить документ на несколько множеств и указать, в каком из этих множеств искать нужный элемент.&lt;br /&gt;
Не все из существующих осей широко применяются в контексте веб-автотестов (например&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;namespace::&lt;/span&gt;&amp;nbsp;не имеет особого смысла). Некоторые оси применяются постоянно, но не всегда это очевидно (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;self::&lt;/span&gt; или&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;descendant-or-self::&lt;/span&gt;).&lt;br /&gt;
&lt;br /&gt;
Список существующих осей:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR5sWWeSf0K7Gf2JvTcI71dRZmUXyOy_TvW4_0CRA8EVkMcp1QAEtdMHrnpbvmARt5C-FIOTeaYpdDJLIH-f5Dwwz9r1_0K_H3zx8yCR3Tu_ilyHeH7HC08VolJ0oHT6LAJaj1oKlzP0I/s1600/xpathAxes.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;769&quot; data-original-width=&quot;1367&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR5sWWeSf0K7Gf2JvTcI71dRZmUXyOy_TvW4_0CRA8EVkMcp1QAEtdMHrnpbvmARt5C-FIOTeaYpdDJLIH-f5Dwwz9r1_0K_H3zx8yCR3Tu_ilyHeH7HC08VolJ0oHT6LAJaj1oKlzP0I/s640/xpathAxes.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Чтобы разобраться со смыслом основных осей, рассмотрим выдуманную веб-страницу. Как всякий XML-документ, веб-страницу можно рассматривать как дерево, узлы которого пронумерованы сверху вниз и слева направо.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLPhMof3-zjbkO7XD-jfv7EZNzlrkMv3uE5U1pGHsinDnZOBL0IZo0YwZCrQ7en31ImOFttjSqv9ZnEiyXr3qQgqAxaZsYmjvlALMbfzJ42LexDF3KEBsC4Q3pG2I7ZMh7mEazYpD5bpQ/s1600/xpathTree.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;469&quot; data-original-width=&quot;633&quot; height=&quot;296&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLPhMof3-zjbkO7XD-jfv7EZNzlrkMv3uE5U1pGHsinDnZOBL0IZo0YwZCrQ7en31ImOFttjSqv9ZnEiyXr3qQgqAxaZsYmjvlALMbfzJ42LexDF3KEBsC4Q3pG2I7ZMh7mEazYpD5bpQ/s400/xpathTree.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Чтобы было легче видеть за этим деревом веб-документ, опишем эту же структуру стандартными HTML тегами:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi36VGsQDKmJ-La5vHe6rFXbtW35pJx4DH8BNlfWIL3ZFEm2-UKq7uUnq4Br6yHu6nY4-CjUEHLqtEVvVbZcPAyi5-WXrO_NAFe_xltWExffcF7ScHGsHAZujq6AYMMt8mz56e9iglvtTg/s1600/xpathTreeHtml.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;483&quot; data-original-width=&quot;1322&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi36VGsQDKmJ-La5vHe6rFXbtW35pJx4DH8BNlfWIL3ZFEm2-UKq7uUnq4Br6yHu6nY4-CjUEHLqtEVvVbZcPAyi5-WXrO_NAFe_xltWExffcF7ScHGsHAZujq6AYMMt8mz56e9iglvtTg/s640/xpathTreeHtml.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Числа рядом с именами тегов проставлены, чтоб было проще сопоставлять картинки. Эти числа - номера узлов дерева.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Чтобы было нагляднее, в качестве текущего элемента выберем узел №7 и рассмотрим, как мы можем добраться до остальных узлов дерева с помощью осей XPath.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Ось&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;self::&lt;/span&gt;&amp;nbsp;позволяет обратиться к текущему элементу, если это зачем-то нужно.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Краткая нотация этой оси - точка.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9VcLPYoop-V7fS1OPAmjf0OplkTi6q_9R0152SvMZRXbohnURksNR-503xPBnqSyhzXXzi3Pl-BT4KskhpreQdF5oXHIa_gRWnTJnVxE2AHJrKvNlI-4onZ1FT4ox_9dc6P_v7t1lUAk/s1600/xpathSelf.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;588&quot; data-original-width=&quot;1319&quot; height=&quot;284&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9VcLPYoop-V7fS1OPAmjf0OplkTi6q_9R0152SvMZRXbohnURksNR-503xPBnqSyhzXXzi3Pl-BT4KskhpreQdF5oXHIa_gRWnTJnVxE2AHJrKvNlI-4onZ1FT4ox_9dc6P_v7t1lUAk/s640/xpathSelf.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
У элемента есть предки и потомки.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Предки - элементы, расположенные на пути от корня дерева до текущего элемента. Множество предков лежит на оси &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ancestor::&lt;/span&gt;.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Потомки - элементы, расположенные в дереве ниже текущего элемента. Они лежат на оси &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;descendant::&lt;/span&gt;.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
В терминах HTML тегов предки - это теги, которые не были закрыты до того места, где был открыт тэг текущего элемента. А потомки - это элементы, расположенные между открывающим и закрывающим тегами текущего элемента.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBBwTKwkrAXP0Up2VnfmFdOt-j0opiRSTFB0_uTKDcHmkfrq3MHuUD88Adj1CtvzLK8NdlK27qxj8TokHHEyjktyM-GjVuJzQN3TKt3o5PumMbTKKMt2vrRlWEF3ihVKUWVAU6ylJ9x30/s1600/xpathAncDesc.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;476&quot; data-original-width=&quot;1318&quot; height=&quot;230&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBBwTKwkrAXP0Up2VnfmFdOt-j0opiRSTFB0_uTKDcHmkfrq3MHuUD88Adj1CtvzLK8NdlK27qxj8TokHHEyjktyM-GjVuJzQN3TKt3o5PumMbTKKMt2vrRlWEF3ihVKUWVAU6ylJ9x30/s640/xpathAncDesc.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
На картинке ниже показано, какие элементы будут найдены с помощью того или иного XPath. Легко заметить, что к одному и тому же элементы можно обратиться с помощью различных путей.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuPdnYhbfifOA7kU9V9cfpk34V-wl7xiuo1ludXKU4Dcg_OeyCqYB4ZtbbIdUNQn5BBobhrxyLTIm36a1FRP-uAh5C5tjvmrxUmn4GybiVi_4ckvVY-fQ1xkC2IBfa52gMAFJhLTzVGCE/s1600/xpathAncDescPath.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;619&quot; data-original-width=&quot;1316&quot; height=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuPdnYhbfifOA7kU9V9cfpk34V-wl7xiuo1ludXKU4Dcg_OeyCqYB4ZtbbIdUNQn5BBobhrxyLTIm36a1FRP-uAh5C5tjvmrxUmn4GybiVi_4ckvVY-fQ1xkC2IBfa52gMAFJhLTzVGCE/s640/xpathAncDescPath.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Кстати, все приведённые пути начинаются точки, то есть с оси &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;self::&lt;/span&gt;, чтобы задать текущий элемент в качестве точки отсчёта. Без этой точки поиск начнётся от корня дерева.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Также стоит отметить правило нумерации: элементы оси всегда нумеруются относительно текущего элемента: ближайший элемент имеет номер 1, следующий 2 и так далее. Можно искать среди всех элементов лежащих на оси или указать имя тега, чтобы сузить пространство поиска. Соответствующим образом меняется нумерация: так, &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;td11&lt;/span&gt; - четвёртый среди всех потомков, но третий элемент &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;td&lt;/span&gt; среди потомков. Поэтому запросы &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;./descendant::*[4]&lt;/span&gt; и &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;./descendant::td[3]&lt;/span&gt; в данном случае эквивалентны.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Следующие две оси - &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;parent::&lt;/span&gt; и &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;child::&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;, означающие, соответственно, родителя (он всегда ровно один, если речь не о корневом элементе) и детей текущего узла.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
У этих осей есть краткие нотации.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwrA5I8WSYzkY2_WmJ7AZT6y8J8pM_U0Y1VG5aUNJliNlKkl4Zsvh3Gg2BxjWrEVn1buLpTQZylAgwZC-mPrdE4G0_61XgvMSfZeuc1qnGOSEJrmCc_HaJkDd9MtLbIMVaWcKy8l75dQU/s1600/xpathParentChild.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;477&quot; data-original-width=&quot;1317&quot; height=&quot;230&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwrA5I8WSYzkY2_WmJ7AZT6y8J8pM_U0Y1VG5aUNJliNlKkl4Zsvh3Gg2BxjWrEVn1buLpTQZylAgwZC-mPrdE4G0_61XgvMSfZeuc1qnGOSEJrmCc_HaJkDd9MtLbIMVaWcKy8l75dQU/s640/xpathParentChild.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Примеры поиска элементов на этих осях:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE18reCtn1sI1fvfUUkFlS-Ir_rhf5HK-alyEapEHm4Wf6yy5Z0FWKWomggts_nEzkBc7RXFGBZTGtOvfwlj8OKY9yym140t59y5i1olPnXmr8c9h4yOQ-zc19GNrBJBcYVoOnqZu4dWo/s1600/xpathParentChildPath.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;556&quot; data-original-width=&quot;1316&quot; height=&quot;270&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE18reCtn1sI1fvfUUkFlS-Ir_rhf5HK-alyEapEHm4Wf6yy5Z0FWKWomggts_nEzkBc7RXFGBZTGtOvfwlj8OKY9yym140t59y5i1olPnXmr8c9h4yOQ-zc19GNrBJBcYVoOnqZu4dWo/s640/xpathParentChildPath.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Идём далее.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Предшествующие (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;preceding::&lt;/span&gt;) и последующие (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;following::&lt;/span&gt;) элементы.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
В терминах дерева предшествующие - это элементы, чьи порядковые номера меньше номера текущего элемента, за исключением предков. Последующие - элементы с номерами большими, чем у текущего за исключением потомков.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
В терминах HTML предшествующие - это элементы, теги которых были закрыты до открывающего тега текущего элемента. А последующие - те, чьи теги были открыты уже после закрытия тега текущего элемента.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9wk3QmF9voCXumMVAXYyMRVnbz08LXRG0UeeoF6wjndVh4Ees2UxIjgR0sNFothjAFwZIcyVGQ3C5KHbwLYIiKYkVl1Tf4ooONR4GqgpVY4Sh5kQ7rWoEJPyAuGjoUVha6AzZqX1sLYI/s1600/xpathPrecFoll.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;480&quot; data-original-width=&quot;1315&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9wk3QmF9voCXumMVAXYyMRVnbz08LXRG0UeeoF6wjndVh4Ees2UxIjgR0sNFothjAFwZIcyVGQ3C5KHbwLYIiKYkVl1Tf4ooONR4GqgpVY4Sh5kQ7rWoEJPyAuGjoUVha6AzZqX1sLYI/s640/xpathPrecFoll.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
На практике использование этих осей я встречал редко, но на всякий случай вновь примеры доступа к элементам лежащим на этих осях:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMiuvX3DK3jAV9-fq79QB6hFv9l4YMIdO1k5Yy5vYFsUu5zVUZE3f3Ks2wqZDoDZEA4V0PghXTCzNVxp3haaZmQPlhnRIIHAIlspHiBhA7r75BVzQiKPoogQzISsjUokmNLM3GWODGIBE/s1600/xpathPrecFollPath.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;482&quot; data-original-width=&quot;1310&quot; height=&quot;234&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMiuvX3DK3jAV9-fq79QB6hFv9l4YMIdO1k5Yy5vYFsUu5zVUZE3f3Ks2wqZDoDZEA4V0PghXTCzNVxp3haaZmQPlhnRIIHAIlspHiBhA7r75BVzQiKPoogQzISsjUokmNLM3GWODGIBE/s640/xpathPrecFollPath.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Ещё две интересные оси - &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;preceding-sibling::&lt;/span&gt; (предшествующие братья или старшие братья) и &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;following-sibling::&lt;/span&gt; (последующие или младшие братья).&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Как следует из названий, на этих осях расположены элементы, имеющие того же родителя, что и текущий элемент, и имеющие меньшие или большие порядковые номера.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtp4pvqu39-maxeGMleVKDG8pteTp7KP4H7ttgk2vv685QCUSFRRLGZMTEId32dlFlpB4uOgJP-RSM54F8q6VIjic8i2koNWpu6yVMLLLF5kr6XdVIIGDbzaSg4yWsnLOJQV5xxTR0ojI/s1600/xpathSibling.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;480&quot; data-original-width=&quot;1315&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtp4pvqu39-maxeGMleVKDG8pteTp7KP4H7ttgk2vv685QCUSFRRLGZMTEId32dlFlpB4uOgJP-RSM54F8q6VIjic8i2koNWpu6yVMLLLF5kr6XdVIIGDbzaSg4yWsnLOJQV5xxTR0ojI/s640/xpathSibling.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Примеры XPath для этих осей:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL6L2eoCkJuELOJ6Q9I3VF4kO8sccc5arB4OVfCqqLQ0yA-l1ZJIoD9bBL-70Am9Lb3NWE3zF_1zEw8BYOm8RvsDfLuQ5NeC93RqRy01EYmDWZH1Nf6wdEACjzzEBY180wRQh0zdhAflQ/s1600/xpathSiblingPath.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;507&quot; data-original-width=&quot;1313&quot; height=&quot;246&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL6L2eoCkJuELOJ6Q9I3VF4kO8sccc5arB4OVfCqqLQ0yA-l1ZJIoD9bBL-70Am9Lb3NWE3zF_1zEw8BYOm8RvsDfLuQ5NeC93RqRy01EYmDWZH1Nf6wdEACjzzEBY180wRQh0zdhAflQ/s640/xpathSiblingPath.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Кроме перечисленных, есть ещё несколько осей, которые на этих картинках не видны.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Ось атрибутов &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;attribute::&lt;/span&gt; (или &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;@&lt;/span&gt; в краткой нотации) позволяет обратиться к атрибутам элементов: например, атрибуту &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;href &lt;/span&gt;элемента а9.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKe91sWR6-wuEj4UfB3EBT19_2z338PSzQsR120z9XHGnnM7-vzCHSJlks9IZ1szIGBzICItFmBI2PN0pm1JI3kdSzpJ0XHUZpvfkyZ81gcTq5puDvFJMbOwHn0nPNRvx-vVGyoyitO_8/s1600/xpathAttr.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;570&quot; data-original-width=&quot;1321&quot; height=&quot;276&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKe91sWR6-wuEj4UfB3EBT19_2z338PSzQsR120z9XHGnnM7-vzCHSJlks9IZ1szIGBzICItFmBI2PN0pm1JI3kdSzpJ0XHUZpvfkyZ81gcTq5puDvFJMbOwHn0nPNRvx-vVGyoyitO_8/s640/xpathAttr.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;text()&lt;/span&gt; позволяет найти текстовые элементы документа (которые, в частности, есть между любыми двумя соседними тегами, даже если там нет явно написанного текста).&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;node()&lt;/span&gt;&amp;nbsp; - узловые элементы документа.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;*&lt;/span&gt; - узловые и текстовые элементы.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4YUcox5IJa_y5IDF0xjCRcRkVI_PkTrItQcwB7jbGxfhrxvDwLNlE_bjsdTsKw4PcIkgGRtaYhPMxphmtzrzGGxXz_zxzf8jMXPUVnfA396t0wsq-JM2MNvaB3okEixim9ArAKgJVxh8/s1600/xpathNodes.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;554&quot; data-original-width=&quot;1323&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4YUcox5IJa_y5IDF0xjCRcRkVI_PkTrItQcwB7jbGxfhrxvDwLNlE_bjsdTsKw4PcIkgGRtaYhPMxphmtzrzGGxXz_zxzf8jMXPUVnfA396t0wsq-JM2MNvaB3okEixim9ArAKgJVxh8/s640/xpathNodes.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Также есть оси &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;ancestor-or-self::&lt;/span&gt; и &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;descendant-or-self::&lt;/span&gt;, смысл которых ясен из названия, и которые редко используются в явном виде.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Зато часто используется запрос /&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;descendant-or-self::node()/&lt;/span&gt; более известный виде краткой нотации &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//&lt;/span&gt;.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
На этом про оси всё. Напоследок ещё раз список осей, с краткими нотациями:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTSXLnqGCYc0k83QBC6im13v6CvD0K41Kq8bvHCe2MncG36fdi2ohXKl-V0vkEfVRJ4d8E8W1EEJyMcmEHWlPeBSMtDaRRK2fHEK-wSjkoIrRA3iaNJLi-PSEczh3TvIfikn8W7rCzlH4/s1600/xpathAxes2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;780&quot; data-original-width=&quot;1381&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTSXLnqGCYc0k83QBC6im13v6CvD0K41Kq8bvHCe2MncG36fdi2ohXKl-V0vkEfVRJ4d8E8W1EEJyMcmEHWlPeBSMtDaRRK2fHEK-wSjkoIrRA3iaNJLi-PSEczh3TvIfikn8W7rCzlH4/s640/xpathAxes2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style=&quot;clear: both; text-align: left;&quot;&gt;
Предикаты XPath&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Предикаты XPath - это дополнительные условия, помогающий уточнить запрос.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
На самом деле в примерах выше постоянно использовался простейший предикат - указание позиции элемента.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicxaxY7ms01X0oZKwdVOm5EqKAPusx5jwwLLg772_qrYkvP6G04h6snACN_KmaD2FHWXVtniLbukNo_P7aldtpL_CQIkbzH5kTkqoWvwodxMB8YWddCe5r2MHv9E9L8fqt1FZZgb6rBUY/s1600/xpathPredicates.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;764&quot; data-original-width=&quot;1365&quot; height=&quot;358&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicxaxY7ms01X0oZKwdVOm5EqKAPusx5jwwLLg772_qrYkvP6G04h6snACN_KmaD2FHWXVtniLbukNo_P7aldtpL_CQIkbzH5kTkqoWvwodxMB8YWddCe5r2MHv9E9L8fqt1FZZgb6rBUY/s640/xpathPredicates.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Однако пользоваться только позицией было бы не очень удобно, особенно в мире динамических веб-страниц.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Предикаты позволяют указать значения атрибутов искомого элемента.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Пример ниже показывает, какое множество элементов находит тот или иной запрос в HTML коде справа.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVpu4EjvS7ocfLqcktiJ1-A5leehlHBsYDgGkvcizf3gr1VComt5-j1fZ3QetfHDOpHOY0sZq75tesTI571PBcfgtevIJ_OlTjtAL1C6bJq6UZlg-MWaLoqSkyDy2iNZqtYtezZOlpr2U/s1600/xpathPredicatesAttr.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;669&quot; data-original-width=&quot;1352&quot; height=&quot;316&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVpu4EjvS7ocfLqcktiJ1-A5leehlHBsYDgGkvcizf3gr1VComt5-j1fZ3QetfHDOpHOY0sZq75tesTI571PBcfgtevIJ_OlTjtAL1C6bJq6UZlg-MWaLoqSkyDy2iNZqtYtezZOlpr2U/s640/xpathPredicatesAttr.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Также популярны предикаты работающие&amp;nbsp; текстом внутри элемента: &quot;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;text()&lt;/span&gt;&quot; и &quot;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;.&lt;/span&gt;&quot;.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
На первый взгляд они выглядят похоже: оба запроса для &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;span&lt;/span&gt; на картинке ниже возвращают одно и то же.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Однако если посмотреть на запросы для кнопок - возникают вопросы:&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//button[text()=&quot;Click&quot;]&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;не находит ничего,&lt;span style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//button[.=&quot;Click&quot;]]&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;находит нужную кнопку, а&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//button[.=&quot;Press&quot;]]&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt; вновь ничего не находит.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Причина в том, что предикат &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;text()=&quot;something&quot;&lt;/span&gt; ищет элемент, у которого есть собственный текстовый узел с таким значением. А &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;.=&quot;something&quot;&lt;/span&gt; ищет элемент, текстовое представление которого совпадает с указанным значением. При этом текстовое представление элемента учитывает все текстовые узлы внутри элемента - как собственные, так и дочерних элементов. Иными словами, тестовое представление узла - это конкатенция всех текстовых узлов внутри элемента.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Поэтому&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//button[text()=&quot;Click&quot;]&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;не находит ничего - ведь &quot;Click&quot; содержится не в собственном текстовом узле кнопки,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//button[.=&quot;Click&quot;]]&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace; font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;находит нужную кнопку: текстовое представление кнопки именно &quot;Click&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//button[.=&quot;Press&quot;]]&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-size: 12pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;вновь ничего не находит, так помимо &quot;Press&quot; текстовое представление кнопки содержит ещё и два переноса строки.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikukQnvKFyWcKlRBpBAYSxFYDmtJRVTlY1ziHpErxJ3yGf-6h3CzjbEeLvwL8WpQHnsD6-fYPf7XMmP9I8til-Du6WuW7Gkg0pEnWwxP16qMHwbDaZUEIwJ7fsba006TM1W14Q-YqBXnA/s1600/xpathPredicatesTextDot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;760&quot; data-original-width=&quot;1361&quot; height=&quot;356&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikukQnvKFyWcKlRBpBAYSxFYDmtJRVTlY1ziHpErxJ3yGf-6h3CzjbEeLvwL8WpQHnsD6-fYPf7XMmP9I8til-Du6WuW7Gkg0pEnWwxP16qMHwbDaZUEIwJ7fsba006TM1W14Q-YqBXnA/s640/xpathPredicatesTextDot.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
Кроме того имеется набор функций, позволяющих сравнивать строки, считать элементы и т.д. Подробно останавливаться на этом не буду.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf60Yb0LStm_qlOGgiQqN2yVtHOANFbHDBocu5e7Yat2Ma-t82_6FDm3KdzsfrYiQjInCTZyw-Tga6qbcYj_n4ici7WF5lze71FGneD9O0O2acTEVsPgRxvuMPpHupFzJPSgEB3Nac5ps/s1600/xpathPredicatesFunctions.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;715&quot; data-original-width=&quot;1363&quot; height=&quot;334&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf60Yb0LStm_qlOGgiQqN2yVtHOANFbHDBocu5e7Yat2Ma-t82_6FDm3KdzsfrYiQjInCTZyw-Tga6qbcYj_n4ici7WF5lze71FGneD9O0O2acTEVsPgRxvuMPpHupFzJPSgEB3Nac5ps/s640/xpathPredicatesFunctions.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Хороший XPath&lt;/h3&gt;
&lt;div&gt;
Напоследок некоторые мысли, что отличает &quot;хороший&quot; XPath-запрос от &quot;плохого&quot; в контексте веб-тестирования.&lt;/div&gt;
&lt;div&gt;
Хороший XPath должен быть&lt;/div&gt;
&lt;div&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;li&gt;описательным и лаконичным - то есть по возможности коротким, но при этом хорошо, если читая XPath-запрос человек понимает, что этот запрос ищет (да, это немного противоречивые требования).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
Все эти критерии ситуативны и требуют применения здравого смысла.&lt;/div&gt;
&lt;div&gt;
Обычно не возникает проблем с точностью и скоростью поиска.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
С другими тремя пунктами сложнее.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Чтоб было понятнее, о чём речь, приведу примеры.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Не уникальный XPath:&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//span[contains(text(), &#39;already exists&#39;)]&lt;/span&gt; - сложно сказать сколько подобных элементов окажется на странице. Хотя, в контексте конкретного теста мы можем точно знать, что такой элемент ровно один.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Хрупкий XPath:&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;direction: ltr; language: ru; margin-bottom: 0pt; margin-top: 0pt; mso-line-break-override: restrictions; punctuation-wrap: simple; text-align: left; unicode-bidi: embed; vertical-align: baseline;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//span[text()=&#39;Open&#39;]&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;/../../button[contains(@id,
&#39;actions-button-%s&#39;)]&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//span[contains(text(),&#39;%s&#39;)]/..//div[@class=&#39;panel&#39;]&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;/div/span/div/span[3]//span[1]&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Лесенки вверх (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;../../&lt;/span&gt;),&amp;nbsp; длинные списки элементов (&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;/div/span/div/span[3]//span[1]&lt;/span&gt;) это те места, которые могут легко и неожиданно ломаться при изменении веб-страницы.&lt;br /&gt;
&lt;br /&gt;
Лесенки в большинстве случаев можно устранить, используя вместо них предикаты и вложенные запросы&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;//button[span[text()=&#39;Open&#39;]][contains(@id, &#39;actions-button-%s&#39;)]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Не лаконично-описательный XPath:&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;direction: ltr; language: ru; margin-bottom: 0pt; margin-top: 0pt; mso-line-break-override: restrictions; punctuation-wrap: simple; text-align: left; unicode-bidi: embed; vertical-align: baseline;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//span[@aria-label=&#39;%s.
Press the Enter key.&#39;]/../..&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//p[text()=&#39;%s&#39;]/../../../td[1]/input&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;//td[text()=&#39;%s&#39;]/following-sibling::td[count(//div[@id=&#39;usage_stat&#39;]//th[text()=&#39;Amount&#39;]/preceding-sibling::th)-1]&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
Чтобы понять, что ищут эти запросы, нужно в лучшем случае очень внимательно читать запрос (а в худшем - нет ни одного шанса понять, не проверив непосредственно на странице).&lt;/div&gt;
&lt;div&gt;
Кстати, эти не лаконично-описательные XPath&#39;ы одновременно ещё и хрупки. Есть ощущение, что часто эти свойства ходят парой: если сломано одно из них, до и другое скорее всего тоже.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Иногда полезно вообще попробовать использовать вместо XPath другой инструмент. Например, вместо построения сложного запроса ищущего что-то в таблице (&lt;code&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&amp;amp;lttable&amp;amp;gt&lt;/span&gt;&lt;/code&gt;), может оказаться проще вычитать всю таблицу в хэш-таблицу (aka мапу, словарь) и потом вычитывать нужные данные оттуда.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Ссылки&lt;/h3&gt;
Несколько полезных ссылок, помогающих разобраться с XPath:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://msdn.microsoft.com/ru-ru/library/ms256086(v=vs.120).aspx&quot; target=&quot;_blank&quot;&gt;https://msdn.microsoft.com/ru-ru/library/ms256086(v=vs.120).aspx &lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://scraping.pro/5-best-xpath-cheat-sheets-and-quick-references/&quot; target=&quot;_blank&quot;&gt;http://scraping.pro/5-best-xpath-cheat-sheets-and-quick-references/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://pragmatictestlabs.com/2016/09/27/mastering-xpath-for-selenium-test-automation/&quot; target=&quot;_blank&quot;&gt;http://pragmatictestlabs.com/2016/09/27/mastering-xpath-for-selenium-test-automation/&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://ru.wikipedia.org/wiki/XPath&quot; target=&quot;_blank&quot;&gt;https://ru.wikipedia.org/wiki/XPath&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
На этом всё.&lt;br /&gt;
Хороших XPath&#39;ов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://notsocritical.blogspot.com/2018/09/xpath.html</link><author>noreply@blogger.com (Pavel )</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR5sWWeSf0K7Gf2JvTcI71dRZmUXyOy_TvW4_0CRA8EVkMcp1QAEtdMHrnpbvmARt5C-FIOTeaYpdDJLIH-f5Dwwz9r1_0K_H3zx8yCR3Tu_ilyHeH7HC08VolJ0oHT6LAJaj1oKlzP0I/s72-c/xpathAxes.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-4084390120362230507</guid><pubDate>Fri, 22 Apr 2016 11:08:00 +0000</pubDate><atom:updated>2017-09-07T08:03:34.066+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">common sense</category><category domain="http://www.blogger.com/atom/ns#">communication</category><category domain="http://www.blogger.com/atom/ns#">process</category><category domain="http://www.blogger.com/atom/ns#">quality</category><category domain="http://www.blogger.com/atom/ns#">tools</category><title>Качественный субъективизм</title><description>Один из серьёзных нюансов с качеством ПО с точки зрения разработки: уровень этого самого качества в изрядной степени субъективен.&lt;br /&gt;
&lt;br /&gt;
При желании каждый участник процесса разработки легко найдёт оправдания и объяснит, почему налажал не он. Бизнес-аналитик честно подумал, но не смог учесть все нюансы многолетней архитектуры. Разработчик честно реализовал требования, а тестировщик честно их проверил. Оба - как поняли. Ну а что, если требования не полны - вопросы к аналитику. Он ещё и менял их постоянно, чего удивляться. Техлид недоучёл энтузиазм джуниора, а джуниор не в курсе, чем отзывается взмах крылом в этом конкретном компоненте системы.&lt;br /&gt;
&lt;br /&gt;
В общем, все молодцы, а на выходе какашка. Нормальный процесс переработки сырого продукта.&lt;br /&gt;
&lt;br /&gt;
И да, отмечу, фраза &quot;каждый легко найдёт оправдания и объяснит, почему налажал не он&quot; не должна вводить в заблуждение. Злобные мудаки встречаются всё же не очень часто (ну или я избалован работой в продуктовой компании). Никто не стремится саботировать. Просто каждый работает так, как видит возможным. Через голову не перепрыгнешь. Если есть из критериев качества только и прежде всего соответствие требованиям, то от них и будет каждый отталкиваться. В меру своего формализма, бодрости, семейных радостей и физического здоровья.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
Я как аналитик сделал всё возможное: проанализировал ожидания и возможности, проконсультировался с инженерами. Несколько раз скорректировал требования по мере проявления нюансов.&lt;br /&gt;
&lt;br /&gt;
Я как разработчик реализовал требования в архитектуре и коде насколько позволили уже существующие архитектура и код, а также время и личная смелость.&lt;br /&gt;
Я как тестировщик, проверил фичу, пришёл в ужас, зарепортил баги, бился за них, но треть багов умерли вонтфиксами. Часть потом переоткроется, как показывает опыт, но это потом. Ответственные лица решили, что баги не фатальные. С формальной точки зрения блокирующих проблем нет, тестирование - done.&lt;br /&gt;
&lt;br /&gt;
Я как... Ой, а всё, никого ж не осталось. Релиз.&lt;br /&gt;
&lt;br /&gt;
Я как руководитель RnD недоволен, что мне на совете директоров рассказывают про баги в продукте. Каждый из инженеров видел проблему, и никто её не починил (а то и не заметил).&lt;br /&gt;
В этой войне авторитетов &quot;рядовой тестировщик&quot; равно как и &quot;рядовой разработчик&quot; с формальной точки зрения не всегда может показать что продукт - ну не готов к использованию. Есть те, кто более равны и есть формальные требования.&lt;br /&gt;
&lt;br /&gt;
Поэтому важно привнести тот самый фактор субъективности в финальную оценку качества. Чтоб учитывался не только формальный критерий, но и общее впечатление от продукта. Тогда есть шанс перейти от &quot;тут довольно много багов, но сплошь мажорчики, можно релизить&quot; к &quot;да, каждый баг формально мажор, но вместе они делают работу с продуктом невозможной&quot;.&lt;br /&gt;
Конечно, подобная оценка - прежде всего повод к разговору. Может я как тестировщик сгущаю краски. А может я как менеджер не могу сдвинуть релиз, зато могу подстелить соломку другим способом. Обсудим и решим, лишь бы важная информация о качестве продукта не потерялась. А личное впечатление, мнение работающего у нас инженера - это важно.&lt;br /&gt;
&lt;br /&gt;
Полагаю, привносить эту субъективность можно по-разному, и разным командам/компаниям подойдут разные способы. Если тестировщик поставил фиче оценку 2 из 5, вероятно с фичей что-то не так. Возможны и другие способы, но &quot;техническая&quot; реализация не суть важна. Важно дополнить формальные показатели живым ощущением сотрудника - тогда чуть больше шансов узнать реальное состояние продукта.&lt;br /&gt;
&lt;br /&gt;
Всяко это лучше и полезней, чем пытаться понять, что таск-трекер может сказать о качестве продукта (QA квартирник Codefest&#39;а, привет). Таки таск-трекер для задач, а качество для людей. Давайте у людей и спрашивать о качестве.</description><link>http://notsocritical.blogspot.com/2016/04/quality-from-human.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-7301465279703612942</guid><pubDate>Thu, 10 Dec 2015 11:06:00 +0000</pubDate><atom:updated>2017-09-07T08:03:00.995+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">context</category><category domain="http://www.blogger.com/atom/ns#">how do i</category><category domain="http://www.blogger.com/atom/ns#">UX</category><title>SUT с человеческим именем</title><description>Допустим я тестирую продукт, который работает [в том числе] с &quot;человеческими данными&quot;.&lt;br /&gt;
&lt;br /&gt;
Где-то для чего-то указываются и хранятся имена, емейлы, логины, телефоны и тому подобное. Есть формы, где можно данные редактировать, потом эти данные где-то показываются и используются. Есть и прочие вещи, слабо связанные с этими данными, например, возможность давать пользователю разные права: тут не обойтись без объекта &quot;пользователь&quot;, но всякие атрибуты вроде имени/телефона обычно не важны. Другими словами, при тестировании можно указать любую белиберду, которую система согласна принять.&lt;br /&gt;
&lt;br /&gt;
Так я и делал. Тестируя формы - вводил произвольный текст, лишь бы пройтись по классам эквивалентности, потыкать во все границы. Тестируя прочие фичи - указывал минимальный допустимый набор символов, потому что неважно же какое там имя. И пользователь a12 взаимодействовал с ttt, и всё, в общем, у них получалось.&lt;br /&gt;
&lt;br /&gt;
Но с некоторых пор я стал чаще использовать данные похожие на настоящие имена, фамилии и адреса. Ибо не фиг. И это таки немножко помогает в тестировании.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
Например, вдруг оказалось, что в некоторых местах даже не очень длинные имена банально не влезают в отведённое пространство. Тут средней длины имя домена, тут фамилия пользователя, и вот емейл созданный по шаблону либо вылезает за границу поля, либо не виден полностью, либо появляется горизонтальная прокрутка на сайте, или ещё какое чудо случается. В первый раз очень удивляет: &quot;обычный!&quot;-то pb@pb1209.com нормально помещался, ничего не съезжало.&lt;br /&gt;
&lt;br /&gt;
С настоящими именами заметнее мелкие баги и расхождения, когда в разных местах продукта по-разному упорядочены имена-фамилии-инициалы и т.п.. Мелочь, но иногда сбивает с толку и заставляет человека думать лишнюю секунду-две.&lt;br /&gt;
&lt;br /&gt;
То же и при работе с названиями учреждений и компаний. Например, список ВУЗов города содержит много записей с одинаковым началом &quot;Китежгородский государственный …&quot; а до остального еще поди дотянись глазом. С выдуманными названиями можно и не обратить внимания, а с настоящими сразу приходит мысль, что хорошо бы указывать ещё и аббревиатуру на видном месте: тогда проще не спутать КГУ, КГИТ, КГМУ и т.п. То есть [почти] настоящие имена и названия помогают увидеть, обо что споткнётся пользователь - и вовремя улучшить эти коварные места.&lt;br /&gt;
&lt;br /&gt;
Что до классов эквивалентности, то отчасти и их можно тестить с помощью настоящих имён. Так, по интернетам ходят слухи, что самое длинное имя содержит более 1000 символов. Как, обработает такое имя наш продукт? Или - имя не может быть длиннее 128 символов (БД ведь не резиновая)? А как насчёт имён, состоящих из нескольких слов и включающих в себя пробелы? Понятно, что индустрия таких людей не балует, они уже не ждут многого от IT и давно научились указывать краткое имя. С другой стороны - толика уважения, возможность указать полное имя, - такие вещи подкупают людей.&lt;br /&gt;
&lt;br /&gt;
Так что теперь я использую имена и названия похожие на настоящие. Или - просто настоящие. Это привело к паре побочных эффектов. Первый из них: продукт тоже стал &quot;более настоящим&quot;. Используя фейковые и тестовые имена я не мог отделаться от ощущения, что я не коммерческий продукт работаю, а играю в kind of компьютерной игры. Найди проблемы в продукте и добейся чтоб починили. Ачивку нарисуешь себе сам. А вот поверить, что продукт кто-то где-то по-настоящему использует - толком не получалось. То есть я знал, я видел проблемы утекшие к клиентам, обсуждал случившиеся на продакшенах фейлы, но ощущения что &quot;всё по-настоящему&quot; не было. С нормальными именами это ощущение стало появляться. Потому что в списках, формах и т.д. - не ерунда какая-то, не &quot;абырвалг&quot;, а человеческие имена, адреса, телефоны, названия и прочая &quot;ГлавРыба&quot;. К ним уважения и сочувствия больше.&lt;br /&gt;
Второй сайдэффект - для некоторых любимых имён потихоньку вырисовываются роли и профили. Что этот конкретный Имя Фамилия знает, любит, не любит, что хочет от продукта и как к нему относится. Всякая такая вот ерунда. Понятно, что эта Америка давно открыта, и подобные персонажи уже классика UX. Просто тут это само собой появляется, всего лишь оттого, что используются нормальные имена, которые сами навевают ассоциации. И да, нет необходимости формально определять и расписывать персонажей. Иногда они живут всего лишь одну-две тестовых сессии. Но успевают помочь по-разному глянуть на продукт.&lt;br /&gt;
&lt;br /&gt;
Как по мне, вполне достаточная польза, чтоб использовать [почти] настоящие имена, названия и прочие атрибуты.&lt;br /&gt;
&lt;br /&gt;
Напоследок пара слов о том, где взять эти самые имена: не тратить же время на выдумывание прямо во время тестирования.&lt;br /&gt;
&lt;br /&gt;
Вариантов не так уж мало. Персонажи книг/фильмов. Имена актеров. Имена топ-менеджеров и директоров корпораций, они свободно доступны в инфопространстве. Тут минус в том, что с известными именами идёт куча лишнего контекста, он отвлекает и мешает при тестировании. Кроме того, могут случится неприятности, если скриншот с подобным именем просочится в документацию продукта или хотя бы в демо, так что ну его.&lt;br /&gt;
&lt;br /&gt;
Есть вариант взять список имён, список фамилий, а потом эти списки перемножить. Правда всё равно нужны исходные списки (а если придумывать самому - упускается разнообразие мира). Но интернет большой, данных в нём много, так что всё осуществимо. Списки участников конференций, списки сообществ и организаций, и всякое такое прочее. Наверняка существуют и уже заранее сгенерированные наборы или сервисы умеющие генерировать имена/названия на лету. Было бы только желание и понимание, зачем это всё нужно.</description><link>http://notsocritical.blogspot.com/2015/12/human-friendly-names.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-7622248042577443160</guid><pubDate>Fri, 13 Nov 2015 11:03:00 +0000</pubDate><atom:updated>2017-09-01T22:20:28.048+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dev</category><category domain="http://www.blogger.com/atom/ns#">evidence</category><category domain="http://www.blogger.com/atom/ns#">legacy</category><title>Уважение к старшим</title><description>С легаси кодом не просто.&lt;br /&gt;
&lt;br /&gt;
Это такой специальный код, который был написан в доисторические времена &lt;span style=&quot;color: grey;&quot;&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;br /&gt;
Он окончательно устарел и пришло-таки время всё исправить? ОК, не вопрос, давай исправлять. Но смотри внимательно: шрамы на старом коде - это следы древних багов. Будешь небрежен - и те же баги повторятся уже в новом коде.&lt;br /&gt;
&lt;br /&gt;
Это легаси. Уважай его.</description><link>http://notsocritical.blogspot.com/2015/11/do-respect-legacy.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-5935702724737469465</guid><pubDate>Thu, 29 Oct 2015 11:00:00 +0000</pubDate><atom:updated>2017-09-07T08:02:36.294+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">automation</category><category domain="http://www.blogger.com/atom/ns#">configuration</category><category domain="http://www.blogger.com/atom/ns#">env</category><category domain="http://www.blogger.com/atom/ns#">process</category><category domain="http://www.blogger.com/atom/ns#">tools</category><title>Сказка о неразобранных автотестах</title><description>Жил был проект, а в проекте делали продукт, а у продукта была веб-морда, и нужно было ту веб-морду тестировать, и были автотесты &lt;span style=&quot;color: #999999;&quot;&gt;(&quot;Selenium&quot; - подумал Штирлиц)&lt;/span&gt; для всех и всяческих сценариев. Автотесты регулярно запускали на свежих билдах, они &lt;span style=&quot;color: #999999;&quot;&gt;достаточно &lt;/span&gt;быстро выполнялись и радовали всех &quot;зелёными&quot; результатами. &quot;Красные&quot; результаты быстро исследовали, чинили проблему, и каждый следующий запуск был &quot;зеленее&quot; предыдущего. Скоро сказка сказывается, да не скоро дело делается.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #999999;&quot;&gt;У меня есть друг, у которого есть друг, знакомый которого рассказывал про человека…&lt;/span&gt; На одном из местных TechTalk&#39;ов зашла речь про автотесты, и выяснилось, что &quot;в реальном мире это не работает&quot;. Тут нужен дисклеймер. Сам я на том техтолке не был, это мне коллега рассказал, как люди болью делились. Мол, продукты хорошие, автотесты тоже в целом есть, и запустить их не проблема. Проблема - разобрать результаты работы автотестов. Что выполнилось, что упало, где баг, где косяк автотеста - вот это всё. Не хотят люди результаты разбирать - неинтересно им как-то, что ли… И что с такими неразобранными результатами делать? Как заставить, нет &quot;заставить&quot; слово нехорошее, как мотивировать человека разобрать-таки результаты автотестов?&lt;br /&gt;
&lt;br /&gt;
Сразу хочется задать кучу уточняющих вопросов, что же именно не работает и почему не работает и какой мир считается реальным и т.п., но не могу: не коллегу же спрашивать про чужие проблемы &lt;span style=&quot;color: #999999;&quot;&gt;(слышал я эти Битлз - мне друг по телефону напел)&lt;/span&gt;. Но понятно, что если на результаты автотестов не смотреть, то можно тогда автотесты и не использовать вообще. С точки зрения бездушной математики это то же самое.&lt;br /&gt;
&lt;br /&gt;
С другой стороны, если сесть и вспомнить, то - ну да, всё так. Разбирать автотесты - это не вдохновляет. Как возникает эта задача, так сразу хочется чем-то другим заняться. На такой случай всегда найдётся Важное Дело, Которое Надо Сделать. То есть проблема не совсем выдуманная, и как-то же её решают те, кто живёт в нереальном мире.&lt;br /&gt;
Итак, возможные решения, только здесь и сейчас, спешить узнать.&lt;br /&gt;
&lt;span style=&quot;color: #999999;&quot;&gt;Возможны противопоказания, проконсультируйтесь со своей командой.&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3&gt;
&lt;b&gt;От результата&lt;/b&gt;&lt;/h3&gt;
Нам ведь не нужны результаты автотестов. Нам нужно квалифицированное и обоснованное знание о состоянии продукта. Не хочешь возиться с автотестами, можешь не возиться. Главное - это самое знание предоставь. Как - дело десятое. Можешь &quot;руками&quot; всё пройти, можешь еще как-то. Лишь бы работало, было воспроизводимо и в разумные сроки. В общем, ты сам кузнец своей задачи.&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3&gt;
&lt;b&gt;От процесса&lt;/b&gt;&lt;/h3&gt;
Ты за автотесты, но ведь нудятина же невозможная? Да, всё так, согласен. Но уйти от рутины совсем - не получалось никогда и ни у кого. &lt;span style=&quot;color: #999999;&quot;&gt;Кроме Карлсона, но супергерои не в счёт.&lt;/span&gt; Рутина есть и будет, на каждом сколько-нибудь долгом проекте; это надо принять как неизбежность. Но можно варьировать количество рутины на каждую персональную душу населения.&lt;br /&gt;
Простой вариант: ротировать ответственность. Две недели я отвечаю за разбор автотестов, две недели ты, потом отдадим третьему. Всё честно, все страдают по очереди. Но отлынивать в свою очередь - нельзя, результат должен быть готов в срок.&lt;br /&gt;
&lt;br /&gt;
Другой вариант - поделить весь большой сет автотестов на куски. Самые приоритетные выделить в отдельный пул и сперва выполнять только их, а остальные - пореже и только если Top-Priority тесты &quot;зеленые&quot; &lt;span style=&quot;color: #999999;&quot;&gt;(вы слышали, он сказал &quot;build verification test&quot;, он правда это сказал)&lt;/span&gt;. Этих самых Top-Pri тестов не должно много получаться. Если какой-то из Top-Pri тестов, будучи &quot;красным&quot;, не блочит 10% общей массы тестов, то может он и не Top-Pri.&lt;br /&gt;
Вообще, вариантов подобного перераспределения рутины можно придумать немало - лишь бы помогали работе.&lt;br /&gt;
&lt;br /&gt;
Издержки: как за всяким процессом, кто-то должен за ним следить: что он работает, не провисает, не начинает мешать ходу проекта и так далее.&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3&gt;
&lt;b&gt;От инструмента&lt;/b&gt;&lt;/h3&gt;
А может, всё проще и достаточно допилить инструменты, чтоб они помогали разбору результатов АТ &lt;span style=&quot;color: #999999;&quot;&gt;(о, вот она, Важная Задача, которой я буду отмазываться в следующий раз)&lt;/span&gt;.&lt;br /&gt;
Как эти результаты выглядят? Легко ли отфильтровать из общей массы только &quot;красные&quot; тесты? Легко ли понять, что делал каждый &quot;красный&quot; тест и в каком месте свалился? Можно ли сгруппировать тесты, упавшие с похожими причинами? Можно ли указать для каждого теста соответствующий баг в трекере? Можно ли подтянуть для &quot;красного&quot; теста баг с прошлого запуска? Может ли разобраться в логике теста человек, не знакомый с внутренним устройством автотестов, - просто глядя на результаты выполнения?&lt;br /&gt;
&lt;br /&gt;
Неказистый инструмент может серьёзно затруднить работу. Хороший и удобный инструмент не избавит от работы, но поможет её делать быстрее и качественней.&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3&gt;
&lt;b&gt;От проблем&lt;/b&gt;&lt;/h3&gt;
Да нет, говоришь, это всё понятно, говоришь, но что толку, если половина падений тестов - это не баги продукта?&lt;br /&gt;
&lt;br /&gt;
Автотесты не совершенны и пишутся людьми, а потому содержат свои ошибки и падают там, где не надо &lt;span style=&quot;color: #999999;&quot;&gt;(и проходят где надо бы упасть, но не будем об этом)&lt;/span&gt;. А железо и тестовое окружение - вообще не совершенны и настраиваются людьми, глючат и приводят к ложным падениям автотестов. Мыть в этом песке золото - баги продукта - та еще работёнка.&lt;br /&gt;
&lt;br /&gt;
Ну что тут скажешь. Время исправлять грехи молодости: стабилизировать АТ, разбираться с настройками, учить роботов…&lt;br /&gt;
&lt;br /&gt;
Или - придумать как получать всё-таки пользу от таких АТ.&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3&gt;
&lt;b&gt;От себя&lt;/b&gt;&lt;/h3&gt;
Говоришь, ничего я не знаю про реальный мир, и советы мои к нему неприменимы? Подумай сам, как обойти грабли реального мира.&lt;br /&gt;
&lt;br /&gt;
Специфику продукта никто не отменял, но вдруг есть способ лучше, чем просто страдать - то от того, что разбираешь автотесты, то от того, что автотесты не разобраны.&lt;br /&gt;
&lt;br /&gt;
Сказка ложь, да.</description><link>http://notsocritical.blogspot.com/2015/10/tale-of-non-resolved-tests.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-9019169692251223495</guid><pubDate>Tue, 13 Oct 2015 10:57:00 +0000</pubDate><atom:updated>2017-09-01T22:14:54.131+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">fun</category><title>Разработка и Продажи</title><description>Продажи &lt;span style=&quot;color: grey;&quot;&gt;(падают из-за кулис на сцену и смирно лежат)&lt;/span&gt;.&lt;br /&gt;
Разработка &lt;span style=&quot;color: grey;&quot;&gt;(выходит, спотыкается об Продажи и падает)&lt;/span&gt;: Вот черт! Никак об Продажи!&lt;br /&gt;
Продажи&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Мерзопакость какая! Отдохнуть не дадут! &lt;span style=&quot;color: grey;&quot;&gt;(Идут, спотыкаются об Разработку и падают)&lt;/span&gt;. Никак об Разработку спотыкнулися!&lt;br /&gt;
Разработка &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Ни минуты покоя! &lt;span style=&quot;color: grey;&quot;&gt;(Идет, спотыкается об Продажи и падает)&lt;/span&gt;. Вот черт! Никак опять об Продажи!&lt;br /&gt;
Продажи&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Вечно во всем помеха! &lt;span style=&quot;color: grey;&quot;&gt;(Идут, спотыкаются об Разработку и падают)&lt;/span&gt;. Вот мерзопакость! Опять об Разработку!&lt;br /&gt;
Разработка &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Хулиганство! Сплошное хулиганство! &lt;span style=&quot;color: grey;&quot;&gt;(Идет, спотыкается об Продажи и падает)&lt;/span&gt;. Вот черт! Опять об Продажи!&lt;br /&gt;
Продажи&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Это издевательство сплошное! &lt;span style=&quot;color: grey;&quot;&gt;(Идут, спотыкаются об Разработку и падают)&lt;/span&gt;. Опять об Разработку!&lt;br /&gt;
Разработка &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Вот черт! Истинно что черт! &lt;span style=&quot;color: grey;&quot;&gt;(Идет, спотыкается об Продажи и падает)&lt;/span&gt;. Об Продажи!&lt;br /&gt;
Продажи&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Мерзопакость! &lt;span style=&quot;color: grey;&quot;&gt;(Идут, спотыкаются об Разработку и падают)&lt;/span&gt;. Об Разработку!&lt;br /&gt;
Разработка &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;:&amp;nbsp; Вот&amp;nbsp; черт! &lt;span style=&quot;color: grey;&quot;&gt;(Идет, спотыкается об Продажи и падает за кулисы)&lt;/span&gt;. Об Продажи!&lt;br /&gt;
Продажи&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: grey;&quot;&gt;(поднимаясь)&lt;/span&gt;: Мерзопакость! &lt;span style=&quot;color: grey;&quot;&gt;(Уходит за кулисы)&lt;/span&gt;.&lt;br /&gt;
За сценой слышен голос Продаж: &quot;Об Разработку!&quot;&lt;br /&gt;
Занавес&lt;br /&gt;
&lt;br /&gt;
P.S. Основано на &lt;a href=&quot;http://harms.ouc.ru/pushkin-i-gogol.html&quot;&gt;вымышленных событиях&lt;/a&gt;</description><link>http://notsocritical.blogspot.com/2015/10/rnd-and-sales.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-631572738713454650</guid><pubDate>Sat, 25 Oct 2014 09:50:00 +0000</pubDate><atom:updated>2017-09-07T08:01:26.292+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">agile</category><category domain="http://www.blogger.com/atom/ns#">dependencies</category><category domain="http://www.blogger.com/atom/ns#">teams</category><category domain="http://www.blogger.com/atom/ns#">tools</category><category domain="http://www.blogger.com/atom/ns#">translation</category><title>Связанные многочисленными ниточками</title><description>В больших компаниях и проектах, тем более распределенных, часто трудно согласовать работу между несколькими людьми и/или командами. Команда А ждет чего-то от команды Б, а та ожидает чего-то от А и от В, а В делает нечто важное, после чего нужно будет потрудиться еще нескольким командам. Это дополнительно усугубляется временными поясами, ролевыми разделениями, иерархией, личными отношениями им много чем еще.&lt;br /&gt;
&lt;br /&gt;
Ниже — перевод статьи &lt;a href=&quot;http://www.slideshare.net/sgreene/dependency-management-in-a-large-agile-environment-presentation&quot;&gt;«Dependency Management in a Large Agile Environment»&lt;/a&gt;, опубликованной компанией Salesforce.com. В статье рассказано, как компания решала проблемы взаимодействия команд разработки на крупном проекте. Многие подходы выглядят очень полезными.&lt;br /&gt;
&lt;br /&gt;
Стоит потратить пять минут на чтение.&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;strong&gt;Краткий обзор&lt;/strong&gt;&lt;br /&gt;
Департамент разработки Salesforce.com включает в себя более 30 Scrum-команд, совместно работающих над общим кодом в одной и той же ветке системы контроля версий. Статья описывает методы, используемые salesforce.com для масштабирования Scrum-подхода и для управления межкомандными взаимосвязями.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;1 Введение&lt;/strong&gt;&lt;br /&gt;
В октябре 2006 года начался грандиозный переход отдела разработки (R&amp;amp;D) salesforce.com от модели водопада к гибким методологиям, основанных на Scrum. На тот момент прошло 10 месяцев с предыдущего мажорного релиза, а дата выпуска нового переносилась уже пять раз. Многих расстраивало, что продукт выпускается редко и с серьёзными опозданиями. Мы не стали дожидаться завершения релиза, реорганизовали существующие команды в Scrum-команды и с помощью процессов Scrum выпустили релиз в феврале 2007 года. С тех пор, используя наш новый гибкий подход, мы выпустили уже пять мажорных релизов (длительностью в 3-4 месяца) нашего набора SaaS приложений и платформы Force.com. Каждый из них состоялся точно в запланированный день.&lt;br /&gt;
&lt;br /&gt;
Во время реорганизации мы следовали рекомендациям Scrum для отдельных команд, но не обращали особого внимания на взаимодействие между командами. Формируя команды, мы стремились минимизировать зависимости между ними, однако код не изменился в одночасье, так что сохранилось немало взаимосвязей. Довольно скоро мы внедрили Scrum-of-Scrum meetings. Эти встречи помогали обсуждать проблемы и состояние дел, но одних только собраний было недостаточно. Работая над последними пятью релизами, мы опробовали и отшлифовали дополнительные подходы, улучшающие взаимодействие команд. Далее в статье мы расскажем о некоторых трудностях с управлением зависимостями и о том, как мы преодолели эти проблемы.&lt;br /&gt;
&lt;br /&gt;
&lt;span id=&quot;more-168&quot;&gt;&lt;/span&gt;&lt;strong&gt;2 Структура команды&lt;/strong&gt;&lt;br /&gt;
Разработка продукта в salesforce.com состоит из трех подразделений: Applications, Platform и Core Infrastructure. Эти три подразделения суммарно содержат более 30 Scrum-команд. В каждой Scrum-команде есть разработчики, тестировщики и Product Owner, а также Scrum Master (обычно это руководитель разработчиков или тестировщиков либо Program Manager). Для сложных фич Scrum-команды также привлекают представителей других функциональных команд, например System Testing, Documentation, UI Design, Usability, Technology Operations, Release Engineering.
Обычно все Scrum-команды работают над одним и тем же релизом в одной и той же ветке кода. Наши продукты связаны между собой, поэтому фичи разных команд могут очень тесно переплетаться — как функционально, так и технически. С точки зрения технической реализации многие команды используют общий код. С точки зрения функциональности команды, работающие над фичами для одного и того же конечного пользователя, должны тесно сотрудничать, чтоб создать гармоничный и согласованный user experience.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;3 Почему управлять зависимостями трудно?&lt;/strong&gt;&lt;br /&gt;
Когда столько команд работают над одним релизом, внедряя общие фичи и меняя общий код, невозможно предвидеть все проблемы, неожиданности, изменения, провалы и успехи, которые встретятся в процессе разработки. Такая непредсказуемость — одна из причин, почему управлять зависимостями так трудно. Далее в этом разделе мы отметим еще несколько причин. Любые решения должны быть направлены на эти основополагающие конфликты и вызовы.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;3.1 Сложность системы&lt;/em&gt;&lt;br /&gt;
Выявление зависимостей — первый шаг к управлению ими. Подобно многим зрелым продуктам, системы salesforce.com слишком сложны, чтобы один человек или команда были способны знать и помнить все взаимосвязи. Чтобы выявить и осознать зависимости, нам все чаще приходится полагаться на коллективные знания множества людей. Крайне важно объединять такие знания и связывать людей, обладающих информацией, с людьми, нуждающимися в ней. Ключевую роль в определении зависимостей и последствий предлагаемых изменений играют эксперты с широким пониманием системы. Однако по мере роста и усложнения системы трудно избежать специализации и дробления знаний. К тому же при текущем количестве изменений нецелесообразно просить экспертов проверять детали каждой новой фичи. Нужен способ выявлять изменения, с высокой вероятностью влияющие на (или зависящие от) работу других команд, чтобы уделить таким изменениям особое внимание. Конечно, сделать это не так просто, поскольку порой сравнительно небольшие изменения серьёзно влияют на всю систему.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;3.2 Конфликт приоритетов&lt;/em&gt;&lt;br /&gt;
Зависимости могут приводить к конфликтам между командами. Если одна команда хочет, чтоб другая команда что-то сделала, то Product Owner’ы этих команд обсуждают и определяют приоритет этой работы. Если по итогам обсуждения удается договориться о сроках выполнения, то в дальнейшем управлять этой зависимостью довольно просто. Если внятное соглашение не достигнуто, или если приоритет работы все еще низок, то неопределённость и уровень рисков вокруг данной зависимости возрастают.
Также конфликты возникают, когда одна команда вносит изменение, добавляющее работу другой команде. Например, когда одна команда изменяет архитектуру, так что остальным надо приспособиться к этим изменениям. Изменение не всегда приносит очевидную пользу другим командам, так что иногда люди обижаются и возмущаются появлением дополнительной работы, особенно когда она появляется внезапно. Мы стараемся выявлять такие зависимости на ранних этапах, но некоторые из них неизбежно появляются позже — вследствие уже внесенных изменений либо после пересмотра приоритетов.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;3.3 Изменения в планах&lt;/em&gt;&lt;br /&gt;
Одно из преимуществ Scrum — возможность менять приоритеты команды для каждого спринта. Однако, это усложняет работу с зависимостями. Нельзя просто выявить и продумать все зависимости в самом начале релиз-цикла. Анализ взаимосвязей скорее похож на непрерывный постоянный процесс. По мере работы зависимости появляются и исчезают, пока команды уточняют детали того, что должно быть сделано. Поэтому процесс управления такими зависимостями должен быть динамичным и активным.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;3.4 Короткие и пересекающиеся релиз-циклы&lt;/em&gt;&lt;br /&gt;
В коротких релиз-циклах меньше времени на координацию между командами, поэтому взаимосвязи и их влияние нужно выявлять на ранних этапах. В salesforce.com релиз-циклы пересекаются, в том смысле, что планирование нового релиза начинается до завершения предыдущего. Это сделано намерено, поскольку некоторые команды уже освободились и могут начинать работу над новым релизом. Однако остальные команды могут запаздывать с планированием и пропускать обсуждение зависимостей для следующего релиза. Это серьёзная проблема, учитывая важность коллективного знания для прояснения взаимосвязей.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;4 Специальные подходы&lt;/strong&gt;&lt;br /&gt;
В этом разделе мы обсудим конкретные подходы, которые мы используем, чтобы управлять зависимостями и справляться с вышеперечисленными проблемами. Общие стратегии, используемые в этих подходах:
&lt;br /&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;em&gt;4.1 Старт релиза&lt;/em&gt;&lt;br /&gt;
Примерно за месяц до выпуска текущего мажорного релиза мы устраиваем стартовое собрание для следующего релиза. На собрании присутствуют все сотрудники компании. Вице-президенты бизнес-подразделений рассказывают в общих чертах, над какими фичами планирует работать каждая команда в новом релизе. Это собрание заметно помогает управлять взаимосвязями. Прежде всего, оно побуждает команды подготовить их начальные планы на релиз к намеченной дате. Если у какой-то команды остается незавершенная работа из текущего релиза, то эта команда начинает задерживать планирование следующего релиза; в этом случае собрание помогает выполнить планирование к сроку. Трудно выявлять зависимости и обсуждать обязательства с командой, которая понятия не имеет, что она будет делать. Стартовое собрание служит точкой синхронизации команд и помогает обеспечить продуктивное обсуждение межкомандных взаимосвязей.&lt;br /&gt;
&lt;br /&gt;
Кроме того, после собрания планы команды на релиз становятся общеизвестными. Мы стремимся добиться высокой осведомленности о том, чем занимаются все команды, поскольку верим, что это заставляет людей обдумывать и обсуждать взаимосвязи. В стартовом собрании участвуют все руководители R&amp;amp;D, что помогает привлечь людей и сосредоточить внимание на планировании релиза. Высокий уровень участия помогает согласовать ожидания и информировать правление о планах на релиз.&lt;br /&gt;
&lt;br /&gt;
Конечно, планы могу меняться и меняются в процессе работы. Не так давно мы начали проводить обзор обновленной презентации стартового собрания во время ежемесячных обзоров спринтов. Обновленная презентация показывает, какие фичи были исключены или добавлены, и очень помогает поддерживать ясность и публичность планов в течение релиза.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;4.2 Сессия выявления взаимосвязей&lt;/em&gt;&lt;br /&gt;
Приготовив начальные планы на релиз, команды могут более предметно обсуждать взаимосвязи, и множество таких обсуждений возникает спонтанно. В дополнение к этому мы сочли весьма ценным проведение более формальной сессии выявления взаимосвязей, когда совместно работают представители всех команд. Полезней всего проводить такую сессию незадолго до стартового собрания релиза, чтобы повысить качество планов, анонсируемых на этом собрании.&lt;br /&gt;
&lt;br /&gt;
Сессия выявления взаимосвязей устроена довольно просто. Представители (чаще всего Scrum Master или Product Owner) всех Scrum-команд собираются в комнате с большой доской. В первой части сессии все участники одновременно рисуют на доске две диаграммы зависимостей между командами. Одна диаграмма изображает команды, которым нужно, чтоб другая команда сделала что-то для них. Вторая диаграмма изображает команды, делающие нечто, что повлияет на работу других команд. Мы используем несколько простых правил для этих диаграмм:
&lt;br /&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;br /&gt;
За очень короткое время мы создаем полную картину взаимосвязей в релизе. На рис. 1 показан типичный результат сессии после приведения в более читабельный вид. Сразу выявляются горячие точки (то есть команды с большим количеством зависимостей). Также видны команды, имеющие несогласованные зависимости. Такие команды больше всех рискуют не достичь своих планов, пока их взаимосвязи не согласованы.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBwGFwnSHUEWpNBxQZvQBU36yYnpq0lb956NoZbY5J_fJYOj_Hg_Ehxcq4v3e2McieAMb0zCaO0TaR3XaZHGjrVh1QCmYxIXDcExdGB1YjPOsm0F9o72Lmic8tnkMMvgWbuRhFup8u1GE/s1600/CrossTeamDepends.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;831&quot; data-original-width=&quot;1173&quot; height=&quot;283&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBwGFwnSHUEWpNBxQZvQBU36yYnpq0lb956NoZbY5J_fJYOj_Hg_Ehxcq4v3e2McieAMb0zCaO0TaR3XaZHGjrVh1QCmYxIXDcExdGB1YjPOsm0F9o72Lmic8tnkMMvgWbuRhFup8u1GE/s400/CrossTeamDepends.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;i&gt;Рис.1. Пример диаграммы межкомандных зависимостей&amp;nbsp;&lt;/i&gt;&lt;/div&gt;
&lt;em&gt;&lt;br /&gt;&lt;/em&gt;
&lt;em&gt;4.3 Открытые обсуждения&lt;/em&gt;&lt;br /&gt;
С недавних пор в течение недели после стартового собрания мы проводим открытые встречи, главная цель которых — создать площадку для обсуждения вопросов и проблем, связанных с планами команды на релиз. Мы просим, чтоб на этих встречах был хотя бы один представитель от каждой Scrum-команды, в остальном они необязательны для посещения. Обычно в начале открытой встречи участники предлагают темы для обсуждения. Далее в течение 45 минут проходят обсуждения тем в группах, а затем группы рассказывают остальным о результатах обсуждения. Чаще всего участники хотят узнать детали новой и полезной функциональности, а также об изменениях, которых повлияют на другие команды. Участники открытых встреч отметили поучительность таких обсуждений, кроме того людям оказалось интересно общаться с коллегами из других команд, с которыми они не взаимодействуют в обычной работе. Открытые встречи пока что новый формат для нас, так что мы пробуем разные варианты, чтоб понять, что работает лучше, например:
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Предлагать идеи тем до начала встречи;&lt;/li&gt;
&lt;li&gt;Привлекать к участию высокое начальство;&lt;/li&gt;
&lt;li&gt;Менять количество и длительность дискуссий.&lt;/li&gt;
&lt;/ul&gt;
&lt;em&gt;4.4 Обзор дизайна&lt;/em&gt;&lt;br /&gt;
Основная цель собраний по обзору дизайна функциональности — повысить общий уровень качества и удобства наших продуктов, с помощью:
&lt;br /&gt;
&lt;ul&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;br /&gt;
Существует два основных типа таких собраний. На ранних этапах релиз-цикла участники фокусируются на концепциях дизайна и стремятся достичь согласованности и эффективного взаимодействия между существующими и новыми фичами. На этой стадии в собраниях обычно участвуют Product Owner’ы и дизайнеры пользовательского интерфейса (UI), и изредка представители других функциональных команд, таких как разработка и QA.
Примерно в середине релиз-цикла состав участников меняется: теперь это в основном представители QA и отчасти разработки, а обсуждения сосредоточены на деталях реализации. Эти встречи обеспечивают понимание и ясность относительно:
&lt;br /&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;em&gt;4.5 Виртуальная команда архитектуры&lt;/em&gt;&lt;br /&gt;
Виртуальная команда архитектуры (Virtual Architecture Team, VAT) — «виртуальна», поскольку включает в себя разработчиков из всех Scrum-команд. Члены команды работают в VAT без отрыва от основных обязанностей в рамках Scrum-команды из бизнес-подразделений Applications, Platform или Core Infrastructure.&lt;br /&gt;
&lt;br /&gt;
VAT отвечает за поддержку и развитие архитектуры нашего ПО. Команда определяет дорожную карту (road map) развития архитектуры, проводит обзор серьезных изменений с точки зрения архитектуры, определяет стандарты кодирования, чтобы обеспечить совместимость и поддерживаемость кода.&lt;br /&gt;
&lt;br /&gt;
VAT управляет бэклогом важных архитектурных проектов и необходимого рефакторинга. По мере развития продукта нам приходится перепроектировать фичи и избавляться от старого неоптимального кода. Порой разработчики не хотят менять уже работающие программы, даже когда они понимают, что код программы оставляет желать лучшего. Product Owner’ы предпочитают видеть, как разрабатываются новые фичи, а не как переделывается нечто уже работающее. Чтобы противостоять таким настроениям, каждое наше бизнес-подразделение обязано запланировать не меньше 20% времени в каждом релизе на изменения рекомендованные VAT.&lt;br /&gt;
&lt;br /&gt;
VAT собирается дважды в неделю на два часа для обзора технической реализации продуктов и фич, создаваемых Scrum-командами. Команды, работающие над наиболее сложными фичами релиза обязаны представить их VAT. VAT дает Scrum-команде обратную связь о том, как их технические решения затронут остальные команды, и какие разработки других команд могут повлиять на фичу. VAT сосредоточена прежде всего на технической реализации, особенно на аспектах масштабируемости и производительности. Если дизайн фичи требует серьезных изменений, то Scrum-команда обязана повторно представить фичу в том же релиз-цикле и показать VAT, как они изменили свой дизайн.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;4.6 Непрерывная интеграция&lt;/em&gt;&lt;br /&gt;
Наша веб-инфраструктура автоматизированной сборки, тестирования и сортировки (triage) обеспечивает непрерывную интеграцию билд-системы и позволяет отслеживать состояние каждой строчки кода. Эта инфраструктура — ключевой аспект, позволяющий всем разработчикам и QA инженерам работать с общей базой кода.&lt;br /&gt;
&lt;br /&gt;
Главный набор тестов построенный на расширении JUnit дает возможность создавать функциональные тесты с помощью API Force.com. Кроме того, у нас есть фреймворк для тестирования пользовательского интерфейса, использующий Selenium для автоматизации тест кейсов, которые нужно выполнять через UI.&lt;br /&gt;
&lt;br /&gt;
Вот несколько фундаментальных принципов, определяющих наш подход к автоматизации:
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;Давать разработчикам быструю обратную связь&lt;/b&gt;, чтобы они видели результаты своих изменений. Каждый коммит запускает сборку билда и выполнение набора тестов. В случае ошибки ответственные инженеры сразу же получают сообщение о сбое. Базовый набор тестов выполняется за полчаса, и разработчик получает результаты проверки внесенных им изменений. Периодически в течение дня выполняется расширенный набор тестов;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Быстро чинить сборку и сбои тестов&lt;/b&gt;. Для этого у нас есть роль «мастера сборки», меняющая владельцев каждую неделю. Обычно эту роль выполняют два тесно взаимодействующих человека — менеджер разработки и старший разработчик. Мастер сборки отвечает за проверку результатов сборки, отслеживание тестовой истории и сбоев на различных строчках кода, а также назначение багов конкретным разработчикам для починки. У нас есть специальная панель, отображающая различные метрики исходя из собранных в базе данных результатов тестов (доля успешных тестов, время сборки, количество сбоев и т.д.). Мастер сборки использует эти данные при подготовке отчета о состоянии сборки;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Поддерживать высокий уровень покрытия автоматизированными тестами&lt;/b&gt;. Обычно Scrum-команды стремятся покрыть автоматизированными тестами 70-80% кода. Один из наших важнейших активов — большой набор автотестов, играющий ключевую роль в поставке качественных релизов в срок каждые 3-4 месяца.&lt;/li&gt;
&lt;/ol&gt;
&lt;em&gt;4.7 Scrum-of-Scrums&lt;/em&gt;&lt;br /&gt;
В каждом бизнес-подразделении еженедельно проводится собрание Scrum-of-Scrums, существует и » Scrum-of-Scrum-of-Scrums». Иногда мы организуем дополнительный Scrum-of-Scrums для группы команд, тесно взаимодействующих при работе над общей целью. Мы опробовали несколько различных форматов проведения Scrum-of-Scrums. Мы начали со стандартного формата «4 вопроса», когда команды сообщали, что они сделали, что собираются делать, что их блокирует, и делают ли они что-то влияющее на работу других команд. Поначалу это работало, но вскоре стало утомительным и скучным из-за большого количества команд. Тогда мы перешли к более открытому формату самоорганизации, когда участники предлагали темы для обсуждения, выписывая их на доске в начале собрания. Это заставило участников взять на себя ответственность за содержание митинга и привело к более продуктивным обсуждениям. Вопрос межкомандных зависимостей часто поднимается во время Scrum-of-Scrums, особенно на ранних стадиях разработки. Сессия распознавания взаимосвязей проводится во время Scrum-of-Scrums, и в последующие две-три недели на этом собрании часто обсуждаются изменения в межкомандных зависимостях.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;4.8 Отчеты о состоянии&lt;/em&gt;&lt;br /&gt;
Когда команда переходит на Scrum, письменные отчеты часто становятся не нужны, поскольку ясность состояния теперь обеспечивается за счет других вещей (обзоры спринтов, burndown chart, ежедневные стендап-митинги). Когда мы перешли на Scrum, то решили сохранить облегченные еженедельные отчеты о статусе, которые готовит каждый Scrum мастер. Это выглядело избыточно пока мы использовали формат «4 вопроса» для Scrum-of-Scrums. Однако при нынешнем открытом формате Scrum-of-Scrums еженедельные отчеты стали важным дополнением к этому собранию. Мы не обсуждаем состояние каждой команды во время Scrum-of-Scrums, если только это не вынесено как отдельный вопрос, однако этот статус всегда доступен в еженедельном отчете. В отчете обозначены все зависимости, блокеры и риски. Конечно, такие отчеты требуют немного дополнительных усилий от Scrum мастеров, но ясность, которую они обеспечивают, оправдывает затраты на их создание.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;5 Заключение&lt;/strong&gt;&lt;br /&gt;
Salesforce.com доказала, что масштабирование Scrum осуществимо, и мы уверены, что сможем продолжать такое масштабирование по мере роста компании. По мере роста количества команд, управление взаимосвязями и межкомандная координация становятся непростой задачей. Критически необходима надежная инфраструктура сборки и автоматизированного тестирования. Очень помогает повышение осведомленности и синхронизация с помощью стартового собрания, сессии выявления взаимосвязей, Scrum-of-Scrums и облегченных отчетов о состоянии. В конечном итоге это приводит к эффективному общению, взаимодействию и обмену знаниями между командами. Такие подходы, как виртуальная команда архитектуры, открытые обсуждения и Scrum-of-Scrums призваны помочь общению и поддержать взаимодействие.</description><link>http://notsocritical.blogspot.com/2014/10/cross-linked.html</link><author>noreply@blogger.com (Pavel )</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBwGFwnSHUEWpNBxQZvQBU36yYnpq0lb956NoZbY5J_fJYOj_Hg_Ehxcq4v3e2McieAMb0zCaO0TaR3XaZHGjrVh1QCmYxIXDcExdGB1YjPOsm0F9o72Lmic8tnkMMvgWbuRhFup8u1GE/s72-c/CrossTeamDepends.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-2706365712181367329</guid><pubDate>Wed, 03 Oct 2012 02:55:00 +0000</pubDate><atom:updated>2012-10-03T09:55:13.018+07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">конфигурации</category><category domain="http://www.blogger.com/atom/ns#">техники</category><category domain="http://www.blogger.com/atom/ns#">эффективность</category><title>100500 конфигураций.</title><description>Знакомая многим проблема: тестируя, мы настраиваем продукт и окружение не совсем так, как это делают пользователи. Причин для этого масса – нет того оборудования, недостаточно времени, неучтенные сочетания настроек, более приоритетные задачи и так далее.&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;a name=&#39;more&#39;&gt;&lt;/a&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;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;br /&gt;&lt;br /&gt;Наконец, анализируйте проблемы найденные пользователями. Без этого половина вышеупомянутых действий де-факто бессмысленна. Может, мы неверно расставили приоритеты, или не учли какие-то отличия настроек в лабе и в боевом окружении, или поторопились что-то объявить устаревшим, или ошиблись еще в чем-то. Всегда полезно узнать, что мы можем делать лучше, чем сейчас.&lt;br /&gt;&lt;br /&gt;Удачи вам, понятных конфигураций и жизненных тестовых лаб.&lt;br /&gt;
&lt;br /&gt;</description><link>http://notsocritical.blogspot.com/2012/10/100500.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-967602141418406997</guid><pubDate>Mon, 10 Sep 2012 02:35:00 +0000</pubDate><atom:updated>2012-09-10T09:35:02.740+07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">инструменты</category><category domain="http://www.blogger.com/atom/ns#">эффективность</category><title>4k+ знаков про ТО</title><description>Тестовое окружение – неизменный спутник тестирования. Неважно, какое ПО мы тестируем, без разницы, какую используем методологию: если мы выполняем тест, то, как минимум, нам нужен объект тестирования в подходящем состоянии. И как только этот объект появляется, появляется и оно, тестовое окружение.&lt;br /&gt;
&lt;br /&gt;
Тестовое окружение (ТО) может готовиться заранее, а может «возникать» прямо в момент выполнения теста. Разным проектам нужны разные ТО, что естественно. ТО меняется вместе с развитием продукта, требованиями к нему, бюджетом и пониманием роли тестирования. Короче, как водится, идеального-вообще ТО не бывает, бывает – адекватное здесь-и-сейчас, решающее текущие задачи при данных обстоятельствах (ну и желательно с каким-то заделом на обозримое будущее).&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Говорят, хороший интерфейс ПО – тот, который пользователь «не замечает», а просто решает свои задачи, работая с программой. Про ТО можно сказать что-то подобное: чем проще подготовка и выполнение тестов, воспроизведение дефектов, работа с прочими артефактами, тем лучше ТО. Чем меньше мы спотыкаемся о разложенные нами же грабли, не относящиеся к тестируемому продукту, тем больше мы спотыкаемся о грабли в продукте, разбросанные разработчиками. А этого от нас и ждут, ага.&lt;br /&gt;
&lt;br /&gt;
Создание такого ТО, понятно, требует труда. По сути,  это такой сопутствующий проект – со своими требованиями, дедлайнами и потребителями. Скорее всего, этот проект будет длиться не меньше, чем собственно разработка system under test (SUT). От этого проекта серьёзно зависит успех производимого продукта.&lt;br /&gt;
&lt;br /&gt;
Можно выделить несколько требований, актуальных для большинства ТО.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Применимость&lt;/b&gt;&lt;br /&gt;
ТО должно отвечать поставленным задачам. Железо должно соответствовать требованиям к SUT. Хорошо бы, чтоб конфигурации были подобны тем, что используются в боевом режиме (или мы хотя бы знали diff).&lt;br /&gt;
Конечно, ТО должно позволять выполнить необходимые тесты и прочие активности. Должна быть возможность проверить различные важные конфигурации (поддерживаемые ОС, БД, локализации, и т.д.). В общем, тестировщики должны иметь возможность тестировать, иначе зачем всё?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Изолированность&lt;/b&gt;&lt;br /&gt;
По-хорошему, SUT должна запускаться на отдельных серверах, реальных или виртуальных. Это не должны быть сервера разработчиков. Это не должны быть рабочие станции сотрудников. Это не должны быть сервера взятые на час взаймы у соседнего отдела.&lt;br /&gt;
Подобная изолированность защищает, с одной стороны, от особенностей конфигурации отдельных машин. С другой – от потери данных из-за нестабильности SUT. С третьей – упрощает контроль за состоянием SUT и конфигурациями, обеспечивает воспроизводимость тестов. Ладно, даёт шанс обеспечить воспроизводимость. &lt;br /&gt;
В более долгосрочной перспективе – позволяет настраивать нетривиальное окружение, варьировать настройки и подходы, проверять идеи и подозрения. Масса пользы в общем.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Доступность и простота&lt;/b&gt;&lt;br /&gt;
Если нет каких-то особых причин для обратного, ТО должно быть легко доступно для всех, кто с ним работает – тестировщиков, программистов, аналитиков и других интересующихся. &lt;br /&gt;
Не должно быть проблем с созданием нового экземпляра SUT в требуемой конфигурации.&lt;br /&gt;
Нам нужна возможность без особых затрат отслеживать состояние и использование ТО – что где находится и почему, кто использует тот или иной объект (например, копию SUT), где у нас есть свободные ресурсы, и т.д.&lt;br /&gt;
По возможности следует исключить конфликты использования общих ресурсов/объектов.&lt;br /&gt;
Если отдельные проверки требуют специфичных данных, имеет смысл их подготовить заранее и сложить в какое-то общее хранилище. Не в ущерб качеству тестов, конечно.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Управляемость&lt;/b&gt;&lt;br /&gt;
ТО должно быть управляемо. Добавление или замена серверов должны происходить максимально просто. Внезапные падения старых машин не должны вести к фатальным последствиям (ну, хотя бы не всегда). Перенос данных между серверами тоже не должен становиться проблемой. &lt;br /&gt;
Перераспределение машин под ту или иную задачу, перенастройка, обновление, развертывание SUT – все это должно быть возможно, и желательно – легко выполнимо.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Стабильность&lt;/b&gt;&lt;br /&gt;
Пусть SUT сколь угодно нестабильна, ей можно, а ТО должно быть здоровым и непотопляемым. Тут стоит задействовать практики рекомендованные системным администраторам (кстати, невредно с ними проконсультироваться, если есть с кем) – мониторинг состояния железа, контроль нагрузки на сервера, регулярные бэкапы и подготовка сценариев на случай внезапной смерти Самого Важного Сервера…&lt;br /&gt;
В общем, все, что выглядит нужным и применимым.&lt;br /&gt;
&lt;br /&gt;
Пожалуй, для начала достаточно этих пяти небольших китов. На них можно построить вполне себе приличное тестовое окружение. Особенно, если не забывать думать хотя бы на полшага вперёд и планировать развитие ТО, отталкиваясь от нужд проекта. </description><link>http://notsocritical.blogspot.com/2012/09/4k.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-383714629136884092</guid><pubDate>Mon, 16 Apr 2012 02:08:00 +0000</pubDate><atom:updated>2012-04-16T10:20:02.924+07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">здравый смысл</category><category domain="http://www.blogger.com/atom/ns#">капитан О.</category><category domain="http://www.blogger.com/atom/ns#">новичок</category><title>Привет, Аноним в поисках вопросов</title><description>&lt;div style=&quot;text-align: justify;&quot;&gt;
Внезапно мне пришёл комментарий:&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Анонимный прокомментировал(а) ваше сообщение:&lt;br /&gt;
&lt;i&gt;Добрый день, Павел. &lt;br /&gt;Решил себя попробовать в тестировании, как мне казалась вещь очень интересная (знания брал из знаменитой для тестировщиков книги Савина), устроился в компанию, которая разрабатывает свой програмный продукт, проработав меньше месяца сбежал, т.к.было настолько скучно (тестирование - черный ящик, метод назывался &quot;свободный поиск&quot;).&lt;br /&gt;О чем спрашивать работодателя, когда принимают на работу? какие вопросы задавать по тестированию (чтобы потом не было так скучно)?
&lt;/i&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
Комментарий к комментарию получился длинноват, так что публикую его отдельным постом.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&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;
&lt;i&gt;Совсем бессмысленный ответ&lt;/i&gt; (я испорчен массовой культурой, да): Перефразируя писателя Пелевина, можно сказать так: «Очень общее описание, что угодно может оказаться».&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Пространный ответ&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Давай я пройдемся по твоему комменту и попробуем понять, что же произошло.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt;&lt;br /&gt;
Итак, ты прочел Савина и пошёл устраиваться в тестировщики. Опыта, как я понимаю, пока нету. Знание техник тестирования – на уровне книги Савина. &lt;br /&gt;
&lt;br /&gt;
Тут есть нюанс. Если я верно помню, Савин описывает скорее некий общий процесс разработки ПО и примерное место тестирования в этом процессе. Да, он уделяет больше внимания тестированию, чем разработке, и рассказывает, как работать с багтрекером. Но на самом деле это – про процесс тестирования, а не про его техники. Ну просто чтоб юный тестировщик понимал контекст своей работы – откуда появляется предмет тестирования, кто обрабатывает багрепорты и т. п. Естественно, Роман старался описать общий подход. Естественно, в реальной жизни процесс отличается от книжного (где-то больше, где-то совсем). &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt;&lt;br /&gt;
Ну ладно, так или иначе – ты устроился на работу и начал свой путь тестировщика. Чорный ящик + свободный поиск. Не очень понятно, в чём тут скука. Ты же не ожидал, что тебя сразу посадят работать с Самой Главной Фичей или анализировать архитектуру проекта. Или – что ящик сразу будет белый/прозрачный: это требует умения читать и анализировать код и еще некоторых специфических знаний, которые трудно ожидать от новичка с Савиным в рюкзаке. &lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Нет, задачи первого времени: познакомить тебя с продуктом, посмотреть, как ты работаешь (на собеседовании же этого не увидишь особо), как общаешься с коллективом и т.д. Понятно, решать их можно по-разному, смотря сколько ресурсов в наличии и какие люди нужны.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Кроме того, есть такой нюанс, что при долгой работе с продуктом глаз «замыливается», и часть проблем просто не замечается. На этот случай новичок, не знакомый с продуктом, просто клад. Он же совсем ничего не знает пока про продукт. Он, конечно, задаст кучу «глупых» вопросов, но параллельно и пару-десяток багов на юзабилити, а то и логику приложения выявит.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Вот тебя и посадили знакомиться с продуктом и командой, а не свободно искать баги в чёрном ящике. Нет, если их нашёл, это только плюс. Но в первый месяц это обычно не самое главное.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #cccccc;&quot;&gt;Домашнее задание: Вспомни, что ты делал, когда становилось непонятно и скучно. Как ты знакомился с продуктом. Сколько вопросов задавал, как и кому. Разобрался ли с главной идеей продукта. Какой там основной сценарий использования. Можешь ответить внятно – хорошо. Нет – а может, ты не очень и интересовался? А работодатель-то больше любит активных ребят. Да и не могут окружающие понять без твоей помощи, что тебе понятно, а что нет.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3.&lt;/b&gt;&lt;br /&gt;
Так о чём же спрашивать работодателя, когда принимают на работу? &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Ну, вообще – о чём угодно, точнее – обо всём, что интересно (и имеет отношение к работе, конечно). Сколько лет другим тестировщикам? На скольки проектах нужно будет работать? Сколько лет проекту? Каковы его перспективы? Что будет, когда он закончится? Есть ли в здании столовая? Давно ли образована команда тестирования? Во сколько люди приходят на работу? Какая ОС используется на рабочих машинах? Как уменьшить испытательный срок? В какой комнате я буду сидеть? Можно ли совмещать работу с учёбой? Что самое главное в моей работе? Какая методология разработки используется? А свою кружку можно принести на работу?&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Список вопросов ограничен только фантазией, временем на обсуждение, ну и слегка – позицией, на которую идешь. Не надо только задавать вопросы ради вопросов. Спрашивай о том, что правда интересно и важно для тебя. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Вообще, в интернетах немыслимое количество &lt;a href=&quot;https://www.google.ru/search?q=%D0%BE+%D1%87%D0%B5%D0%BC+%D1%81%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C+%D0%BD%D0%B0+%D1%81%D0%BE%D0%B1%D0%B5%D1%81%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:ru:official&amp;amp;client=firefox&quot;&gt;статей&lt;/a&gt; &lt;a href=&quot;http://yandex.ru/yandsearch?text=%D0%BA%D0%B0%D0%BA+%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C%D1%81%D1%8F+%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D1%82%D1%8C+%D0%B2+IT&amp;amp;from=fx3&amp;amp;clid=46510&amp;amp;lr=65&quot;&gt;про&lt;/a&gt; &lt;a href=&quot;http://go.mail.ru/search?q=%EA%E0%EA+%EF%F0%EE%E9%F2%E8+%F1%EE%E1%E5%F1%E5%E4%EE%E2%E0%ED%E8%E5&amp;amp;utf8in=1&amp;amp;fr=ff3tb&quot;&gt;собеседование&lt;/a&gt; и как его успешно провалить. Часть вопросов можно почерпнуть оттуда. &lt;a href=&quot;http://www.itcompanies.ru/15sobesed.html&quot;&gt;Вот&lt;/a&gt;, например.&lt;br /&gt;
&lt;br /&gt;
Не, ну с вопросами-то понятно. А что спрашивать, чтобы потом не было так скучно?&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Ну что тебе сказать, я не знаю. Почему скучно-то было?&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Тестировать – это всё же работа, а не телевидение, оно тебя само по себе развлекать не будет. Или дело не в тестировании, а продукт был неинтересный? Или с командой характерами не сошелся? Найди скучный угол, и пляши от него, да.&lt;br /&gt;
&lt;br /&gt;
Важный момент: вопросами «когда принимают на работу» всё не заканчивается. Когда уже приняли, их всё еще можно задавать. И нужно. Чем больше спросишь – тем больше тебе расскажут, тем больше будешь понимать, тем больше интересного узнаешь. &lt;br /&gt;
&lt;br /&gt;
Конечно, если вся команда тестирования состоит из новичков, то знания будут добываться потом и кровью. Чуть проще работать там, где есть опытные тестировщики, которые укажут на самые большие грабли на пути. В какой из таких команд работать менее скучно – ну, не знаю, it depends.&lt;br /&gt;
&lt;br /&gt;
Помимо работодателя, вокруг есть еще довольно большой мир. А в мире – довольно много ребят, &lt;a href=&quot;http://alexeybulat.blogspot.com/&quot;&gt;которым&lt;/a&gt; &lt;a href=&quot;http://goblingame.blogspot.com/&quot;&gt;настолько&lt;/a&gt; &lt;a href=&quot;http://qcthoughtsaloud.blogspot.com/&quot;&gt;интересно&lt;/a&gt; &lt;a href=&quot;http://okiseleva.blogspot.com/&quot;&gt;тестирование&lt;/a&gt;, &lt;a href=&quot;http://seljava.blogspot.com/&quot;&gt;что&lt;/a&gt; &lt;a href=&quot;http://vestfalka.blogspot.com/&quot;&gt;они&lt;/a&gt; &lt;a href=&quot;http://jnechaeva.blogspot.com/&quot;&gt;ведут&lt;/a&gt; &lt;a href=&quot;http://hvorostovoz.blogspot.com/&quot;&gt;свои&lt;/a&gt; &lt;a href=&quot;http://software-testing.ru/about/blogs&quot;&gt;блоги&lt;/a&gt;, &lt;a href=&quot;http://software-testing.ru/trainings/schedule&quot;&gt;обучают&lt;/a&gt; &lt;a href=&quot;http://testitquickly.com/podklass/&quot;&gt;других&lt;/a&gt;, обсуждают интересное на &lt;a href=&quot;http://software-testing.ru/forum/forum/279/&quot;&gt;форумах&lt;/a&gt;, &lt;a href=&quot;http://it-conf.ru/ru/content/464.htm&quot;&gt;устраивают&lt;/a&gt; &lt;a href=&quot;http://confetqa.ru/&quot;&gt;конференции&lt;/a&gt;. &lt;span style=&quot;color: #cccccc;&quot;&gt;И это только русскоязычный мир.&lt;/span&gt; Посмотри, о чем они пишут/говорят; наметь перспективы, куда можно двигаться; придумай первые три шага на этом пути; шагай по плану.&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;
Короче, чтоб было интересно – интересуйся, что происходит вокруг и как всё устроено. Это поможет и не скучать, и работать эффективнее, и вообще поможет.&lt;br /&gt;
&lt;br /&gt;
Сумбурно получилось, извини – давно я не брал в руки шашек. Надеюсь, хоть частично я тебе ответил.&lt;br /&gt;
Пойду работать, у меня там сегодня столько вкусного запланировано…&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2012/04/blog-post.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-5386315136436956781</guid><pubDate>Fri, 20 May 2011 13:58:00 +0000</pubDate><atom:updated>2011-05-20T20:58:50.901+07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">апгрейд</category><category domain="http://www.blogger.com/atom/ns#">наблюдения</category><category domain="http://www.blogger.com/atom/ns#">тестирование</category><title>Новая версия доступна. Обновить?</title><description>&lt;div style=&quot;text-align: justify;&quot;&gt;В жизни приложений, помимо &quot;просто работы&quot;, есть масса интересных, пусть и относительно редких событий. &lt;br /&gt;
Приложение должно корректно устанавливаться – и нам нужно проверять это.&lt;br /&gt;
Приложение должно корректно удаляться (а вдруг!) – и нам нужно проверять это.&lt;br /&gt;
Приложение должно корректно обновляться до новой версии – и нам… подождите-подождите… нужно проверять это!&lt;br /&gt;
Об апгрейдах и пойдет речь.&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;Порой мне начинает казаться, что “забыть про апгрейд” – дело не то чтобы обычное, но и нередкое. Ну ладно, забыть – слишком сильно сказано, просто – отложить. Нет, конечно,&amp;nbsp; процедуру апгрейда сделаем, но пока вот сосредоточимся на доведении функциональности до ума. А потом все разом прикрутим и протестируем. &lt;/div&gt;&lt;br /&gt;
&lt;span style=&quot;color: #666666;&quot;&gt;Ну, мы знаем, сколько того &quot;потом&quot; обычно остается.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;Отложить тестирование апгрейда &quot;на потом&quot;, проводить такое тестирование на простейших сценариях означает создать проблемы своим клиентам. Хочу отдельно обратить внимание: не потенциальным клиентам, а людям, которые уже используют наш продукт и собирались использовать и дальше. &lt;span style=&quot;color: #666666;&quot;&gt;А тут вдруг апгрейд сломался в середине и похоронил все данные за два года работы. Беда…&lt;/span&gt; Неудивительно, если клиенты разбегутся, когда что-то пойдет не так.&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;Ладно, будем считать, что все согласны: аккуратная проверка апгрейдов необходима. Будем проверять. &lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;Что проверять – зависит от приложения, а они бывают разными, и апгрейдиться могут различными способами. Впрочем, многие проблемы актуальны для самых разнообразных программ. Некоторые из таких проблем я и хочу упомянуть.&lt;/div&gt;&lt;br /&gt;
&lt;span style=&quot;color: #666666;&quot;&gt;Disclaimer. Все &quot;диалоги&quot; выдуманы, совпадения случайны, слова перепутаны, буквы стоят не на своих местах. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Всего лишь набор файлов&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Что может пойти не так при апгрейде, если все наше приложение это набор файлов, некоторые из которых – исполняемые?&lt;br /&gt;
&lt;br /&gt;
Да вроде как и особо ничего, а? Берем новые файлы, копируем их на место старых – и готово. Ну для порядка можно &quot;инструкцию апгрейда&quot; написать, что-то вроде&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 1. Откройте папку, в которую установлено приложение (путь по умолчанию: ХХХ).&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 2. Скопируйте в нее файлы входящие в новую версию приложения&lt;br /&gt;
А лучше – использовать инсталлятор/скрипт, который все файлы сам по местам разложит. &lt;br /&gt;
&lt;br /&gt;
Все так, пока программист проверяет апгрейд, выполняя &quot;очевидные&quot; действия, которые &quot;и так сами собой разумеются&quot;. У пользователя же потом апгрейд может сломаться, потому что&lt;br /&gt;
- File is locked &lt;span style=&quot;color: #666666;&quot;&gt;– Ой, мы не проверили, что приложение не запущено.&lt;/span&gt;&lt;br /&gt;
- Access is denied &lt;span style=&quot;color: #666666;&quot;&gt;– Из под какого пользователя они запускают апгрейд?&lt;/span&gt;&lt;br /&gt;
- Диск полон &lt;span style=&quot;color: #666666;&quot;&gt;– И это в век терабайтных дисков?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Или – апгрейд успешно отработал, но приложение не запускается, ведь&lt;br /&gt;
- Method not supported &lt;span style=&quot;color: #666666;&quot;&gt;– Упс, а версия одной библиотеки старая. Забыли файл обновить.&lt;/span&gt;&lt;br /&gt;
- ОЙ, какая-то мистика &lt;span style=&quot;color: #666666;&quot;&gt;– Эээ, какая у них древняя ОС. А мы-то писали-проверяли только с последними апдейтами. Хотя прежняя версия и без них работала…&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
А еще – апгрейд отработал, а версия программы запускается прежняя. &lt;span style=&quot;color: #666666;&quot;&gt;– Хех. У них программа стояла по кастомному пути, а мы &quot;проапгрейдились&quot; в дефолтный :)&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
Список, понятно, не полон. Но, дает понять, что проблемы могут возникнуть даже с простейшим приложением.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&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;
- Апгрейд закончился, а сервис работает точно как раньше! &lt;span style=&quot;color: #666666;&quot;&gt;– А рестартануть-то демона мы забыли!&lt;/span&gt;&lt;br /&gt;
- Все работает, все здорово, только сервис перестал запускаться после рестарта сервера.&lt;span style=&quot;color: #666666;&quot;&gt; – Даа, а настройки запуска мы сбросили в &quot;умолчальные&quot; во время апгрейда…&lt;/span&gt;&lt;br /&gt;
- Эй, сервис не работал все время, пока шел апгрейд! Кто мне заплатит за простой бизнеса? &lt;span style=&quot;color: #666666;&quot;&gt;– Хм, надо бы предупреждать, наверное, что сервис будет приостанавливаться во время апгрейда.&lt;/span&gt;&lt;br /&gt;
- Будет простой сервиса? Ну ладно, спасибо, что предупредили. А долгий простой-то? &lt;span style=&quot;color: #666666;&quot;&gt;– Слушай, и правда надо измерять время даунтайма. И, кстати, попробовать как-то минимизировать его.&lt;/span&gt;&lt;br /&gt;
- Я апгрейд выполнил, и уехал по делам. А сервис после апгрейда не запустился оказывается! &lt;span style=&quot;color: #666666;&quot;&gt;– Надо бы запоминать, в каком состоянии сервис был до апгрейда – и возвращать его в то же состояние после.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Да, стоит помнить, что клиенты не для развлечения наши сервисы разворачивают…&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Клиент-Сервер&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Отношения Клиент-Сервер – обычное дело в современных программах. Впрочем, и эти отношения бывают &quot;разной степени усложненности&quot;. &lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
Простейший случай – это когда есть четко выделенные клиентская и серверная часть размещенные на одном хосте. Более сложный – когда много инстансов клиентов крутятся на удаленных хостах и обращаются к одному серверу. А еще интереснее становится, если приложение распределено по нескольким серверам, и различные его части выступают по отношению друг к другу то как клиент, то как сервер.&lt;br /&gt;
&lt;br /&gt;
- Не могу подключиться к серверу. Никогда такой ошибки не было! &lt;span style=&quot;color: #666666;&quot;&gt;– Как мы забыли предупредить, что клиентскую часть тоже надо апгрейдить, а старая версия клиента не сможет работать с сервером???&lt;/span&gt;&lt;br /&gt;
- Мне что, запускать апгрейд на каждом хосте, где стоит какой-то модуль системы?? &lt;span style=&quot;color: #666666;&quot;&gt;– Кстати да, мы могли бы и автоматически обновлять все хосты – параллельно или один за другим, надо подумать, как лучше. А то боком нам распределенность выходит.&lt;/span&gt;&lt;br /&gt;
- Что-то апгрейд упал на середине… &lt;span style=&quot;color: #666666;&quot;&gt;– ОЙ, вот мы молодцы! Модуль Первый на хосте 01 проапгрейдился и пытается пнуть модуль Второй на хосте 02. А интерфейс общения-то другой после апгрейда! Где ты, обратная совместимость? Даа, на свежих инсталляциях таких проблем не возникает…&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
И по-прежнему, все проблемы из предыдущих частей могут оказаться актуальными и в этом случае.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&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;
В целом БД состоит из структуры базы данных (таблицы, индексы, ограничения и т.д.) и собственно данных. Пострадать при апгрейде может и то, и другое. &lt;br /&gt;
&lt;br /&gt;
Неверная структура БД может аукнуться по-разному: от явного сбоя в работе приложения (когда оно не найдет требуемую таблицу или поле) до накопления несовместимых, неверных данных в этих самых таблицах. Трудно сказать, что хуже. Пожалуй, все-таки второе. &lt;br /&gt;
&lt;br /&gt;
Хороший способ контроля структуры БД – сравнивать структуру проапгрейженой БД со структурой БД, полученной в результате свежей установки приложения. Другой вариант – не изменять &quot;боевую&quot; БД, а создавать рядом новую, как в случае свежей установки, а потом просто переносить данные из одной БД в другую. Заодно и копия данных остается в старой БД. &lt;br /&gt;
&lt;br /&gt;
С самими данными все хитрее. Их целостность контролировать сложнее, особенно если меняется структура таблиц, и данные переносятся в процессе апгрейда из одного места в другое. Тут, кроме сравнения содержимого БД до и после апгрейда, ничего особо в голову не приходит, а как это сделать правильно – сильно зависит от совершаемых изменений. &lt;br /&gt;
&lt;br /&gt;
Кроме того, сами данные могут повлиять на ход апгрейда. Например, если в результате неверной работы приложения (или самого апгрейда) в таблице появились дублирующиеся записи, а процедура апгрейда добавляет на поле таблицы требование уникальности значения, то апгрейд ожидаемо сломается с соответствующим сообщением. И решать проблему в этом случае придется руками. И хорошо, если в тестовой лабе, а не на боевом сервере. Потом, конечно, желательно изменить процедуру апгрейда таким образом, чтоб подобные проблемы не возникали или решались заранее.&lt;br /&gt;
&lt;br /&gt;
Другой аспект, на который могут влиять данные, – это время апгрейда. Чем больше в таблице записей, тем больше времени потребуется на изменение структуры этой таблицы и обновление данных в ней. А время потраченное на апгрейд – это время потерянное для бизнеса, и его надо минимизировать. Тут тоже в зависимости от ситуации, требований и ожиданий можно применять разные подходы, от выполнения низкоуровневых функций до использования отдельного сервера для апгрейда БД, пока приложение работает со старым.&lt;br /&gt;
&lt;br /&gt;
Еще интересен случай, когда приложение умеет работать с разными движками БД. SQL, как известно, &quot;немного свой&quot; у каждого движка – MySQL, PgSQL, MSSQL… Всегда есть шанс, что запрос, работающий на PgSQL, окажется нерабочим на MSSQL. На этот случай вариантов немного – нужно проверять на всем, что поддерживается.&lt;br /&gt;
&lt;br /&gt;
Если приложение состоит из нескольких компонент, каждая из которых работает со своей базой данных, то это тоже нужно учитывать во время апгрейда. Например, не стоит пытаться править БД, относящуюся к компоненте, которую даже не устанавливали (и соответственно – не создавали саму БД). Ну и в чужие БД лазить не стоит, конечно.&lt;br /&gt;
&lt;br /&gt;
Пожалуй, пока достаточно. Не будем рассматривать случаи переполнения диска или потери связи до сервера БД, равно как и использование несколько таких серверов, реплицирующих данные между собой (или не реплицирующих). &lt;br /&gt;
&lt;br /&gt;
Кстати, проблема целостности данных актуальна не только для баз данных. Например, обидно будет, если после обновления браузера потеряются все закладки и настройки, неважно, где там они хранятся, – в реляционной базе данных или текстовом файле.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&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;
Нагрузочному тестированию инсталер, наверное, подвергать незачем, но в целом стоит не забывать про этот кусочек продукта.&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Пара общих соображений&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Напоследок выскажу еще несколько соображений, не вошедших в предыдущие части.&lt;br /&gt;
&lt;br /&gt;
К апгрейду вполне применимо одно из простейших правил тестирования: не верь &quot;очевидному&quot;, проверь. Пусть кажется, что все очень просто, и проблеме вылезти неоткуда. Практика показывает, что жизнь богаче, чем можно представить.&lt;br /&gt;
&lt;br /&gt;
Полезную практику непрерывной интеграции хорошо бы распространять и на тестирование апгрейдов. Так и проблемы быстрее будут обнаруживаться, и соблазна отложить создание процедур апгрейда &quot;на потом&quot; будет меньше.&lt;br /&gt;
&lt;br /&gt;
Имеет смысл даже после тщательного тестирования быть готовым к возможным проблемам у клиентов, особенно в случае апгрейда баз данных. Наполнение БД на боевых серверах обычное хитрее и разнообразнее того, что можно придумать в тестовой лабе, а значит могут вылезать неучтенные проблемы. &lt;br /&gt;
&lt;br /&gt;
На этом, пожалуй, хватит.&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Удачи вам и быстрых беспроблемных апгрейдов.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/05/blog-post.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-6118159286288457132</guid><pubDate>Thu, 07 Apr 2011 07:00:00 +0000</pubDate><atom:updated>2011-04-07T14:00:33.864+07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">инструменты</category><category domain="http://www.blogger.com/atom/ns#">наблюдения</category><category domain="http://www.blogger.com/atom/ns#">планирование</category><category domain="http://www.blogger.com/atom/ns#">процессы</category><title>Всего лишь пара изменений</title><description>&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Чем хороши изменения требований - они, пусть даже и возникают неожиданно, а все равно пройдут весь традиционный круг оценок и планирования. Ну ладно, должны проходить. Но все равно об изменениях мы узнаем заранее.&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Но не всегда тестировщик заранее знает, что что-то в поведении продукта изменится. Приходит он на работу, берет свежий билд приложения и видит, что добавились/пропали/переехали контролы в GUI. Или поменялась очередность шагов визарда. Или изменилась давно привычная логика работы. Да мало ли что. А чтоб такие изменения планировались, он и не слышал. Баг писать? Или так и должно быть теперь?&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;В целом понятно, что если оснований для изменений нет, то со стороны тестировщика честно будет написать баг. Возможно, этот баг потом выкинут, но зато хоть повод для обсуждений появится.&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Другой вопрос - как такая ситуация могла возникнуть. Есть варианты, да. Возможно, потихоньку идет процесс улучшения GUI и юзабилити продукта. Или - прилетел баг от клиента, и его починили в продукте, а тестировщик этого бага и не видел пока. Или - над продуктом работают несколько команд разработчиков и тестировщиков, каждая в своей песочнице, и время от времени их наработки добавляются в новые билды. Много чего возможно.&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;И вопрос - как эти изменения контролировать?&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;В маленьких командах этот вопрос, наверное, не очень актуален, но чем больше людей, тем сложнее работать с изменениями. Тем более, что разным людям и в разное время нужны разные данные об изменениях. Но в любом случае, первое, что приходит на ум - это&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Сообщать об изменениях&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Сообщать, по большому счету, можно любым способом - словом, письмом, страничкой в вики и т.д. Что удобнее в каждом отдельном случае - зависит от размера команды, масштаба изменений и еще примерно трехсот параметров.&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Что именно сообщать - тоже во многом вопрос контекста, но в любом случае стоит упомянуть, в чем суть изменения, на каком основании оно сделано, с какого момента оно вступает в силу.&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;В принципе, так можно сообщать не только о неожидаемых изменениях, но и о готовности [части] фичи к тестированию. Понятно же, что не всякое изменение - фича, но всякая фича - изменение. &lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Ок, нам сообщили, можно жить и радоваться. Тестировщику - наверное, да, можно. А его начальнику, возможно, пора задуматься, как&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Сохранять историю тестирования изменений&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Мы же тестировщики; если что-то изменилось - наша работа проверить, что все продолжает работать как нужно.&amp;nbsp; А по итогам тестирования мы должны ответить - что было протестировано в контексте данного изменения, когда (в каких билдах), с каким результатом. &lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Опять же, как сохранять эту информацию - дело вкуса. Кому-то подойдут ответы на письма об изменениях. Кто-то захочет все свести в единую таблицу. Важно чтоб в итоге было удобно с этими отчетами работать. &lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Впрочем, история - это хорошо и полезно, но иногда стоит еще и&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Планировать тестирование изменений&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Действительно, на одну и ту же функциональность может прилететь несколько изменений, затрагивающих разные нюансы. С точки зрения тестирования может быть дешевле проверять такие изменения не по мере поступления, а все скопом. &lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Тут, правда, нужно как-то узнать, что планируется N изменений в данной части продукта, а это не всегда возможно. Про фичи-то мы знаем, конечно, а вот с мелкими изменениями и фичами других команд дела обстоят посложнее.&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Кроме того, не надо забывать про баги. Откладывая тестирование до момента внесения всех ожидаемых изменений, мы и починку внесенных багов откладываем на тот же (или больший) срок. Риск, ага. &lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Контролировать изменения или нет, и как тщательно, - дело каждого отдельного проекта. Лишь бы изменения не засыпали проект с головой.&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;Удачи вам, внятных требований и контролируемых изменений.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/04/blog-post.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>8</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-7084650879502525875</guid><pubDate>Fri, 11 Mar 2011 07:03:00 +0000</pubDate><atom:updated>2011-03-11T13:03:45.705+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">баги</category><category domain="http://www.blogger.com/atom/ns#">логи</category><category domain="http://www.blogger.com/atom/ns#">списки</category><title>Баг для лога</title><description>&lt;div align=&quot;justify&quot;&gt;В &lt;a href=&quot;http://notsocritical.blogspot.com/2011/03/blog-post_09.html&quot;&gt;предыдущем посте&lt;/a&gt; речь шла о пользе чтения логов при исследовании и описании дефектов ПО. Сегодня я хочу зайти немного с другой стороны.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Логи, безусловно, помогают исследовать поведение приложения, но в то же время логи – часть тестируемого продукта. То есть – их тоже можно тестировать. И вокруг них тоже могут водиться баги, а как же.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Предположим, что худшего не случилось, приложение работает и даже пишет логи в положенное место. Перечислю несколько направлений, в которых можно искать проблемы.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Полнота&lt;/b&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Все ли операции, которые выполняет приложение, логируются (на том или ином уровне)? Тут, конечно, сразу возникает вопрос, что мы считаем операцией, должны ли все они действительно попадать в лог и т.д. Как обычно, все зависит от приложения. Где-то достаточно упомянуть самые верхнеуровневые бизнес-сценарии. В другом потребуется детальная информация о выполняемых запросах. Опять же, разным уровням логирования обычно соответствует и разная степень детализации. &lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Настраиваемость&lt;/b&gt; &lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Можно ли изменять настройки логирования? Изменяется ли реальное поведение при изменении настроек? Адекватны ли настройки выставляемые по умолчанию? Легко ли изменяются настройки? Все это тоже предмет для проверки и, возможно, улучшения, почему нет.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Безопасность&lt;/b&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Не попадает ли в лог что-то такое, что не должно туда попадать? Пароли простым текстом, номера кредиток и т.д. Опять же, для разных приложений и секретная  информация – разная. Кто и как может получить доступ к логам? Как он может использовать добытую оттуда информацию?&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Производительность&lt;/b&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Приложение, пишущее логи, создает дополнительную нагрузку на дисковую систему. Для иных приложений эта нагрузка может быть весьма ощутимой, и лучше отследить это в тестовой лаборатории. Если проблемы возникают, то решать их можно по-разному – исправлять что-то в механизмах логирования, изменять требования к дисковой системе, да мало ли. Но сперва проблему нужно отловить.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Читабельность&lt;/b&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;А также – полезность при исследовании проблем. Вдруг мы пишем массу всего, но это никак не помогает исследовать большинство возникающих странностей. Или помогает, но могло бы быть устроено поудобней. Например, если в лог пишут одновременно несколько процессов или потоков, то легко ли понять, к какому потоку относится та или другая строка лога?&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Документация&lt;/b&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Упомянуты ли логи в документации? Описаны ли возможные/рекомендуемые настройки, советы по работе с логами? Нужна ли вообще подобная информация в документации?&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Автоматизация&lt;/b&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Приспособлены ли логи для автоматической обработки? Сможем ли мы, к примеру, собрать и сымитировать профиль реальной нагрузки на приложение, используя логи, взятые с боевой клиентской инсталляции?&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;Добавить свой вариант&lt;/b&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Я уверен, мой список далеко не полон.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Нетрудно видеть, что перечисленные области частично пересекаются друг с другом, а требования из разных областей могут противоречить друг другу. Иные области в принципе не актуальны для многих приложений, это нормально – у всех своя специфика, требования и проблемы. Я это к тому, что приведенный список – не более чем набросок, который нужно адаптировать к каждому конкретному проекту, да.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Удачи вам и интересных логов.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/03/blog-post_11.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-3399664762492837495</guid><pubDate>Wed, 09 Mar 2011 17:29:00 +0000</pubDate><atom:updated>2011-03-09T23:29:54.643+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">баги</category><category domain="http://www.blogger.com/atom/ns#">капитан О.</category><category domain="http://www.blogger.com/atom/ns#">логи</category><title>Лог для бага</title><description>&lt;div align=&quot;justify&quot;&gt;Опытным тестировщикам не нужно рассказывать о важности и пользе логов. Логи помогают исследовать проблемы, с их помощью быстрее и точнее локализуются дефекты, они могут рассказать, что происходит на самом деле (а не должно, как нам кажется, происходить). &lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Логи в чём-то подобны скриншотам – это такое же документальное и объективное свидетельство о работе приложения, с которым нет смысла спорить. Его можно обсуждать, изучать, уточнять сопутствующие условия, но факт есть факт, и отмахнуться от него не получится.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Поскольку тестировщикам по роду деятельности приходится много сталкиваться с различными проблемами в работе приложения, то мы должны уметь грамотно работать с логами. Если смотреть «снаружи», то  вся эта грамотность сводится к паре простых правил.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div align=&quot;justify&quot;&gt;&lt;strong&gt;Загнал баг без лога – увеличил энтропию&lt;/strong&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Обнаруженный и зарегистрированный баг – один из основных результатов деятельности тестировщика. Чем точнее описана и локализована проблема, тем проще потом всем жить. Сохранённый и прикрепленный к багу лог помогает повысить точность описания, особенно в случае сложных систем, когда изменение одной настройки приводит к порой неочевидным переменам в поведении программы. Тестировщик может не вспомнить или даже не знать, что для некоторых параметров приложения заданы специфические значения. Соответственно, и в баге он это не упомянет. А лог поможет восстановить, как дело было.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;strong&gt;Нашли проблему, что слоны с неба падают; написали, что автобус за углом стоит&lt;/strong&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Впрочем, мало прикрепить или &quot;процитировать&quot; в баге какой-то кусок лога. Хорошо бы еще, чтоб этот кусок имел отношение к проблеме, описываемой в баге. К сожалению, я не раз сталкивался с ситуацией, когда сохраненный лог не содержал никаких полезных данных, или, что не лучше, содержал только часть таких данных, а самое, как водится, важное и вкусное было отброшено.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;В общем, правил всего два: прикреплять лог всегда, когда проблема не абсолютно очевидна, и прикреплять нужный и полезный кусок лога, а не первый попавшийся. Всё просто.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Однако, видимо, не слишком просто, поскольку проблемы с наличием/полезностью логов возникают вновь и вновь. &lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;А что вообще нужно знать, чтобы суметь выкусить адекватную &quot;цитату&quot; из лог-файла?&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Для начала надо знать о существовании лога. Ну просто сам факт, что тестируемое приложение куда-то там что-то пишет о своей деятельности.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Второе, что потребуется узнать, – где хранятся логи.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Далее – самое интересное. Как их читать. Я прекрасно помню, как меня поначалу пугали сложные логи: ничего ведь непонятно, что куда относится и как это понимать. Тут подход простой, как с прямохождением: чем больше практики, тем лучше результат. Ну и знаниями окружающих тоже пренебрегать не стоит: те же разработчики читают же как-то те же логи, и что-то в них понимают; вот и пусть расскажут.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Еще немаловажный момент: знать, где и как настраиваются логи. Как включить/выключить логирование, как изменить уровень логирования, как настроить ротацию логов – всё это рано или поздно пригодится и поможет лучше разобраться с той или иной проблемой.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Ну и напоследок нелишне упомянуть, что в случае распределенного приложения зачастую полезно собрать логи на обеих (и более) сторонах. А если ваше приложение взаимодействует с каким-то чужим, то логи этого чужого приложения тоже могут содержать ценную информацию. &lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Такие вот довольно очевидные и неоригинальные соображения и рекомендации. &lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Удачи вам, парящих слонов и логов без ошибок.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/03/blog-post_09.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-2994728542949089161</guid><pubDate>Tue, 01 Mar 2011 07:12:00 +0000</pubDate><atom:updated>2017-09-01T22:29:43.225+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">fun</category><title>Калибан с зеркалом</title><description>&lt;div align=&quot;justify&quot;&gt;
Уточняя цитату про Калибана, перечёл предисловие к &quot;Портрету Дориана Грея&quot;. Не удержался и перетолмачил это предисловие в иных терминах. Получился своеобразный манифест о тестировании :)&lt;br /&gt;
&lt;br /&gt;
Я рекомендую сперва прочитать &lt;a href=&quot;http://lib.ru/WILDE/doriangray.txt&quot;&gt;оригинал&lt;/a&gt;, а потом уже мои вариации на тему. Впрочем,&amp;nbsp; порядок чтения не так уж важен.&lt;/div&gt;
&lt;div align=&quot;justify&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div align=&quot;justify&quot;&gt;
Итак.&amp;nbsp;&lt;/div&gt;
&lt;div align=&quot;justify&quot;&gt;
&lt;/div&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div align=&quot;justify&quot;&gt;
&lt;/div&gt;
&lt;div align=&quot;justify&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;blockquote&gt;
Тестировщик - тот, кто предоставляет информацию [о качестве].&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Раскрыть окружающим положение дел и скрыть [роль] тестировщика - вот к чему стремится тестирование.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Руководитель проекта - это тот, кто способен в доступной форме или наглядными средствами передать свои впечатления от результатов тестирования.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Высшая, как и низшая, форма руководства - один из видов воспитания.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Те, кто в результатах тестирования ищет неточности, - люди предубежденные, и притом предубежденность не делает их искренними. Это большой грех.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Те, кто способны узреть в результатах тестирования его высокую пользу, - люди культурные. Они не безнадежны.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Но избранник - тот, кто в результатах тестирования видит лишь одно: Информацию.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Нет продуктов изобилующих дефектами или избавленных от оных. Есть продукты хорошо протестированные или протестированные плохо. Вот и все.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Ненависть индустрии разработки ПО к Дефектам - это ярость Калибана, увидевшего себя в зеркале.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Ненависть индустрии разработки ПО к Требованиям - это ярость Калибана, не находящего в зеркале своего отражения.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Для тестировщика дефекты программы - лишь одна из областей его работы. Суть же тестирования в совершенном применении несовершенных средств.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Тестировщик не стремится что-то доказывать. Доказать можно даже даже неоспоримые истины.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Тестировщик не формалист. Подобная склонность тестировщика рождает непростительную мелочность подхода.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Не приписывайте тестировщику нездоровых тенденций: ему дозволено сомневаться во всем.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Идеи и Навыки для тестировщика - средства тестирования.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Дефекты и Ценности - материал для его работы.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Если говорить о форме, - прообразом всех видов тестирования является чек-лист. Если говорить о чувстве - свободный поиск.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Во всяком виде тестирования есть то, что описано в книгах, и суть.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Кто пытается постичь больше, чем описано, тот идет на риск.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
И кто раскрывает суть, идет на риск.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
В сущности, Тестирование - зеркало, отражающее того, кто в него смотрится, а вовсе не продукт.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Если результаты тестирования вызывают споры - значит, в них есть нечто важное, сложное и значительное.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Пусть руководители расходятся во мнениях - тестировщик остаётся верен себе.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Можно простить человеку, который делает нечто качественное, если только он этим не восторгается. Тому же, кто создает низкопробное, единственным оправданием служит лишь страстная любовь к&amp;nbsp;своему творению.&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
Всякое тестирование [само по себе] совершенно бесполезно.&lt;/blockquote&gt;
&lt;div align=&quot;justify&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div align=&quot;justify&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://notsocritical.blogspot.com/2011/03/blog-post.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-4761733346620126998</guid><pubDate>Wed, 16 Feb 2011 07:06:00 +0000</pubDate><atom:updated>2011-02-16T13:06:48.731+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">границы</category><category domain="http://www.blogger.com/atom/ns#">наблюдения</category><title>Границы и края</title><description>&lt;div align=&quot;justify&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Как знает практически каждый, кто занимался анализом границ, на этих самых границах - &lt;a href=&quot;http://software-testing.ru/library/testing/general-testing/1190-plakat1&quot;&gt;водятся баги&lt;/a&gt;. Там живут далеко не все баги, конечно, но все же довольно многие; недаром разбиение на классы эквивалентности – одна из базовых техник создания тестов. Впрочем, подобный подход используется постоянно в самых различных сферах деятельности. Помню, когда я изучал в университете математику, мой научный руководитель советовал, чтобы лучше понять ту или иную сущность, изучать ее поведение прежде всего в крайних, экстремальных точках. Да и в тестировании анализ границ может пригодиться не только при непосредственной работе с приложением.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Так, приглядываясь к рискам, которые могут возникнуть в работе, проще всего сперва посмотреть на крайние значения. Кстати нередко вокруг таких крайних значений ломаются копья в различных спорах на тему тестирования (и вообще разработки ПО). Несколько примеров:&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;center&quot; class=&quot;MsoNormal&quot;&gt;&lt;i&gt;Все тесты должны быть описаны так, чтоб их мог выполнить челов&lt;/i&gt;ек с улицы&lt;/div&gt;&lt;div align=&quot;center&quot; class=&quot;MsoNormal&quot;&gt;против&lt;/div&gt;&lt;div align=&quot;center&quot; class=&quot;MsoNormal&quot;&gt;&lt;i&gt;Мы тестируем, а не мараем бумажки&lt;/i&gt;&lt;i&gt;&amp;nbsp;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;&lt;br /&gt;
&lt;i&gt;Просто дайте нам приложение, и мы его проверим&lt;/i&gt;&lt;br /&gt;
против&lt;i&gt;&lt;br /&gt;
Чтобы начать тестирование, нам нужны следующие N артефактов: спецификация по стандарту XXX, …&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Тут такая странная проблема, я над ней два дня бьюсь. Нет, баг еще не забивал и с разработчиками не общался, завтра еще поисследую&lt;/i&gt;&lt;br /&gt;
против&lt;i&gt;&lt;br /&gt;
Я проблемы не исследую, пусть разработчики этим занимаются. Я описал, что видел, этого достаточно&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Подобных примеров можно привести много. Чем они удобны – так это тем, что ясно видно, какие опасности нас могут подстерегать в том или ином &lt;i&gt;крайнем&lt;/i&gt; случае. Потери времени на создание формальных и подробных документов; опасность увольнения/болезни ключевого сотрудника, обладающего неким уникальным знанием; потери времени из-за неэффективного исследования дефектов; простои из-за следования слишком формальному процессу. Все это реальные опасности, и едва ли кто-то захочет с ними столкнуться.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Поэтому подобных крайностей обычно стараются избегать: тесты документируются, но не так подробно; артефакты нужны, но можно начать тестирование, когда часть из них еще не готова; исследовать проблемы надо, но отводить на это разумное время.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Это не избавляет от проблем, конечно. В каком-то смысле даже, наоборот, добавляет. Ведь до сих пор мы работали с отрезком и двумя крайними точками на нем. В каждом конце отрезка мы довольно хорошо представляем себе, какие тут опасности, и какова степень риска. Теперь же мы провели произвольную (и зачастую не очень четкую) границу где-то внутри отрезка. Областей (классов эквивалентности :) ) стало больше, добавилась лишняя граница. Одновременно изменились и риски. Вероятно, на нашей границе определенный риск стал меньше, чем в крайней точке, однако он все еще ненулевой. Плюс к нему добавился ненулевой риск, тяготеющий к противоположной точке отрезка.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;То есть для эффективной работы нужно довольно хорошо представлять себе, в каком месте мы проводим границу, и какие опасности (баги) обитают вблизи этой границы.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Но это еще не все границы, с которыми приходится иметь дело, и, наверное, не самые интересные.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Куда сложнее работать с границами полномочий и ответственности людей и команд в проекте. Тут тоже много споров и мнений. Кто отвечает за качество? Кто должен писать юнит-тесты? Кто имеет право изменять приоритет бага? Как понять, нужно ли вносить данное улучшение или пользователям все равно? Вариантов масса. Тут уже не отрезок, а многомерное пространство; соответственно, и граница получается сложной, и проблем в ее окрестностях больше.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Однако если никакой границы не обозначено, то проблемы могут похоронить под собой весь проект – ведь каждый станет проводить границу по-своему, так, как удобно ему. Уж лучше иметь общую карту, чем десяток локальных планов местности.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;И в любом случае, – с картой ли, с планом ли – полезно иногда приглядываться к обозначенным границам и спрашивать, почему они проведены именно так. Может, стоит где-то их немного сдвинуть, и проблем станет поменьше. А может, стоит добавить новую границу. А то и забыть про какую-то из уже существующих – просто потому, что там уже никто не ходит.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Удачи вам, четких границ и нестрашных проблем вокруг них.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/02/blog-post.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-8944258852127635344</guid><pubDate>Wed, 02 Feb 2011 13:03:00 +0000</pubDate><atom:updated>2011-02-02T19:03:11.930+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">баги</category><category domain="http://www.blogger.com/atom/ns#">наблюдения</category><title>40 и 90</title><description>&lt;div align=&quot;justify&quot;&gt;Как и многие до меня, однажды я задумался о звучании чисел 40 и 90 в русском языке. Почему они - &quot;сорок&quot; и &quot;девяносто&quot;, а не &quot;четыредесять&quot; и &quot;девятьдесять&quot;? В том же английском языке все честно: forty и ninety. И у нас вроде бы должно быть так же, если сравнивать с другими числами: &quot;пятьдесят&quot;, &quot;семьдесят&quot;. Что не так с этими двумя?&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Наверняка я не знаю, конечно; разные есть версии на этот счет. Приведу те, что мне самому кажутся интересными и правдоподобными.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;40&lt;/b&gt;. В христианстве вообще и православии в частности число 40 играет заметную роль - начиная с потопа, длившегося сорок суток, и заканчивая Христом, проповедовавшим сорок&amp;nbsp;месяцев. Православие, как известно, пришло на Русь из Византии, и долгое время службы велись на греческом языке. Оттуда и позаимствовалось звучание числа &quot;четыредесять&quot;, и&amp;nbsp;вытеснило постепенно родной вариант.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;b&gt;90&lt;/b&gt;. Тут тоже без церкви дело не обошлось, но в несколько ином качестве. В течение долгих веков церкви отдавалась десятина. То есть десять из каждой сотни. Отсюда и пошло выражение &quot;девятьдесять, но сто&quot;, постепенно редуцировавшееся до знакомых &quot;девяноста&quot;.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Впрочем, речь не о числах, интересно другое. Замеченная &quot;странность мира&quot; (нелогичные названия чисел) позволила по-новому взглянуть на числа и связь их названий с историей&amp;nbsp;страны. То есть, заметив странное и покопав в этом направлении, я узнал что-то новое.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Странности мира - отличный источник знаний о мире.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Дефекты продукта - отличный источник знаний о продукте.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div align=&quot;justify&quot;&gt;Есть куча других, более официальных, что ли, источников информации о продукте. Требования и спецификации, диаграммы и собственно код; много всего интересного, что можно изучать, анализировать и сравнивать друг с другом и действительностью. Однако, это все, в том или ином смысле, - документы. А обнаруженный дефект - он живой и светится. Особенно когда дефект нетривиальный, вызывающий искреннее изумление. Код не все станут читать; требования расскажут, что мы хотим сделать, но не расскажут как. Зато дефект наглядно продемонстрирует неожиданные выверты внутренней логики приложения. Или - не очень наглядно. Но появится повод поинтересоваться, &lt;i&gt;а чего оно вообще так себя ведет&lt;/i&gt;?&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Черный ящик становится серым (или, если угодно, полупрозрачным) как раз от желания понять, что происходит. Простой и понятный дефект такого желания не вызовет - для этого требуется что-то удивительное, меняющее картину мира и представление о приложении. Ведь пока все идет &quot;нормально&quot;, особого желания лезть в кишки продукта и не возникает: и так примерно понятно, что там за логика, и вообще - неинтересно. Но когда приложение выделывает коленце, и оказывается, что &quot;в действительности все не так, как на самом&amp;nbsp;деле&quot;, - тогда-то и рождается настоящий исследователь. Он вгрызается в логи, смотрит наконец в код, зудит над ухом у разработчиков, пока ситуация не прояснится.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;С опытом, конечно, знаний о продукте становится больше, и, соответственно, удивительного поведения - меньше. Привычка - страшное дело. Хотя если порой суметь посмотреть на&amp;nbsp;давно привычное непредвзято, можно опять же узнать что-то новое. Наверное, это будет не такое открытие, как в случае искреннего изумления, скорее - интересный дополнительный&amp;nbsp;нюанс, дополняющий общую картину. Но тоже полезно. &lt;br /&gt;
&lt;br /&gt;
Полезно хотя бы потому, что расширяет область знания, а это в свою очередь помогает задавать новые вопросы, которые раньше не удалось бы сформулировать, и замечать новые&amp;nbsp;странности, которые раньше оставались невидимыми. &quot;И так по кругу, без конца и без начала.&quot;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Вообще, что неудивительно, тестировщик в некотором смысле узнает продукт через дефекты. Требования и прочие артефакты - это интересно, полезно, здорово, но несколько абстрактно и безжизненно; дефекты - вот где жизнь продукта во всей ее полноте, вот где настоящий вкус этой жизни. Для тестировщика, конечно. Для разработчика, вероятно, все иначе, и продукт это набор классов, шаблонов проектирования, хитрых и гениальных решений, принятых во время разработки - вот что вкусно. А дефекты это так, куда ж без них.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Отчасти поэтому и нужны тестировщики - они смотрят на продукт по-своему.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;В жизни, в отличие от разработки ПО, не всегда можно поймать &quot;разработчика&quot; за руку; порой отдельного автора у той или иной странности мира просто нет. Но все равно&amp;nbsp;различные &quot;дефекты&quot; окружающей среды помогают узнать что-то новое об этой самой среде. И, кстати, тенденция та же: чем дальше в лес, тем реже чистое изумление, зато больше&amp;nbsp;нюансов.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Все это, безусловно, не значит, что школа и спецификации не нужны. Очень нужны, и даже зачастую интересны. Но они все же навязывают готовое решение. А найденный дефект дает&amp;nbsp;шанс совершить собственное открытие. Может за это мы и любим тестирование.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Удачи вам, удивительных дефектов и интересных открытий.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/02/40-90.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-6821087453132364411</guid><pubDate>Thu, 27 Jan 2011 07:09:00 +0000</pubDate><atom:updated>2011-01-27T13:09:11.406+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Дорофеев</category><category domain="http://www.blogger.com/atom/ns#">наблюдения</category><category domain="http://www.blogger.com/atom/ns#">тестирование</category><title>Между роботом и обезьяной</title><description>&lt;div align=&quot;justify&quot;&gt;Есть две точки зрения на тестирование, с которыми в свое время сталкивался практически каждый тестировщик. Первая - что тестировать может&amp;nbsp;любой, ума тут не надо: сел и прокликал. Вторая - что вообще не надо тестировать людьми, надо просто автоматизировать все тесты и жить&amp;nbsp;счастливо. Эти подходы, пожалуй, несколько, гм, наивные (кто-то все равно должен эти тесты придумать и описать; кто-то должен приглядывать&amp;nbsp;за автотестами и анализировать результаты их работы, и так далее), но я сейчас не об этом. На деле, мне кажется, это одна и та же точка&amp;nbsp;зрения. В обоих случаях как минимум предполагается, что можно описать тесты таким образом, что их успешно выполнит любой - хоть студент,&amp;nbsp;хоть скрипт. Или в других терминах - хоть обезьянка, хоть робот. Года полтора назад Макс &lt;a href=&quot;http://cartmendum.livejournal.com/&quot;&gt;cartmendum&lt;/a&gt; Дорофеев устраивал доклад-состязание&amp;nbsp;&quot;&lt;a href=&quot;http://www.slideshare.net/Cartmendum/testlabs09-part-i&quot;&gt;Обезьянки&lt;/a&gt; &lt;a href=&quot;http://www.slideshare.net/Cartmendum/testlabs-part-ii&quot;&gt;против&lt;/a&gt; &lt;a href=&quot;http://www.slideshare.net/Cartmendum/test-labs09-dorofeev-m-part-iii&quot;&gt;Роботов&lt;/a&gt;&quot;; если вдруг кто не видел - рекомендую к просмотру. В докладе отлично сформулирована разница между этими&amp;nbsp;&quot;крайностями&quot;: &lt;i&gt;&quot;Обезьянки умеют немножко смотреть по сторонам. Роботы не могут смотреть по сторонам. Они могут смотреть в точку, но быстро и долго&quot;&lt;/i&gt;. Это существенное различие, которое позволяет в разных ситуациях выигрывать то Обезьянкам, то Роботам.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;На самом же деле ни Обезьянки, ни Роботы сами по себе практически ничего не умеют. Они не могут придумывать тест-кейсы и программировать роботов. Они способны учитывать только формальный критерий, описанный в тест-кейсе или скрипте, они не обращают внимания на контекст. Ну, почти не обращают: Обезьянки все-таки немножко глядят по сторонам и иногда замечают &lt;i&gt;странное&lt;/i&gt; не предусмотренное тест-кейсами. Они не умеют задавать вопросы и разговаривать (хотя бы с гуглом). Они не стремятся понимать, как работает приложение, и почему после нажатия на кнопку с неба падает (или &lt;i&gt;не&lt;/i&gt; падает) банан. Они не отвечают за результат. Чаще всего они не могут сообщить дополнительные сведения, если что-то сломалось. Они знают только о приложении и не работают с остальными составляющими продукта. Они ничего не помнят. У них нет своих суждений, предположений и ожиданий; есть алгоритм и результаты - ожидаемый и реальный.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Коротко говоря - они не умеют думать. Роботы - совсем, Обезьянки - почти. И в этом смысле тестировщик круче и Обезьянки, и Робота в равной&amp;nbsp;степени. Ну разве что Робот быстрее кликает. Зато тестировщик способен понять, что тут кликать вообще незачем.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Из Обезьянок со временем иногда вырастают тестировщики; это, наверное, один из самых распространенных путей в тестирование ПО. И ключевая&amp;nbsp;особенность, которая позволяет Обезьянке превратиться во взрослого тестировщика - та самая способность к наблюдению, способность немножко&amp;nbsp;смотреть по сторонам. В значительной степени это основное дело тестировщика, а всякие скрипты и Роботы нужны только для того, чтобы на&amp;nbsp;наблюдения и их интерпретацию оставалось больше времени. Пусть автомат выполняет рутинные действия. Мы посмотрим, что у него в итоге&amp;nbsp;получится, и сделаем выводы.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Если перефразировать слова Макса, то можно сказать, что &lt;b&gt;тестировщик смотрит по сторонам, и делает это быстро и долго&lt;/b&gt;. Нужно смотреть&amp;nbsp;&quot;быстро&quot;, чтобы замечать больше дефектов (и не только в продукте :)). Нужно смотреть &quot;долго&quot;, то есть постоянно, на всех этапах разработки.&amp;nbsp;Не случайно одна из главных бед тестировщика - &quot;замыленый взгляд&quot;.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Удачи вам, верных Роботов, смышленых Обезьянок и ясного взгляда.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/01/blog-post_27.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-2603690925303577496</guid><pubDate>Mon, 17 Jan 2011 07:21:00 +0000</pubDate><atom:updated>2011-01-17T13:21:13.353+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">документация</category><category domain="http://www.blogger.com/atom/ns#">наблюдения</category><category domain="http://www.blogger.com/atom/ns#">тестирование</category><category domain="http://www.blogger.com/atom/ns#">техники</category><title>О тестировании документации</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYu3zcvagA17Ye4yuQ6n0jO4h634EFwEZB08ZuVhhCxbi3xqoV0-0fmuvzb16EHW6i6W_WvrqYiyyuG_sx49zOEVJpGxb98nY6qPIXW8rGMiZPuxhU3yhA2LTdWO6YbzM0SO9xwaFLE-c/s1600/manual3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYu3zcvagA17Ye4yuQ6n0jO4h634EFwEZB08ZuVhhCxbi3xqoV0-0fmuvzb16EHW6i6W_WvrqYiyyuG_sx49zOEVJpGxb98nY6qPIXW8rGMiZPuxhU3yhA2LTdWO6YbzM0SO9xwaFLE-c/s1600/manual3.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div align=&quot;right&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Documentation is like sex: when it is good,&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div align=&quot;right&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;it is very, very good; and when it is bad,&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div align=&quot;right&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;it is better than nothing.&lt;/span&gt;&lt;/div&gt;&lt;div align=&quot;right&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Dick Brandon&lt;/span&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Когда заходит речь о тестировании, обычно обсуждается тестирование приложения в том или ином виде. Функциональное тестирование, тестирование безопасности, нагрузочное тестирование, тестирование требований - все это относится к приложению. Это действительно важные аспекты поведения продукта, и количество уделяемого им внимания вполне обосновано. Тестирование документации, поставляемой вместе с приложением (неважно, каким именно способом - в виде книжки, PDF файла или базы знаний на сайте), нередко проводится по остаточному принципу. С одной стороны этот подход делает актуальной фразу вынесенную в эпиграф. С другой - соображения, высказанные в этой фразе могут стать причиной, почему документация так плоха.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Отбросим случай, когда документация не тестируется вообще никогда и никем. Это крайний и маловероятный вариант, к тому же обсуждать тут особо нечего. Как мы тестируем документацию, если уж до этого дошли руки?&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;Обычно документация не обновляется вся целиком. Появляются новые возможности в продукте, их описание добавляют в документацию, а потом назначенный человек (или несколько) проверяет, что &quot;все в порядке&quot;. Это неплохой вариант, когда проверку выполняет опытный человек, хорошо знакомый с продуктом и прочим контекстом (предметной областью; языком, на котором написана документация; целевой аудиторией и так далее). Проблема в том, что часто нет никаких формальных подходов к выполнению таких проверок. Человек читает документацию, по сути - проверяя, не зацепится ли взгляд за что-то странное. Зацепился - хорошо: обсудил с окружающими, открыл баг. Не зацепился - никаких гарантий, что проблем действительно нет.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;Порой чтение документации поручают неофитам. Таким образом, они, с одной стороны знакомятся с продуктом, с другой - опять же тестируют мануалы, пусть и довольно поверхностно, на уровне опечаток и грамматических ошибок.&lt;br /&gt;
&lt;br /&gt;
Иногда происходят изменения, затрагивающие всю документацию. Изменился интерфейс приложения, и нужно&amp;nbsp;обновить все скриншоты. Изменилось название продукта, и нужно его поправить везде, где оно встречается.&amp;nbsp;Изменилась структура самой документации. В этом случае, обычно, проверяющий сосредотачивается на конкретном изменении, о котором идет речь, и связанных с ним опасностях, оставляя в стороне прочие аспекты.&amp;nbsp;Например, если название продукта изменилось с &quot;Го&quot; на &quot;Шахматы&quot;, стоить убедиться, что в документации не&amp;nbsp;появилось слов вроде &quot;до&lt;i&gt;шахматы&lt;/i&gt;вор&quot;. Смысл же предложений в этом случае проверять необязательно.&lt;br /&gt;
&lt;br /&gt;
В целом, проблемы с тестированием документации - те же, что и с тестированием приложения. Тестировать должен&amp;nbsp;опытный и подготовленный человек; нередко тестировщик - не тот, кто должен решать, что должно присутствовать&amp;nbsp;в документации, а что нет; для эффективного тестирования нужен какой-то базис, требования - чего мы вообще&amp;nbsp;ожидаем от документации; и т.п. &lt;br /&gt;
&lt;br /&gt;
Важное умение, как и при тестировании приложения, - поставить себя на место пользователя, попытаться понять,&amp;nbsp;чего он ждет от документации. Не от хорошей же жизни он полез читать эти талмуды. Одна из классических&amp;nbsp;проблем документации: она написана программистами в привычной им манере. Программисты привыкли к описаниям того или иного языка программирования, когда для каждой функции описано, что она делает, какие параметры&amp;nbsp;принимает на вход, что отдает на выход. Этот же подход переносится и в мануалы создаваемого продукта.&amp;nbsp;Описаны параметры, которые можно установить, но непонятно, как это все работает вместе. Нередко&amp;nbsp;пользователю нужно описание вариантов использования (use case) - что, где и в какой последовательности он должен сделать, чтобы получить нужный результат. Если вместо этого он увидит, пусть даже подробное, описание&amp;nbsp;параметров, далеко не факт, что он сумеет достичь цели. Недаром на форумах так много вопросов, связанных с&amp;nbsp;простейшими функциями приложений.&lt;br /&gt;
&lt;br /&gt;
И все же основная проблема, на мой взгляд, связана с требованиями и критериями. Чего мы ждем от документации&amp;nbsp;и по каким критериям мы решаем, есть дефекты в тексте или нет? Если требования и критерии не заданы, то&amp;nbsp;можно (или придется) определять их в процессе тестирования. Главное, чтобы все заинтересованные стороны были&amp;nbsp;с ними согласны. &lt;br /&gt;
&lt;br /&gt;
А вообще, не преувеличиваю ли я проблему? Документация должна рассказать пользователю, что и как делает&amp;nbsp;продукт. Чего тут непонятного? Садимся и пишем. &lt;br /&gt;
&lt;br /&gt;
Нюанс в том, что важно не только, &lt;i&gt;что&lt;/i&gt; написано в документации, но и &lt;i&gt;как&lt;/i&gt; это сделано. Манера изложения,&amp;nbsp;форматирование текста - почти также важны, как и собственно информация о работе продукта. Перечислю некоторые аспекты, на которые, на мой взгляд, стоит обращать внимание при тестировании документации (хотя бы иногда).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Верность и полнота информации&lt;/b&gt;. Тут все понятно. Все, что написано в мануалах, должно соответствовать&amp;nbsp;действительности. По возможности, описание должно быть полным; пользователю может понадобиться информация о&amp;nbsp;любой из возможностей продукта. Более того, если в документации не написано о каких-то возможностях, то&amp;nbsp;пользователь может никогда о них и не узнать (разве что случайно наткнется на них, работая с приложением).&amp;nbsp;Документация не должна содержать устаревшей информации. Возможны исключения, например описание API может включать упоминания устаревших функций с соответсвующими пометками. Но &quot;в среднем по больнице&quot; устаревшие и&amp;nbsp;неактуальные данные о работе приложения, оставленные в документации, могут стоить пользователю кучу времени&amp;nbsp;и денег.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Наличие дублирующейся информации&lt;/b&gt;. В сложных продуктах одни и те же длинные, подробные инструкции могут&amp;nbsp;понадобиться в разных главах документации. Тут стоит решить, что считать правильным, - описывать все в&amp;nbsp;подробностях везде, где понадобилось, или описать один раз, и ссылаться на это описание из других глав. У&amp;nbsp;обоих подходов есть плюсы и минусы. В первом случае, внося изменения, мы можем забыть внести их в одну из&amp;nbsp;глав. Во втором мы вынуждаем пользователя блуждать по документации туда-сюда, что зачастую не очень удобно. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Удобство навигации&lt;/b&gt;. В идеале пользователь вообще не должен задумываться, как найти нужные данные.&amp;nbsp;Документация должна сама &quot;привести&quot; его к ним. Это, конечно, труднопредставимое счастье, но позаботьтесь хотя бы о понятных ссылках между частями; о структуре содержания; об алфавитном указателе. Если документация оформлена&amp;nbsp;в виде PDF документа, и он содержит закладки (bookmarks), то проследите, чтоб панель с закладками показывалась сразу при открытии документа. Не всякий пользователь каждый день читает PDFки - облегчите ему&amp;nbsp;жизнь. Вообще, подумайте, как вы сами ищете информацию в мануалах, и как этот процесс можно ускорить или&amp;nbsp;упростить.&lt;br /&gt;
&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;b&gt;Соблюдение политик документации&lt;/b&gt;. Обычно в документации декларируются некие конвенции оформления текста.&amp;nbsp;Названия кнопок мы пишем так, консольные команды по-другому, важные замечания - по-третьему и т.д. Если уж&amp;nbsp;подобные правила введены, то стоит проследить, чтобы они действительно выполнялись. В противном случае&amp;nbsp;документация как минимум выглядит неряшливо, а как максимум запутывает пользователя.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Структурированность&lt;/b&gt;. Легко ли взгляд находит важные места в документации? Если вы читали документ,&amp;nbsp;отвернулись на пару секунд, а затем вернулись к документу - как быстро вы находите место, на котором&amp;nbsp;остановились? Структурирован ли текст или выглядит сплошным массивом букв и знаков препинания? Это не очень&amp;nbsp;простой пункт; многие чувствуют и могут заявить, что читать неудобно, но &lt;i&gt;почему&lt;/i&gt; неудобно - сформулировать&amp;nbsp;трудно. Тут важную роль играют шрифты, межстрочные интервалы и другие нюансы оформления. Если не получается&amp;nbsp;найти причину неудобства, то можно попробовать хотя бы описать как вам неудобно читать, что за проблемы&amp;nbsp;возникают при чтении. Это тоже полезная информация в данном случае.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Расшифровка терминов&lt;/b&gt;. Если документация содержит какие-то специфичные термины и аббривеатуры, то необходимо&amp;nbsp;убедиться, что соответствующие определения и расшифровки тоже присутствуют.&amp;nbsp;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;
&lt;b&gt;Единообразие и непротиворечивость&lt;/b&gt;. Термины должны использоваться одинаково во всех документах и главах. Избегайте слишком размытых понятий, имеющих много трактовок и смыслов. И уж конечно не называйте разные сущности продукта одними и теми же (или очень похожими) терминами.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Копирование текста&lt;/b&gt;. Тут я имею в виду случаи, когда пользователь хочет, например, скопировать кусок текста из документации. Это может быть какая-то информация, которую он хочет сохранить отдельно, или&amp;nbsp;код скрипта, который ему нужно выполнить, или какой-то список, да мало ли что. Что произойдет при&amp;nbsp;копировании? Сохранятся ли переносы между строками? Если копируемый текст размещался на нескольких&amp;nbsp;страницах, были ли скопированы коллонтитулы страниц? Не содержит ли скопированный список непечатаемых&amp;nbsp;символов? Не потерялись ли они при копировании? Можно ли вообще скопировать данные из документации?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Понятность для целевой аудитории&lt;/b&gt;. Важно понимать, &lt;i&gt;кто&lt;/i&gt; будет читать документацию. Справка блог-сервиса&amp;nbsp;для программистов может очень сильно отличаться от справки блог-сервиса для молодых мам. Нужно знать целевую&amp;nbsp;аудиторию и писать документацию в адекватном стиле. Иначе документы могут оказаться бесполезными.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Правильность языка&lt;/b&gt;. Документация должна быть написана грамотно и по всем правилам языка. Если этот язык -&amp;nbsp;иностранный, то имеет смысл привлечь к проверке носителя языка, желательно - знакомого с предметной областью.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Разделение ролей&lt;/b&gt;. Если продукт предусматривает различные роли и уровни доступа, и для каждого из них пишется&amp;nbsp;отдельный документ, описывающий работу с системой, то стоит убедиться, что документ, предназначенный для&amp;nbsp;одного уровня не содержит информации, позволяющий узнать что-то специфичное и важное о более&amp;nbsp;привилигерованном уровне. Например, рядовому пользователю необязательно знать, как конфигурируется система.&amp;nbsp;Понятно, что если он сильно захочет, то скорее всего найдет соответствующий документ. Но, по крайней мере,&amp;nbsp;случайно не наткнется. К тому же лишняя информация, не относящаяся к его уровню доступа, может его запутать. &lt;br /&gt;
&lt;br /&gt;
Ого, уже одиннадцать пунктов. А казалось бы, всего лишь тестирование документации, ничего сложного.&lt;br /&gt;
&lt;br /&gt;
Надеюсь, документация к вашему продукту уже идеальна, и все вышеизложенное к вам не относится.&lt;br /&gt;
&lt;br /&gt;
Удачи в тестировании!&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/01/blog-post.html</link><author>noreply@blogger.com (Pavel )</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYu3zcvagA17Ye4yuQ6n0jO4h634EFwEZB08ZuVhhCxbi3xqoV0-0fmuvzb16EHW6i6W_WvrqYiyyuG_sx49zOEVJpGxb98nY6qPIXW8rGMiZPuxhU3yhA2LTdWO6YbzM0SO9xwaFLE-c/s72-c/manual3.jpg" height="72" width="72"/><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-688946692000677245</guid><pubDate>Thu, 13 Jan 2011 06:40:00 +0000</pubDate><atom:updated>2011-01-13T12:40:50.502+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Bolton</category><category domain="http://www.blogger.com/atom/ns#">оценки</category><category domain="http://www.blogger.com/atom/ns#">переводы</category><category domain="http://www.blogger.com/atom/ns#">планирование</category><category domain="http://www.blogger.com/atom/ns#">тестирование</category><title>М.Болтон: Оценка проекта и Черные Лебеди. Часть 5. Оценка тестирования.</title><description>&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;yellow&quot;&gt;Вольный перевод статьи Майкла Болтона &lt;b&gt;&lt;a href=&quot;http://www.developsense.com/blog/2010/10/project-estimation-and-black-swans-part-5-test-estimation/&quot;&gt;Project Estimation and Black Swans (Part 5): Test Estimation&lt;/a&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В этой серии статей я говорил об оценке проектов. Но я тестировщик, и вы, вероятно, тоже, раз уж читаете этот блог; ну или, по меньшей мере, вы интересуетесь тестированием. Итак, все это выглядит занятно по отношению к оценке проектов, но какое значение это имеет к оценке проектов тестирования?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Давайте действовать как тестировщики – будем задавать вопросы.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Существует ли вообще такая штука, как &lt;i&gt;проект тестирования&lt;/i&gt;? В частности, может ли проект тестирования существовать независимо от проекта разработки?&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Не бывает &quot;проектов тестирования&quot; абсолютно независимых от каких-либо других проектов. Всегда есть клиент, обычно есть и другие заинтересованные лица. Всегда происходит передача информации, общей или специфичной. Всегда уже выполнена некоторая работа, и кто-то хочет узнать, что получилось. Всегда есть тестировщик или несколько тестировщиков. Всегда есть какие-то временные ограничения -&amp;nbsp; конец итерации в Agile, контрольная точка проекта, назначенная дата поставки или некое представление о том, когда проект должен завершиться. В очерченных временных рамках проводится минимум один, а обычно - несколько циклов тестирования. Также имеются риски, которые тестирование пытается снизить, изыскивая соответствующие данные и передавая их заинтересованным лицам. Время от времени - постоянно или в конце цикла - тестировщики сообщают заказчику обнаруженные сведения.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Проектом может быть периодический обзор продукта. Проектом может быть судебная тяжба, когда команда юристов пытается доказать, что продукт не удовлетворяет требованиям контракта. Проектом может быть научная или промышленная программа исследований, в которой ключевую роль играет ПО. В общем, проект - это некоторый вид разработки ПО (неважно, идет ли речь о массовом коммерческом ПО, об онлайновом сервисе, или об ИТ-поддержке внутри компании). Проект может модифицировать существующий продукт или включать большое количество нового кода. Неважно, о чем идет речь; тестирование само по себе - &lt;i&gt;не проект&lt;/i&gt;, тестирование - часть проекта; часть, которая &lt;i&gt;поставляет информацию&lt;/i&gt; проекту. Тестирование не происходит отдельно, оно часть &lt;i&gt;системы&lt;/i&gt;. Тестирование наблюдает за результатами работы системы, частью которой оно является, и скармливает эту информацию обратно системе. И тестирование - только один из нескольких механизмов получения обратной связи в системе.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Хотя тестирование может быть организовано в виде циклов, было бы странно считать его чем-то отдельным от остального проекта, так же как было бы странно думать о &lt;i&gt;наблюдении&lt;/i&gt; (смотрении, seeing) как об отдельной части вашего дня. Люди говорят много странного, но едва ли вы слышали, чтобы кто-то сказал: &quot;Мне нужно закончить работу, а потом я начну смотреть&quot;; вы почти никогда не спрашиваете: &quot;Когда вы планируете завершить наблюдение?&quot; Бывают моменты, когда вы уделяете глазам и наблюдению больше внимания - когда вы управляете машиной или режете овощи или наблюдаете за ребенком, играющим в захламленной комнате. Но даже когда вы сконцентрированы на наблюдении, оно происходит в контексте какой-то иной деятельности (и &lt;i&gt;обслуживает&lt;/i&gt; эту деятельность).&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Имеет ли смысл термин &quot;фаза тестирования&quot;?&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Многие организации (например, не использующие Agile) делят проект на две обособленных части: &quot;фазу разработки&quot; и &quot;фазу тестирования&quot;. Мой коллега Джеймс Бах (&lt;a href=&quot;http://www.satisfice.com/&quot;&gt;James Bach&lt;/a&gt;) заметил интересное противоречие в таком подходе.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Что происходит в &quot;фазе разработки&quot;? &lt;i&gt;Программисты программируют&lt;/i&gt;. Программирование может включать в себя массу активностей, таких как исследование, проектирование, экспериментирование, создание прототипов, написание кода, блочное тестирование (unit testing) (а в случае TDD тест для блока создается до написания кода, который будет проверяться), интеграционное тестирование, отладка, рефакторинг. А что делают тестировщики во время &quot;фазы разработки&quot;? &lt;i&gt;Тестировщики тестируют&lt;/i&gt;. Говоря точнее, они занимаются обзором, планированием, проектированием тестов, созданием инструментов, генерированием данных, настройкой окружения, выполнением интеграционных тестов сравнительно низкого уровня и даже выполнением высокоуровневых системных тестов. Все эти действия можно включить в категорию &quot;тестирование&quot;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Что происходит в &quot;фазе тестирования&quot;? &lt;i&gt;Программисты по-прежнему программируют, а тестировщики по-прежнему тестируют&lt;/i&gt;. Главное отличие между этими двумя фазами - в фокусе работы программистов: они прекращают добавлять новую функциональность, а вместо этого занимаются починкой найденных проблем. В первой фазе программисты уделяют больше внимания разработке новых функций; во второй - починке. Исходя из этого, Джеймс считает, что &quot;фазу тестирования&quot; правильнее называть &quot;фазой &lt;i&gt;починки&lt;/i&gt;&quot; (fixing phase). Если мы всерьез рассмотрим это предложение, изменится суть некоторых часто возникающих вопросов. Замените слово &quot;тестировать&quot; словом &quot;чинить&quot;: &quot;Сколько времени вам нужно на &lt;i&gt;починку&lt;/i&gt; этого продукта?&quot;, &quot;Когда планируется завершить &lt;i&gt;починку&lt;/i&gt;?&quot;, &quot;А мы можем просто автоматизировать &lt;i&gt;починку&lt;/i&gt;?&quot;, &quot;Стоит ли начинать &lt;i&gt;починку&lt;/i&gt; на ранних стадиях проекта?&quot;, &quot;Почему клиент нашел сломанную функциональность? Вы что, не &lt;i&gt;чинили&lt;/i&gt; ее?&quot; И должны ли мы &lt;i&gt;обращаться к тестировщикам&lt;/i&gt; с такими вопросами?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Как отмечает Джеймс, никто никогда не откладывал выпуск продукта просто потому, что еще было что потестировать. Продукты задерживаются из опасения, что &lt;i&gt;разработчикам&lt;/i&gt; стоило бы сделать еще что-то до релиза. Тестирование можно остановить, как только владелец продукта (product owner) убедился, что имеет достаточно информации, чтобы разрешить поставку продукта. В таком случае, вопрос к тестировщикам &quot;Когда &amp;nbsp;&lt;i&gt;вы&lt;/i&gt; собираетесь завершить тестирование?&quot; превращается в вопрос к владельцу продукта: &quot;Когда &lt;i&gt;я&lt;/i&gt; поверю, что имею достаточно данных для принятия ответственного бизнес-решения?&quot; В такой момент владельцу продукта стоит [в разумной степени] скептически смотреть на чьи-то заявления, что они завершили тестирование.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Вопрос &quot;Когда я получу достаточно данных&quot; может показаться трудным. Это действительно трудный вопрос. Когда я работал программным менеджером (program manager) в коммерческой компании производящей ПО, я не мог ответить на этот вопрос, пока данные не были упорядочены. Чтобы хорошо ответить на него, нужно учесть очень много аспектов: технические данные, технические риски, покрытие тестов, качество используемых моделей, качество используемых оракулов, бизнес-данные, бизнес-риски, представление о достаточности, решительность... Большинство этих переменных нужно собрать и оценить и принять решение, и сделать все это в голове одного человека; &lt;i&gt;и этот человек&amp;nbsp; - &amp;nbsp;не тестировщик. Этот человек - владелец продукта&lt;/i&gt;. Оценка переменных и готовность к поставке меняются каждый момент. Конечное состояние переменных и конечное решение о дате поставки находятся где-то в будущем. Спрашивать тестировщика &quot;Когда вы собираетесь закончить тестирование?&quot; все равно, что спрашивать глаза &quot;Когда вы собираетесь закончить наблюдение?&quot; Глаза продолжают разглядывать окружающую среду, поставляя данные одновременно с прочими органами чувств, пока мозг не примет решение. Подобным образом, тестировщики продолжают тестировать, поставляя данные одновременно с другими участниками проекта, пока владелец продукта не примет решение о поставке. Ни тестировщик, ни глаза не могут в одиночку ответить подходящим образом на вопрос &quot;Когда вы планируете закончить?&quot;; это не их зона ответственности. До принятия решения мозг (выборочно) учитывает массу данных, получаемых от глаз и других органов чувств. Те из нас, кто пожирал глазами стол с десертами, знают, что бывает, если разрешить глазам принимать решения. Более того, если существует проблема, едва ли глаза смогут ее решить.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Некоторые верят, что могут спрогнозировать, когда завершится тестирование, разбивая тестирование на измеримые части, такие как варианты тестирования (test cases) или шаги тестирования. По-моему, это все равно, что использовать &quot;варианты наблюдения&quot; или &quot;шаги наблюдения&quot;, что приводит нас к следующему вопросу:&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Можно ли измерить длительность &quot;проекта тестирования&quot; подсчитав &quot;варианты тестирования&quot; или &quot;шаги тестирования&quot;?&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Недавно на конференции я слушал выступление, в котором докладчица представила способ оценить, когда завершится тестирование. По сути, он сводился к следующей формуле: разбейте тестирование на варианты тестирования (test cases), разбейте варианты тестирования на шаги тестирования, измерьте длительность нескольких шагов тестирования, вычислите среднее (или хоть что-то) чтобы понять, сколько времени занимает один шаг тестирования, а затем умножьте полученное время на число шагов. Вуаля! Оценка готова.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Только одна проблемка: основа вычисления не была объяснена. Что такое &lt;i&gt;шаг тестирования&lt;/i&gt;? Это физическое действие? Похоже, докладчица предполагала, что тестировщик переходит к следующему шагу, когда он начинает подавать новые входные данные (input action). Несомненно, не все входные данные одинаковы. Что считается подачей входных данных? Клик мышкой? Движение мышкой? Ввод каких-то данных в поле? В набор полей с последующим нажатием клавиши Enter? Включается ли наблюдение (несколько наблюдений) в шаг тестирования? А оценка результата (&lt;span lang=&quot;EN-US&quot;&gt;evaluation&lt;/span&gt;)? Что происходит, когда человек замечает странность и начинает размышлять? Что происходит, когда во время выполнения теста тестировщик замечает опасность и решает поискать соответствующие проблемы? Что происходит с единицей измерения, когда тестировщик находит проблему и начинает исследовать и описывать ее?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Докладчица признала проблему, сказав, что шаг может занимать как пять секунд, так и половину дня. Предел погрешности 3000 к одному по отношению к шагу - элементу, на котором основана оценка, - делает надежность оценки сомнительной. Кроме того, предел погрешности, даже столь огромный, ортогонален к гораздо более серьезной проблеме с этим подходом к оценке.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Подлинное тестирование - это не монотонное и/или повторяющееся выполнение сценариев (которое в моем сообществе называют &lt;a href=&quot;http://www.developsense.com/blog/2009/08/testing-vs-checking/&quot;&gt;проверкой&lt;/a&gt;). Тестирование - это &lt;i&gt;исследование&lt;/i&gt; кода, компьютеров, людей, ценностей, рисков и отношений между ними. Исследование включает в себя &lt;a href=&quot;http://www.developsense.com/blog/2010/03/looping-and-branching-in-exploratory-testing/&quot;&gt;периоды изучения&lt;/a&gt;, эксперименты, поиск, открытия, интерпретацию результатов и обучение. Вариативность и приспособление являются &lt;i&gt;сутью&lt;/i&gt; этого процесса. Выполнение тестов включает в себя отражение того, что только что случилось, возвращение на несколько шагов назад, повторение или изменение шагов во время формулировки проблемы или выполнения наблюдений. Исследование не может выполняться по заранее описанному. Исследование в соответствии с заранее описанными шагами - &lt;i&gt;вообще не исследование&lt;/i&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Во время исследования многие возникающие вопросы - начиная с самого первого - могут привести к ответу, который пустит под откос все ваши предубеждения. Во время исследования нужно обнажать, оспаривать и уточнять предположения. Во время исследования ответ на последний заданный вопрос может оказаться важнее, чем все сделанное до этого. Если мы стремимся к качественному исследованию, мы не можем полагать, что самые критичные риски уже обнаружены. Если мы стремимся к качественному исследованию, нам не помогут механические действия (Если возникают &quot;механические&quot; вопросы, давайте ставить их перед автоматическими проверками низкого уровня. И давайте делать это &lt;a href=&quot;http://www.developsense.com/blog/2009/11/merely-checking-or-merely-testing/&quot;&gt;умело&lt;/a&gt;).&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Если мы не можем полагаться на подсчет вариантов тестирования, как мы можем оценить время, необходимое для тестирования?&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Существует множество активностей, которые не попадают в модели, так как они неотделимы от проекта, в котором происходят. Возвращаясь к аналогии Джеймса Баха, - никто не оценивает фазу смотрения-в-окно во время автомобильной поездки. Вы можете оценить длительность поездки, но в окно вы смотрите постоянно, пока не приедете в пункт назначения. Глядя в окно, водитель оценивает, правильно ли он едет, и достиг ли он пункта назначения. Никто не оценивает фазу обслуживания клиентов во время отдыха в отеле. Вы можете оценить длительность постоя, но обслуживание клиентов (если оно хорошее) доступно непрерывно, пока вы не покинете отель. Никто не оценивает &quot;фазу управления&quot; проекта разработки ПО. Вы можете оценить, сколько времени уйдет на разработку, но управление (когда оно хорошее) происходит постоянно вплоть до выпуска продукта. Наблюдения и действия руководителей (руководителя разработки, руководителя техподдержки, руководителя отдела документации, и - да, руководителя тестирования) информируют владельца продукта о том, насколько продукт готов к поставке. &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Оценка тестирования становится проблемой, только если кто-то ошибочно рассматривает тестирование как отдельную активность или фазу, а не как непрерывное исследование, продолжающееся в течение всего проекта. &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Мой начальник говорит, что я должен предоставить оценку, что мне делать?&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В начале проекта мы знаем очень мало по сравнению с тем, что мы узнаем позже. Мы не можем знать все, что нам понадобится узнать. В начале проекта мы не в состоянии узнать, будет ли проект выполняться по плану, избежав встречи с Черным Лебедем или стаей Черных Лебедей. Поэтому попробуйте мыслить не в терминах оценки тестирования, а в терминах &lt;i&gt;стратегии, логистики, переговоров&lt;/i&gt; и &lt;i&gt;улучшений&lt;/i&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Наша &lt;i&gt;стратегия&lt;/i&gt; - это набор идей, на базе которых мы строим тесты. Эти идеи возникают из &lt;a href=&quot;http://www.developsense.com/articles/2005-09-StayingOnTheCriticalPath.pdf&quot;&gt;окружения проекта (контекста)&lt;/a&gt;; из критерия качества, который могут оценить пользователи и другие лица; из &lt;a href=&quot;http://www.developsense.com/articles/2005-10-ElementalModels.pdf&quot;&gt;тестового покрытия&lt;/a&gt;, которое мы хотим получить; из &lt;a href=&quot;http://www.developsense.com/articles/2006-06-TestPatterns.pdf&quot;&gt;техник тестирования&lt;/a&gt;, которые мы выбираем. (В качестве примера основы для разработки стратегии можно рассмотреть эвристическую модель стратегии тестирования, &lt;a href=&quot;http://www.satisfice.com/tools/satisfice-tsm-4p.pdf&quot;&gt;Heuristic Test Strategy Model,&lt;/a&gt; которую мы используем в Rapid Testing). &lt;i&gt;Логистика&lt;/i&gt; - это идеи, направляющие применение людей, оборудования, инструментов и других ресурсов для осуществления нашей стратегии. Сложите стратегию и логистику вместе - и получите &lt;i&gt;план&lt;/i&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Поскольку мы работаем с - и, что важнее, &lt;i&gt;для&lt;/i&gt; - клиента, то цели, расписание и бюджет клиента в значительной степени определяют выбор элементов нашей стратегии и логистики. Отчасти этот выбор определяется историческими данными и текущим состоянием дел. К примеру, многие проекты разрабатываются в организациях, где уже есть программисты и тестировщики; многие проекты расширяют функциональность существующих продуктов или услуг. Порой стратегия проекта основывается на прогнозах, или ожиданиях, или надеждах. Например, когда владелец продукта заранее назначает желаемую дату поставки продукта. Для построения предварительного плана тестирования мы используем всю доступную информацию. Клиенту может понравиться наш план, а может и нет. В любом случае, при эффективных взаимоотношениях ни одна из сторон не может навязывать сроки. В противном случае мы ведем &lt;i&gt;переговоры&lt;/i&gt;. Многие наши предубеждения (и предубеждения клиента) могут оказаться неверными или измениться по ходу проекта. Это нормально; с самого начала окружение проекта, отличное тестирование, непрерывный поток отчетов и взаимодействие помогают нам выявить необоснованные допущения и новые опасные идеи. Если мы трактуем тестирование как нечто, происходящее непрерывно и одновременно с разработкой, а разработка происходит циклически, обеспечивая нечто подобное пульсу проекта, то у нас есть возможность пересматривать и уточнять наши планы.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Итак: &lt;i&gt;вместо попыток оценить &quot;фазу тестирования&quot; &lt;a href=&quot;http://www.developsense.com/blog/2009/08/test-estimation-is-really-negotiation/&quot;&gt;договаривайтесь&lt;/a&gt; и уточняйте свою стратегию тестирования в контексте всего проекта&lt;/i&gt;. &lt;a href=&quot;http://www.developsense.com/blog/2007/01/test-project-estimation-rapid-way/&quot;&gt;Вам в любом случае придется это делать&lt;/a&gt;, не так ли?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Но мое руководство любит оценки! Может, есть хоть что-то, что можно оценить?&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Нет смысла оценивать затраты на тестирование вне контекста всего проекта, но мы &lt;i&gt;можем&lt;/i&gt; оценивать их в рамках цикла разработки. Базовая идея основана на &lt;a href=&quot;http://www.satisfice.com/sbtm&quot;&gt;управлении сессионным тестированием&lt;/a&gt; - разработанном Джеймсом и Джоном Бахами подходе к планированию, оценке, управлению и измерению исследовательского тестирования в обстоятельствах, требующих высокого уровня отчетности.&amp;nbsp; Ключевые факторы: &lt;/div&gt;&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;ограниченные по времени (от 45 минут до двух часов      пятнадцати минут) &lt;i&gt;сессии&lt;/i&gt;      непрерывного тестирования; нормой считаются 90-минутные сессии;&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;i&gt;области      покрытия&lt;/i&gt; тестами - обычно, это функции продукта, тестированию которых      мы намерены уделить некоторое время;&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;i&gt;активности&lt;/i&gt;      - такие как исследование, обзор, проектирование тестов, генерирование данных,      создание инструментов и перепроверка - на которые мы также намерены      выделить время;&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;i&gt;контракт&lt;/i&gt;      в виде одного-трех предложений, описывающих цели и задающих фокус для      отдельной сессии тестирования;&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;i&gt;разбор&lt;/i&gt;,      во время которого тестировщик и его начальник обсуждают результаты сессии;&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;легко обозримые результаты в виде &lt;i&gt;таблицы сессий&lt;/i&gt;, которые задают      основу для разбора, могут быть проанализированы и разобраны с помощью      скриптов; &lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;margin-left: 18pt; text-align: justify;&quot;&gt;и, опционально,&lt;/div&gt;&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;снимки экранов, &lt;i&gt;записанные      &lt;/i&gt;во время сессии, если может потребоваться детальное ретроспективное      исследование;&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;i&gt;метрики&lt;/i&gt;,      цель которых - понять, сколько времени ушло на создание и выполнение      тестов (активности, обеспечивающие тестовое покрытие), а сколько на      исследование проблем и создание отчетов (активности, прерывающие создание      тестового покрытия).&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Ограничение по времени позволяет выполнить &lt;i&gt;неточную&lt;/i&gt;, но достаточно &lt;i&gt;верную&lt;/i&gt; оценку и подсчет. (В чем разница? Если я напишу, что текущее время и дата - 9:43:02.1872 утра 23 января 1953 года, то это очень &lt;i&gt;точное&lt;/i&gt;, но абсолютно &lt;i&gt;неверное&lt;/i&gt; вычисление времени).&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Предположим, цикл разработки длится две недели, или десять рабочих дней, - это обычная длина итерации в Agile. Допустим, у нас в команде четыре тестировщика, и каждый из них может выполнить три рабочих сессии в день (остальное время занимают собрания, почта, перерывы, разговоры и другие активности, не относящиеся к сессиям)&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;десять дней * четыре тестировщика * три сессии = 120 сессий.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Разумно предположить, что сессии эффективны не полностью, поскольку проектирование и выполнение тестов будет прерываться настройкой и исследованием багов. Допустим, 10% времени уходит на настройку и еще 25% на исследование и описание багов. Всего - 35%, для простоты будем считать, что на это тратится треть времени.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;120 сессий - 120 * 1/3 пауз = 80 сессий&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Таким образом, по нашей оценке двухнедельная итерация содержит 80 цельных, эффективных, идеальных сессий, включенных в 120 реальных сессий тестирования. Это не точное значение, оно и не может быть точным. Если проектировщики и программисты очень хорошо поработают, мы обнаружим не так много багов, и эффективность покрытия вырастет для каждой сессии. Если настройки окружения неполны, то перерывы могут занять больше трети времени, и эффективность покрытия снизится, либо нам потребуется больше сессий для получения той же степени покрытия. Таким образом, как только мы начинаем получать данные о том, что на самом деле происходит в тестовых сессиях, мы начинаем использовать эти данные для уточнения оценки. Я писал об этом подробнее &lt;a href=&quot;http://www.developsense.com/blog/2009/11/why-is-testing-taking-so-long-part-1/&quot;&gt;здесь&lt;/a&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Показатели прерываний и перерывов могут стать важной информацией для руководства. Но помните, что эти показатели сами по себе ничего не решают. Они и не могут этого делать. Вместо этого они поднимают вопросы. Из-за чего исследование багов заняло больше времени, чем ожидалось? Находим ли мы больше проблем, чем ожидали или тестировщики слишком долго исследуют проблемы самостоятельно, прежде чем обратиться за помощью к разработчикам? Может настройка занимает больше времени, чем должна, и клиенты тоже столкнутся с этой проблемой? Если даже проблемы с настройкой возникают только при тестировании, нет ли возможности ускорить процесс, чтобы уделить больше времени тестовому покрытию? Настоящая ценность любой метрики - в вопросах, которые она поднимает, а не в ответах, которые она предлагает. &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Желающие оценить длительность цикла тестирования или необходимое количество работников могут использовать и альтернативный подход: определите желаемый уровень покрытия, добавьте известные значения переменных и вычислите остальные. Разбейте продукт на области и сопоставьте каждой из них нужное число сессий в соответствии с рисками, сложностью или любой другой комбинацией параметров, которая вам важна. Отрегулируйте эффективность и число перерывов, отталкиваясь от предположений или предыдущего опыта. Если известно число тестировщиков, вы можете вычислить, сколько времени потребуется; если вы зададите длительность, то сможете определить необходимое количество тестировщиков. Это даст вам быструю оценку.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В которой, конечно, стоит сразу усомниться. Как опыт и умения тестировщика влияют на вашу оценку? На возможные события? Если вы подумываете увеличить число тестировщиков, сможете ли вы обойти закон Брукса? Меняются ли ваши представления о рисках? Верны ли эти представления? И так далее. Хорошо выполненная оценка должна порождать большое количество вопросов. Не беспокойтесь, подлинное тестирование даст ответы на эти вопросы.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Погодите секунду. Мы отдали кучу денег за дорогой инструмент управления тестированием, мы послали всех сотрудников на недельный курс, посвященный оценке тестирования, и теперь мы тратим несколько недель, подготавливая наши оценки. И как только мы начали так делать, наши оценки стали &lt;i&gt;действительно&lt;/i&gt; верными.&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Если опыт чему-то нас и учит, так это тому, что к любому человеку или процессу, обещающему надежное предсказание будущего, следует относиться скептически. Такие обещания подвержены &lt;a href=&quot;http://en.wikipedia.org/wiki/Ludic_fallacy&quot;&gt;игровой ошибке&lt;/a&gt; и искажению нарратива, основам философии &lt;a href=&quot;http://www.amazon.com/Black-Swan-Improbable-Robustness-Fragility/dp/081297381X&quot;&gt;Черного Лебедя&lt;/a&gt;. Если мы уже ответили на вопрос &quot;Когда мы собираемся закончить?&quot;, то у нас есть возможность (а часто и полномочия) превратить оценку в самоисполняющееся пророчество. Нулевой закон качества Джерри Вайнберга (&lt;a href=&quot;http://www.geraldmweinberg.com/&quot;&gt;Jerry Weinberg&lt;/a&gt;) (&quot;&lt;i&gt;Игнорируя качество, вы можете удовлетворить любые другие требования&lt;/i&gt;&quot;) - частный случай моего, более общего, Нулевого закона желательного исполнения: &quot;&lt;i&gt;Игнорируя некоторые параметры, вы можете достичь всего, что пожелаете&lt;/i&gt;&quot;. Если ваши оценки всегда соответствуют реальности, какие предположения и наблюдения вы отбросили, чтобы приспособить реальность к оценке? И если вы тратите недели на выполнение оценки, то может лучше потратить их на тестирование?&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/01/5.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-8658133177381544678</guid><pubDate>Wed, 12 Jan 2011 08:16:00 +0000</pubDate><atom:updated>2011-01-12T14:16:58.610+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Bolton</category><category domain="http://www.blogger.com/atom/ns#">оценки</category><category domain="http://www.blogger.com/atom/ns#">переводы</category><category domain="http://www.blogger.com/atom/ns#">планирование</category><title>М.Болтон: Оценка проекта и Черные Лебеди. Часть 4.</title><description>&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;yellow&quot;&gt;Вольный перевод статьи Майкла Болтона &lt;b&gt;&lt;a href=&quot;http://www.developsense.com/blog/2010/10/project-estimation-and-black-swans-part-4/&quot;&gt;Project Estimation and Black Swans (Part 4)&lt;/a&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В &lt;a href=&quot;http://notsocritical.blogspot.com/2011/01/1.html&quot;&gt;нескольких&lt;/a&gt; &lt;a href=&quot;http://notsocritical.blogspot.com/2011/01/2.html&quot;&gt;последних&lt;/a&gt; &lt;a href=&quot;http://notsocritical.blogspot.com/2011/01/3.html&quot;&gt;статьях&lt;/a&gt; исследовательская автоматизация подсказала некоторые интересные идеи насчет динамики проектов и их оценки. Какую пользу можно извлечь из этих математических экспериментов?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Прежде всего, стоит подчеркнуть, что &lt;b&gt;мы здесь играем с числами&lt;/b&gt;. Это упражнение не может предложить какое-либо реально обоснованное решение, поскольку вероятностная игра с произвольными порциями времени не отражает разработку ПО со всей ее сложностью, беспорядком, великолепием. Впрочем, это не так важно, ведь цель упражнения - не доказать что-либо, а скорее поднять интересные вопросы и выдвинуть предположения или подсказки, о чем еще стоит подумать.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;br /&gt;
&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Похоже, математика поддерживает идеи, расхваливаемые энтузиастами Agile, гуманистами и мыслителями: получайте обратную связь быстро и часто. Глядя на последнюю модель - меньше задач и более короткие проекты - мы можем предположить, что чем короче и управляемей проект, тем меньше шансов у Черного Лебедя нанести вред любому отдельно взятому проекту.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Другая правдоподобная идея, порожденная математикой: избегайте проектов, к которым применим закон степенного распределения - проектов, где вы уязвимы перед Потраченными Утрами и Потерянными Днями. Не беритесь за проекты из &lt;a href=&quot;http://www.edge.org/3rd_culture/taleb08/taleb08_index.html&quot;&gt;четвертого квадранта&lt;/a&gt; Талеба, проекты, которые могут содержать слабо определенные задачи, обладающие большим влиянием. Работайте, насколько это возможно, с достаточно предсказуемыми вещами, чтобы статистика случайных и непредсказуемых событий не так уж часто наносила нам вред. Оставайтесь в области известного, &quot;в Среднестане&quot;, как сказал бы Талеб. Правьте к следующему острову вместо попыток уплыть далеко за линию горизонта.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;И все равно будьте осторожны. Непредсказанность и непредсказуемость свойственна Черному Лебедю (и даже Гадкому Утенку). Парадоксальным образом, чем успешнее мы сокращаем количество неопределенности, тем менее часто мы сталкиваемся с редкими событиями. Чем событие реже, тем меньше мы о нем знаем - и тем меньше заботимся о возможных последствиях. Чем меньше мы знаем о последствиях, тем менее вероятно, что мы знаем, как с ними справляться - и уж точно тем менее ясно мы представляем, как справляться с ним. Короче, чем реже событие, тем меньше у нас знаний и опыта, которые помогли бы нам иметь дело с этим событием. Одно из следствий заключается в том, что наши Гадкие Утята, помимо увеличения длительности задач, имеют шанс изменить ситуацию неожиданным образом.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Кто-то может предложить нам устранить изменчивость, неизвестность и непредсказуемость. Какая отличная идея! По определению, неизвестность - это состояние незнания чего-либо; по определению, что-то непредсказуемое не может быть предсказано. Снежные бури случаются (даже в Британии!). Компьютеры ломаются. В Индии регулярно отключается электричество - когда я последний раз был в Индии, оно отключалось трижды во время занятий и еще трижды вечером за два дня пребывания в отеле бизнес-класса. В Северной Америке отключения электричества тоже случаются - и поскольку мы не привыкли к ним, мы не готовы действовать в такой ситуации. (Для нас это Черный Лебедь, хотя для живущих в Индии это - Серый Лебедь). Руководители назначают общие собрания, порой с печальными новостями. Сервера падают. Бэкапы портятся. Люди болеют, а если они здоровы, то болеют их дети. Поезда опаздывают. У велосипедов спускают колеса. И баги, по своей природе, непредсказаны.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Итак, мы не можем предсказать непредсказуемое. Однако есть жизнеспособная альтернатива: мы можем ожидать непредсказуемое, предвидеть его в некоторой степени, управлять им насколько это возможно и учитывать собственный опыт. Объятия непредсказуемости напоминают мне о парадоксе регулировщика из книги Джерри и Дэни Вайнбергов (Jerry &lt;span lang=&quot;EN-US&quot;&gt;and&lt;/span&gt; Dani Weinberg) &quot;&lt;a href=&quot;http://www.amazon.com/General-Principles-Systems-Design-Weinberg/dp/0932633072&quot;&gt;General Principles of System Design&lt;/a&gt;&quot;, который я &lt;a href=&quot;http://www.developsense.com/blog/2009/01/repeatabiity-and-adaptability/&quot;&gt;упоминал ранее&lt;/a&gt;:&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Задача регулировщика - устранить колебания, но эти колебания - единственный источник информации о качестве его работы. Поэтому, чем лучше работает регулировщик, тем меньше он получает информации о том, что и как улучшать.&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Это наводит меня на мысль, что, в некотором смысле, нам не всегда следует делать наши оценки слишком точными, обязательства - слишком жесткими, процессы - слишком строгими, роли - слишком замкнутыми, а наше видение будущего - слишком ясным. Поступая так, мы уменьшаем поток информации, поступающий извне системы, а это означает, что не развивается важное качество системы: &lt;i&gt;приспособляемость&lt;/i&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Когда я был на мастер-классе Джерри Вайнберга &quot;Problem Solving Leadership&quot; (PSL), одна из групп не смогла выполнить очередное упражнение по решению проблем. Во время опроса Джерри спросил: &quot;Почему у вас возникли такие трудности? Вчера вы справлялись с гораздо более трудными задачами.&quot;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&quot;Нас сразила сложность проблемы&quot; - ответил кто-то&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Джерри посмотрел поверх своих очков и ответил: &quot;Вас сразила &lt;i&gt;ваша реакция&lt;/i&gt; на сложность проблемы&quot;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Джерри часто говорит, что множество компаний пало жертвой невезения, но в большинстве случаев они были разрушены не невезением, а реакцией на невезение. Немало организаций выставило себя на посмешище, не сумев воспитать окружение, в котором каждый уполномочен решать проблемы. Они оставляют решение проблем в руках нескольких людей, обычно имеющих в названии должности слово &quot;менеджер&quot;. Но когда проблема обнаружится, менеджер может быть недоступен, или он может быть не лучшим кандидатом для борьбы с этой проблемой. Итак, еще одна причина, по которой оценки проваливаются, заключается в том, что организации и люди не готовы или не уполномочены иметь дело с неожиданностями. Наступающий хаос и паника делает их еще более уязвимыми перед Черными Лебедями.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;&quot;&gt;В следующий раз мы посмотрим, как все это относится к тестированию и к оценкам тестов.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/01/4.html</link><author>noreply@blogger.com (Pavel )</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-4193299247924562665</guid><pubDate>Tue, 11 Jan 2011 06:43:00 +0000</pubDate><atom:updated>2011-01-11T12:43:32.688+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Bolton</category><category domain="http://www.blogger.com/atom/ns#">оценки</category><category domain="http://www.blogger.com/atom/ns#">переводы</category><category domain="http://www.blogger.com/atom/ns#">планирование</category><title>М.Болтон: Оценка проекта и Черные Лебеди. Часть 3.</title><description>&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;yellow&quot;&gt;Вольный перевод статьи Майкла Болтона &lt;b&gt;&lt;a href=&quot;http://www.developsense.com/blog/2010/10/project-estimation-and-black-swans-part-3/&quot;&gt;Project Estimation and Black Swans (Part 3)&lt;/a&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;a href=&quot;http://notsocritical.blogspot.com/2011/01/2.html&quot;&gt;В прошлый раз&lt;/a&gt; мы показали, что попытки учесть колебания и сюрпризы в проекте с помощью&amp;nbsp; грязных манипуляций с оценкой выглядят довольно нелепо. Сегодня мы рассмотрим альтернативы, относящиеся к задачам и проектам, и посмотрим, к чему они нас приведут.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Оставляйте проблемные задачи незавершенными; допускайте потерю функциональности&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Существует два варианта этой стратегии. Первая - &lt;i&gt;дуть в свисток, достигнув 100&lt;/i&gt;. То есть мы ограничиваем время на проект, что для наших примеров означает остановку проекта по завершении 100 рабочих часов независимо от достигнутых результатов. Это может выглядеть неожиданным, но нам нужно остановиться через 100 часов.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Чтобы уменьшить количество сюрпризов и обеспечить чуть больше предсказуемости, мы можем &lt;i&gt;выбрасывать задачи по ходу работы&lt;/i&gt;. То есть, обнаружив в какой-то момент, что мы не укладываемся в расписание, мы можем втиснуть проект в расписание путем немедленного пересмотра оценок и выброса обязательств, эквивалентных количеству потерянного времени. Более того, мы можем выбирать, какие задачи выбросить, предпочитая избавляться от тех, что зависят от других задач.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Конечно, любая из выброшенных задач могла обернуться Ошеломляющим Успехом, но в данной модели мы полагаем, что это неизвестно заранее; в противном случае не было бы нужды делать оценку. Кроме того, в данном сценарии разумно выделять какое-то количество времени на управление выбрасыванием и добавлением задач.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Я работал программным менеджером (Program Manager) в компании, которая очень успешно применяла комбинацию стратегий &quot;Дуть в Свисток&quot; и &quot;Выбрасывать задачи по ходу работы&quot;. Зачастую такой подход достаточно хорошо работает для коммерческого ПО. Вам нужно периодически выпускать обновления, чтобы биржевые аналитики и акционеры оставались довольны. Досадно выпустить нечто менее амбициозное, чем вы надеялись. Тем не менее, зачастую это гораздо лучше, чем поздний выпуск продукта и потеря прибыли в текущем квартале. Если вам удастся сосредоточить внимание торговцев, аналитиков и слухов на том, что действительно было сделано, то никому за пределами компании не нужно знать, что вы собирались сделать на самом деле. Кроме того, имеется польза и для планирования будущей работы: незавершенные задачи текущего проекта становятся элементами списка задач для следующего.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Оставляйте проблемные задачи незавершенными; допускайте потерю функциональности и багов&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Мы можем ограничить время выполнения задач, снизить стандарт качества и прекращать работу над задачей, как только затраченное время превышает Небольшой Сдвиг. Обычно это ведет к наличию багов или других проблем в задачах, которые при ином подходе могли бы стать Потраченными Утрами, Потерянными Днями или Гадкими Утятами. Кроме того, придется выбросить некоторое количество задач (поскольку даже Небольшой Сдвиг стоит нам одну Нормальную Задачу).&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Это стратегия &lt;b&gt;постоянной бета-версии&lt;/b&gt;, когда мы приспосабливаем стандарт качества таким образом, чтобы объявить результат черновиком или бета-версией в обещанный день завершения проекта. Стратегия подразумевает, что наши клиенты явно или неявно согласны получить &lt;i&gt;что-то&lt;/i&gt; в обещанный срок и готовы принести в жертву часть функциональности, или жить с проблемами, или ждать завершения выполнения исходного списка задач, или к некоторой комбинации подобных недостатков. Это не безумие. На самом деле, многие организации используют такой подход, и некоторые из них становятся очень состоятельными.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Любая из этих двух стратегий становится менее эффективной, когда задачи зависят друг от друга. Поэтому может понадобиться родственная стратегия...&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Расцепляйте задачи &lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Риск задержки проекта особенно велик, когда задачи взаимозависимы, и когда мы не можем быстро и легко переключаться между последовательностями задач. Мои упражнения с методом Монте-Карло не учитывают зависимости между задачами. Они основаны на идее, что проблема в одном месте не повлияет на работу в другом месте, и что задержка отдельной задачи влияет только на проект в целом, но не на другие задачи. С одной стороны модель просто последовательно проходит по всем задачам в каждом проекте, как если бы каждая последующая задача зависела от предыдущей. С другой стороны длительность каждой задачи задается случайным образом.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В реальной жизни все происходит иначе. Зачастую у нас есть возможность реорганизовать задачи, поменять их приоритеты, так что когда встречается Гадкий Утенок, мы порой можем игнорировать его и заняться другими задачами. Это работает, когда наши процессы очень гибки и когда задачи не зависят друг от друга. &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;И все же в какой-то момент, в любом проекте и при любых затратах на оценку, некий набор задач оказывается на &lt;a href=&quot;http://en.wikipedia.org/wiki/Critical_path_method&quot;&gt;критическом пути&lt;/a&gt;. Я никогда не видел проекта, организованного так, чтобы ни одна задача не зависела от другой. Так что наша модель все еще имеет некоторый резонанс, даже если не воспринимать ее буквально.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Похоже, что ключевым фактором в этом случае становится предупреждение проблем и работа над потенциальными проблемами при первой возможности.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Замечайте проблемы и управляйте ими&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Что мы можем сделать, чтобы предупредить и обнаружить проблемы, чтобы управлять ими?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Мы можем применять практики Agile, такие как работа в парах (то есть построение процесса, гарантирующего, что каждый член команды регулярно работает в паре с каждым из остальных членов команды), которые &lt;i&gt;могли бы&lt;/i&gt; помочь с проблемой критического пути. Если каждый член команды хотя бы минимально знаком со всем проектом, то выше вероятность, что любой из них сможет работать над новой задачей, пока его текущая задача заблокирована. И наоборот, если один человек заблокирован, другие могут передать ему свои задачи или помочь с решением блокирующей проблемы. &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Если у нас возникают подозрения, что текущая задача не будет завершена вовремя, мы можем внести коррективы. Это наводит на мысль о сокращении цикла обратной связи с помощью постоянных проверок и тестирования, проверки задач в процессе выполнения и наискорейшего решения проблем - чтобы не позволять задачам отодвигаться и создавать потенциально гибельные задержки. По такому критерию короткие ежедневные standup-митинги лучше длинных еженедельных статусных митингов; но работа в парах, в одном помещении и постоянное общение - еще лучше. Откладывая проверки и тестирование до появления сборок (&lt;span lang=&quot;EN-US&quot;&gt;builds&lt;/span&gt;) интеграционного или системного уровня, мы получаем сравнительно медленную обратную связь для низкоуровневых проблем; проверка самих низкоуровневых элементов позволяет получать информацию относительно быстро и легко.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Мы можем управлять как проектами, так и задачами, уделяя особое внимание сбору и анализу информации. Исследуйте природу сдвигов; возможно, Потраченные Утра, Потерянные Дни или Гадкие Утята возникают по какому-то общему шаблону. Может какая-то часть проекта постоянно порождает проблемы? Может последовательность выполнения проекта делает его более подверженным сдвигам? Может какие-то эксперименты или странные действия, призванные уточнить оценку, отняли все время, отведенное на задачу? Может, задержки постоянно связаны с каким-то человеком или группой людей, и проблему можно решить обучением, работой в парах или переключением на другие задачи?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Заметьте, что получение обратной связи занимает какое-то время. Митинги могут занимать время, достаточное для выполнения задачи; постоянное общение - замедлять работу. В результате нам придется изменить некоторые наши задачи (или некоторую их часть) с &lt;i&gt;«работы»&lt;/i&gt; на &lt;i&gt;«проверку работы»&lt;/i&gt; или &lt;i&gt;«обсуждение работы»&lt;/i&gt;; и возможно, что некоторые Ошеломительные Успехи превратятся в Нормальные Задачи. Это недостаток. Выгода в том, что мы, возможно, &amp;nbsp;предотвратим некоторые Небольшие Сдвиги, Потраченные Утра, Потерянные Дни и Гадких Утят и превратим их в Нормальные Задачи или Ошеломительные Успехи.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Мы можем попробовать сократить число разного рода проблем, связанных с часто повторяющимися задачами. Многие организации пытаются делать это, внедряя непрерывные сборки и автоматизируя проверки, выполняемые для &amp;nbsp;каждой новой сборки. Однако имейте в виду, что автоматизация таких проверок сама состоит из задач, подверженных тем же проблемам оценки, что и остальная часть проекта.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Итак, если нам нужно управлять проектом, быстро реагировать на потенциально неконтролируемые задачи, сглаживать отклонения, используя те или иные из предложенных выше идей, то как мы можем это смоделировать, используя метод Монте-Карло? Если мы часто делаем проверки, то мы делаем меньше в рамках каждой задачи, поэтому давайте превратим Ошеломляющие Успехи (задачи, решенные за 50% запланированного времени) в Скромные Успехи (задачи, решенные за 75% отведенного времени). Мы неизбежно переоценим одни задачи и недооценим другие, так что давайте полагать, что в среднем 50 задач из ста завершаются на 25% раньше, 49 - на 25% позже. Каждого порой настигает неудача, поэтому мы оставим шанс появления одного Гадкого Утенка в проекте.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Число задач&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Тип задачи&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Всего (часов)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;50&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Скромный успех&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;0.75&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;37.5&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;49&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Крохотный сдвиг&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1.25&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;61.25&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Гадкий Утенок&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;И опять я выполнил 5000 смоделированных проектов.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Средний проект&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;114.67 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Минимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;92.0 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Максимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;204.25 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Проекты завершенные вовремя или   раньше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1058 (21.2%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие проекты&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;3942 (78.8%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 50% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;96 (1.9%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 100% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1 (0.02%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ-VQ0RzMjRrXzYKZHsbdsPgjEJOsoJyncNB2ekDtZhPiTUWsg-WU59O-PN6iy_spx46IPz4EUD9KBvS2SSuW3F0lWptTraxRYEDucpjWYa56n75LX_4a246zSmfgFukmjMwdj6CDejq0/s1600/mc_managed_project.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ-VQ0RzMjRrXzYKZHsbdsPgjEJOsoJyncNB2ekDtZhPiTUWsg-WU59O-PN6iy_spx46IPz4EUD9KBvS2SSuW3F0lWptTraxRYEDucpjWYa56n75LX_4a246zSmfgFukmjMwdj6CDejq0/s1600/mc_managed_project.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Вспомните, что в первом примере половина задач завершалась на 50% раньше. Сейчас половина задач завершается только на 25% раньше, но картина в целом выглядит лучше. Мы удвоили число проектов, завершившихся вовремя, а средняя длительность проекта снизилась со 124% до 114%. Отлов проблем до того, как он превратятся в Потраченные Утра или Потерянные Дни дает заметную разницу в результатах.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Замечайте проблемы и управляйте ими, плюс короткие итерации&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Чем больше задач в проекте, тем больше шансов столкнуться с Гадким Утенком. Что если мы получим возможность выбирать и откажемся от крупных проектов? В сущности это идея методологии Agile, фокусирующейся на серии коротких итераций вместо единого монолитного проекта. Разбиение большого проекта на спринты позволяет получить эквивалент частых проверок состояния задач на уровне проекта. &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Когда я смоделировал проект Agile с помощью метода Монте-Карло, я был поражен результатом.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Для распределения задача/длительность я использовал тот же подход, что и раньше&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Число задач&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Тип задачи&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Всего (часов)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;50&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Скромный успех&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;0.75&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;37.5&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;49&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Небольшой сдвиг&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1.25&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;61.25&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 108pt;&quot; valign=&quot;top&quot; width=&quot;144&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Гадкий Утенок&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Я уменьшил размер проекта до 20 задач. Далее, чтобы скомпенсировать уменьшение проекта, я выполнил 25000 смоделированных проектов.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Средний проект&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;22.94 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Минимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16 часов&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Максимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;66.75 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Проекты завершенные вовремя или   раньше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;12433 (49.7%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие проекты&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;12567 (50.3%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 50% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;4552 (18.2%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 100% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;400 (1.6%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;br /&gt;
&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDi22KoKpKvkedo4Wsc3BpGPuVO3kOpfv8lEKRUW02g8lnX6SQOIoOdmGRqFMsJD91PvBFYnWtBeJUt4AaHteg109my1UsLVkr3QZ7Jtmg6dFXWx4Iy_DpG5muZCAH56duhcQwvLL0x1E/s1600/mc_agile_project.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDi22KoKpKvkedo4Wsc3BpGPuVO3kOpfv8lEKRUW02g8lnX6SQOIoOdmGRqFMsJD91PvBFYnWtBeJUt4AaHteg109my1UsLVkr3QZ7Jtmg6dFXWx4Iy_DpG5muZCAH56duhcQwvLL0x1E/s1600/mc_agile_project.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Тут есть несколько интересных моментов. Мы, наконец, сумели завершить вовремя почти половину проектов! Кроме того, более 80% проектов (20443 из 25000 в моем запуске) находятся в пределах 15% от предсказанного времени - а поскольку полный проект занимает только 30 часов, отклонение этих проектов составляет только 3 часа. Это позволяет быстро корректировать курс; в модели сточасовых проектов средний проект задерживался на три дня.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Есть и еще один потрясающий результат: общее количество времени, затраченного на эти 25000 проектов (всего 500 000 задач), равно 573 410 часов. В исходной модели общее время равнялось 619 156,5 часов, что на 8% больше. В более реалистичном втором примере общее время равнялось 736 199,2 часа, что на 28% больше. Короткие итерации дают случайности меньше возможностей повлиять на каждый отдельный проект в нашей модели.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Итак, что все это означает? Чем это полезно? Давайте рассмотрим некоторые идеи в следующий раз.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/01/3.html</link><author>noreply@blogger.com (Pavel )</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ-VQ0RzMjRrXzYKZHsbdsPgjEJOsoJyncNB2ekDtZhPiTUWsg-WU59O-PN6iy_spx46IPz4EUD9KBvS2SSuW3F0lWptTraxRYEDucpjWYa56n75LX_4a246zSmfgFukmjMwdj6CDejq0/s72-c/mc_managed_project.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-7653267992962084357</guid><pubDate>Mon, 10 Jan 2011 07:44:00 +0000</pubDate><atom:updated>2011-01-10T13:44:32.521+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Bolton</category><category domain="http://www.blogger.com/atom/ns#">оценки</category><category domain="http://www.blogger.com/atom/ns#">переводы</category><category domain="http://www.blogger.com/atom/ns#">планирование</category><title>М.Болтон: Оценка проекта и Черные Лебеди. Часть 2.</title><description>&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;yellow&quot;&gt;Вольный перевод статьи Майкла Болтона&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp; &lt;b&gt;&lt;a href=&quot;http://www.developsense.com/blog/2010/10/project-estimation-and-black-swans-2/&quot;&gt;Project Estimation and Black Swans (Part 2)&lt;/a&gt;&lt;b&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В &lt;a href=&quot;http://notsocritical.blogspot.com/2011/01/1.html&quot;&gt;предыдущей статье&lt;/a&gt; я говорил об асимметрии влияния неожиданных событий и о сопутствующих проблемах оценки. Сегодня мы рассмотрим возможные пути решения этих проблем. Тестировщики часто начинают с вопроса об адекватности модели, давайте и мы начнем с этого.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Линейная модель, которую я предлагал, не соответствует реальности в нескольких аспектах, но до сих пор я особо не говорил об этом. Вот лишь несколько недостатков этой модели.&lt;/div&gt;&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;модель неявно предполагает, что все задачи должны      выполняться в определенном порядке.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;модель неявно предполагает, что все задачи      одинаково важны.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;модель не учитывает информацию о зависимостях и      взаимозависимостях между задачами.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;модель предполагает, что, столкнувшись с Потраченным      Утром, Потерянным Днем или Гадким Утенком, мы не можем (и не будем) ничего      с ними сделать.&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В частности модель не учитывает, что руководитель или инженер могут принимать какие-то управленческие решения, регулирующие действия по отношению к задачам, проекту, контексту или оценкам. Начнем с последних.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Дополняйте оценки так, чтобы они были верны в половине случаев&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Взгляните еще раз на график первого вчерашнего сценария:&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirl97Yd6eqjKrzdx-9rvwM6AA0qq63r3hDktNIJmNlzt_UuHcvPKUZTJsbbPbnLZjzZjSiRz8SaxJ_HwCWtBm6EyTmRrdudJKbNQUcNzjjjNbGY2fH6Kb3bEp6jTj9HkCbOHfi9wgSnIk/s1600/mc_standard_project.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirl97Yd6eqjKrzdx-9rvwM6AA0qq63r3hDktNIJmNlzt_UuHcvPKUZTJsbbPbnLZjzZjSiRz8SaxJ_HwCWtBm6EyTmRrdudJKbNQUcNzjjjNbGY2fH6Kb3bEp6jTj9HkCbOHfi9wgSnIk/s1600/mc_standard_project.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Используя данный набор допущений и случайное распределение, мы получаем задержку сроков более чем в 90% случаях. Чтобы противостоять этому, мы могли бы добавить произвольный процент к нашим оценкам так, чтобы в половине случаев проекты завершались вовремя или раньше, а вторая половина по-прежнему запаздывала. В этом случае мы стремимся к значению &lt;i&gt;медианы&lt;/i&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Когда я взял данные метода Монте-Карло и упорядочил проекты по длительности, я обнаружил, что Проект 2500, тот, что находится ровно посередине, занял 122 часа. Таким образом, стоит добавить 22% к оценке, и в половине случаев мы завершим проект в отведенное время.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Однако есть две проблемы. Во-первых, &lt;i&gt;степень опоздания&lt;/i&gt; по-прежнему может сильно различаться. Во-вторых, проблема асимметрии так же актуальна для проектов, как для отдельных задач: крупный проигрыш более значим, чем большая победа. Даже если мы стремимся к &lt;i&gt;средней&lt;/i&gt; длительности проекта вместо медианы (среднее равняется 123,83 часа - на пару часов больше медианы), некоторые проекты займут столько времени, сколько запланировано, но выигрыш &quot;ранних&quot; проектов будет довольно скромным, в то время как &quot;поздние&quot; будут чрезвычайно запаздывать. Все это недопустимо для того, кто ценит предсказуемость (то есть для того, кто просит нас подготовить оценку).&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Дополняйте оценки так, чтобы они были верны почти всегда&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Любитель предсказуемости, вероятно, предпочел бы, чтобы наши проекты завершались вовремя в 95% случаев. Чтобы достичь этого уровня при том же наборе допущений, нам понадобится оценить проект настолько хорошо, насколько мы способны, а затем увеличить нашу оценку на 58% - до 158 часов.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Один из недостатков такой стратегии в том, что работа склонна занимать все отведенное время, а люди начинают работать в более низком темпе.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;С другой стороны, если люди работают в постоянном темпе, 82% проектов завершатся как минимум на 10% раньше, а 42% - на 25% раньше! В этом случае мы можем столкнуться с &quot;политическим&quot; недовольством, и нас заставят быть менее осторожными в наших оценках. Математика показывает, что мы действительно не можем выиграть при данном наборе допущений.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Дополняйте команду&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Вместо дополнения временной оценки мы могли бы заложить в систему резервы, обеспечив возможность привлечения новых людей в случае каких-либо сюрпризов. Но вспомните закон Брукса, утверждающий, что добавление людей в опаздывающий проект задерживает его еще больше. Так происходит по двум причинам: новых людей нужно обучать, а увеличение числа связей в системе ведет к росту расходов на коммуникацию.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Так что, возможно, нам придется менять что-то в управлении проектом. Обсудим это в следующей статье.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/01/2.html</link><author>noreply@blogger.com (Pavel )</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirl97Yd6eqjKrzdx-9rvwM6AA0qq63r3hDktNIJmNlzt_UuHcvPKUZTJsbbPbnLZjzZjSiRz8SaxJ_HwCWtBm6EyTmRrdudJKbNQUcNzjjjNbGY2fH6Kb3bEp6jTj9HkCbOHfi9wgSnIk/s72-c/mc_standard_project.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5296774367900969742.post-466698509696317194</guid><pubDate>Sun, 09 Jan 2011 08:44:00 +0000</pubDate><atom:updated>2011-01-10T13:45:37.857+06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Bolton</category><category domain="http://www.blogger.com/atom/ns#">оценки</category><category domain="http://www.blogger.com/atom/ns#">переводы</category><category domain="http://www.blogger.com/atom/ns#">планирование</category><title>М.Болтон: Оценка проекта и Черные Лебеди. Часть 1.</title><description>&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;yellow&quot;&gt;Вольный перевод статьи Майкла Болтона &lt;b&gt;&lt;a href=&quot;http://www.developsense.com/blog/2010/10/project-estimation-and-black-swans/&quot;&gt;Project Estimation and Black Swans (Part 1)&lt;/a&gt;&lt;/b&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В последние месяцы в сети активно обсуждалось оценивание:&lt;/div&gt;&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;a href=&quot;http://twitter.com/wardcunningham&quot;&gt;Ward      Cunningham&lt;/a&gt; &lt;a href=&quot;http://twitter.com/WardCunningham/status/7574776996&quot;&gt;написал&lt;/a&gt; в      твиттере: &quot;Оценивание - выдуманная проблема, на решение которой      профан тратит десятки дней&quot;&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;a href=&quot;http://testertested.blogspot.com/&quot;&gt;Pradeep      Soundararajan&lt;/a&gt; опубликовал в блоге развернутую статью, посвященную &lt;a href=&quot;http://testertested.blogspot.com/2010/01/test-effort-estimation-getting-it-wrong.html&quot;&gt;оценке      затрат на тестирование&lt;/a&gt;.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Некто, назвавшийся Nathaniel&#39;ем, изложил &lt;a href=&quot;http://terralien.com/blog/articles/2010/01/13/good-estimates&quot;&gt;интересную      точку зрения на успешные оценки&lt;/a&gt; на сайте Terralien.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Jens Schauder опубликовал &lt;a href=&quot;http://blog.schauderhaft.de/2010/01/17/reason-estimate-low/&quot;&gt;8      причин, почему оценки слишком низки&lt;/a&gt;.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Andre Dhondt недавно подключился к спору со статьей      “&lt;a href=&quot;http://www.management30.com/profiles/blogs/estimation-causes-waste-slack&quot;&gt;Оценки      ведут к убыткам, резервы приносят пользу&lt;/a&gt;”. (Вообще-то я не согласен.      Резервы не приносят пользу, а вносят некоторый вклад в создание      благоприятных условий, позволяющих создать нечто полезное. Достаточное      количество резервов позволяет снизить угрозы.)&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Все это сподвигло меня опубликовать результаты некоторых численных экспериментов, начатых в ноябре 2009-го и основанных на мысленном эксперименте, придуманном Джеймсом Бахом (James Bach). Эта работа совпадает по времени с &lt;a href=&quot;http://www.developsense.com/articles/2010-01-SwanSong.pdf&quot;&gt;Лебединой Песней&lt;/a&gt;, колонкой для Better Software, в которой я обсуждал книгу Талеба (Nassim Nicholas Taleb) &quot;Черный Лебедь&quot;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Черный Лебедь - невероятное и неожиданное событие, меняющее наше представление о реальности и обладающее тремя качествами.&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Во-первых, оно застает нас врасплох, обычно от того, что не описывается нашими моделями. Талеб пишет, &quot;Модели и конструкции, эти мысленные карты реальности, не всегда неверны; они неверны только в некоторых случаях. Проблема в том, что а) вы не знаете заранее (а только по наступлении факта), в чем карта неверна и б) последствия ошибки могут быть суровыми. Эти модели похожи на экспериментальную медицину, которая иногда помогает, но очень часто влечет серьезные побочные эффекты.&quot;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Во-вторых, влияние Черного Лебедя непропорционально велико. Происходит много редких и удивительных вещей, не обладающих подобным влиянием. Черные Лебеди могут разрушать состояния, имущество или карьеру, или создавать их. Черный Лебедь может быть хорошим событием, даже если мы не склонны его так оценивать.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В-третьих, после Черного Лебедя люди склонны говорить, что они предполагали его приход. Такие заявления звучат после события и обусловлены парой взаимосвязанных когнитивных ошибок (ошибок познания). Первую Талеб называет &lt;i&gt;&lt;a href=&quot;http://www.fooledbyrandomness.com/blackswanglossary.htm&quot;&gt;эпистемиологической самонадеянностью&lt;/a&gt;&lt;/i&gt;, преувеличенным представлением о том, что мы знаем. Вторая - это искажение нарратива, наша склонность рассказывать и воспринимать истории в соответствии с нашими представлениями о нашем знании, без проверки связей между причиной и результатом. Легко считать, что мы знаем важные факторы истории, когда нам известно, чем кончилось дело. Первая Мировая Война была Черным Лебедем; 11е сентября 2001го года было Черным Лебедем; землетрясения на Гаити, вулкан в Исландии, разрушение нефтяной платформы в Мексиканском заливе были Черными Лебедями. Взлет цены на акции Google после выхода этой компании на биржу тоже был Черным Лебедем. (Возможно, вы встречали людей, заявляющих, что они знали заранее о будущем резком росте акций. Если бы это было правдой, они бы купили акции и стали богаты. Если они не богаты, это проявление искажения нарратива)&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Думаю, одна из причин, по которой проекты не укладываются в оценки, заключается в том, что мы от природы не учитываем влияние Черных Лебедей. Джеймс предложил мне мысленный эксперимент, иллюстрирующий некоторые интересные проблемы оценивания.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Представьте, что вы руководите проектом и что, ради выполнения оценки, вы разбили его на действительно мелкие составляющие. Полный проект декомпозируется в сотню задач, выполнение каждой из которых, по вашим ожиданиям, займет один час. То есть проект должен занять 100 часов.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Кроме того, предположим, что ваша оценка была очень осторожной, и половина задач (т.е. 50) были завершены за тридцать минут вместо часа. Назовем такие задачи &lt;b&gt;Ошеломляющим Успехом&lt;/b&gt;. 35% задач выполнены за отведенное время; назовем их &lt;b&gt;Нормальными Задачами&lt;/b&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;В 15% случаев вам не везет.&lt;/div&gt;&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Восемь задач занимают два часа вместо одного.      Давайте назовем их &lt;b&gt;Небольшой Сдвиг&lt;/b&gt;.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Четыре задачи (одна из 25ти) заканчиваются через 4      часа вместо одного, как вы предполагали. Проявился баг в какой-то чужой      библиотеке, которую вы используете; вам нужен доступ на какой-то сервер, а      IT департамент слишком занят и отвечает только после обеда. Такую задачу      мы назовем &lt;b&gt;Потраченное Утро&lt;/b&gt;.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Две задачи (одна из пятидесяти) занимают целый день      вместо часа. Кто-то должен остаться дома с больным ребенком. Их мы назовем      &lt;b&gt;Потерянный День&lt;/b&gt;.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Одна задача из ста - только одна - занимает два дня      вместо часа. Другая команда задерживает разработку библиотеки на пару дней;      поломка жесткого диска обрушила систему, а резервная копия оказалась      испорченной; одной из программисток удалили зуб мудрости (все эти вещи      случались в проектах, где я работал). Эти события не обладают      разрушительной силой Черных Лебедей; они больше похожи на детей Черного      Лебедя, поэтому давайте звать их &lt;b&gt;Гадкими      Утятами&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Число задач&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Тип задачи&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Всего (часов)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;50&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Ошеломляющий успех&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;0.5&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;25&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;35&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Нормальная задача&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;35&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;8&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Небольшой сдвиг&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Потраченное утро&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Потерянный день&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;8&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Гадкий Утенок&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;100&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 135pt;&quot; valign=&quot;top&quot; width=&quot;180&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;124&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Так и есть: средний проект, основанный на описанных выше предположениях, завершится с опозданием в 24 процента. То есть вы оценили, что он займет две с половиной (человеко-)недели. Похоже, что на самом деле потребуется больше трех недель. Напомню, что это средний проект, а понятие &quot;среднего&quot; проекта основано на вероятности. В реальности не существует такой штуки, как &quot;средний&quot; проект; каждый изобилует деталями. Не каждому проекту сопутствует неудача - но некоторые будут более неудачны, чем остальные.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Таким образом, мы можем смоделировать проекты более подходящим способом, и это может быть очень увлекательно. Возьмем описанные выше вероятности, допуская случайность наступления соответствующих событий. Применим их к каждой задаче в проекте, далее выполним множество таких проектов. Это довольно ясно покажет, что &lt;i&gt;может&lt;/i&gt; произойти с проектами. Такой подход называется &lt;a href=&quot;http://en.wikipedia.org/wiki/Monte_carlo_simulation&quot;&gt;методом Монте-Карло&lt;/a&gt;, и это отличный пример &lt;a href=&quot;http://kaner.com/wp-content/uploads/2010/08/ExploratoryTestAutomationHoffman.pdf&quot;&gt;автоматизации исследовательского тестирования&lt;/a&gt;.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Я создал небольшую программу на Ruby, генерирующую результаты таких сценариев. Скрипт выполняет N проектов (состоящих из M задач каждый), позволяет мне указать произвольное число вероятностей и длительностей для задач, сохраняет результаты в таблицу Excel и создает графики для этих результатов. (Естественно, пока я занимался этим проектом, я нашел и починил тонну багов в моем коде. Но помимо этого я нашел баги в Excel&#39;е, включая обрушения, вследствие состояния гонки (race condition), проблемы с производительностью API и просто недостаточную документацию. Разве тестирование - это не интересно?) Для описанного выше сценария я выполнил 5000 проектов, каждый из которых состоял из 100 случайных задач. Я получил следующие результаты, основанные на&amp;nbsp; указанных выше числах:&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Средний проект&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;123.83 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Минимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;74.5 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Максимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;217 часов&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Проекты завершенные вовремя или   раньше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;460 (9.2%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие проекты&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;4540 (90.8%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 50% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;469 (9.8%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 100% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.15pt;&quot; valign=&quot;top&quot; width=&quot;108&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;2 (0.9%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLuFmTIelNiIxKbR_65Upmk-wje6uOY-Yw9lOU1Ym0X_8slfZDCsHUNUhZubuQxLG48zAwbnuNTyxnv4Qemfr83SbqvnfVYQyIx3RD0S5MZQhbA2ZW_w9A6nv57_c3oNEUQBcTrjF2mMI/s1600/mc_standard_project.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLuFmTIelNiIxKbR_65Upmk-wje6uOY-Yw9lOU1Ym0X_8slfZDCsHUNUhZubuQxLG48zAwbnuNTyxnv4Qemfr83SbqvnfVYQyIx3RD0S5MZQhbA2ZW_w9A6nv57_c3oNEUQBcTrjF2mMI/s1600/mc_standard_project.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Несколько интересных вещей, которые я заметил:&lt;/div&gt;&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Средний проект занимает 123.83 часов, почти на 25%      больше, чем мы оценивали&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;460 проектов (или меньше 10%) завершились вовремя      или раньше срока!&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;4540 проектов (или более 90%) завершились с      опозданием!&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Вам &lt;i&gt;может&lt;/i&gt;      повезти. В моем запуске три проекта завершились за 80 часов и меньше. Ни      один из проектов не избежал &lt;i&gt;какого-либо&lt;/i&gt;      Потраченного Утра, Потерянного Дня или Гадкого Утенка. &lt;i&gt;Ни один из пяти тысяч&lt;/i&gt;.&lt;/li&gt;
&lt;li class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Кроме того, вам может не повезти. 469 проектов      заняли, по меньшей мере, в полтора раза больше времени, чем планировалось.      Два проекта заняли более чем вдвое больше времени. Наконец, один очень      несчастливый проект содержал четыре Потраченных Утра, один Потерянный День      и восемь Гадких Утят. Этот проект занял 217 часов.&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Это может показаться парадоксальным результатом. Половина задач занимает только половину времени, отведенного для их выполнения. 85% задач завершается вовремя или раньше. Только 15% задерживаются. Имеется всего один шанс из сотни встретить Гадкого Утенка. Как вышло, что так мало проектов завершилось вовремя?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Ответ в &lt;i&gt;асимметрии&lt;/i&gt;, еще одном элементе модели Черного Лебедя, созданной Талебом. Делая оценки, легко ошибиться, работая, скажем, с множителем 2. Так, &lt;i&gt;деление&lt;/i&gt; длительности задачи на два имеет совершенно иное влияние, чем &lt;i&gt;умножение&lt;/i&gt; длительности на два. Маленькая Победа сохраняет только половину Нормальной Задачи, в то время как Небольшой Сдвиг стоит две Нормальные Задачи.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Предположим, что вы очень хорошо делаете оценки, и что вы не так часто ошибаетесь. 20% задач завершаются на 10% раньше (назовем их Маленькими Победами). 65% задач выполняются точно вовремя (Нормальные Задачи). То есть, 85% ваших оценок точны или слишком осторожны. Как и раньше, вы имеете восемь Небольших Сдвигов, четыре Потраченных Утра, два Потерянных Дня и Гадкого Утенка. &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Имея 20% задач, завершающихся раньше срока и 15% - позже, как бы вы оценили длительность среднего проекта?&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Число задач&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Тип задачи&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Всего (часов)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;20&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Небольшая победа&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;0.9&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;18&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;65&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Нормальная задача&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;65&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;8&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Небольшой сдвиг&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Потраченное утро&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Потерянный день&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;8&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Гадкий Утенок&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 77.4pt;&quot; valign=&quot;top&quot; width=&quot;103&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;100&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 117pt;&quot; valign=&quot;top&quot; width=&quot;156&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 81.9pt;&quot; valign=&quot;top&quot; width=&quot;109&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 80.1pt;&quot; valign=&quot;top&quot; width=&quot;107&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;147&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Хотя ваши оценки даже более точны, чем в первом примере, средний проект завершается на 47% позже. То есть вы полагаете, что он займет две с половиной недели, а на самом деле, судя по всему, потребуется &lt;i&gt;более трех с половиной недель&lt;/i&gt;. Напомню, это в &lt;i&gt;среднем&lt;/i&gt;, и вновь основано на вероятности. Как и ранее, не каждый проект столкнется с невезением, а некоторые проекты будут более невезучими, чем остальные. Я вновь выполнил 5000 проектов, состоящих из ста задач каждый.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: medium none;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Средний проект&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;147.24 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Минимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;105.2 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Максимальная длительность&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;232 часа&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Проекты завершенные вовремя или   раньше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;0 (0.0%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие проекты&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;5000 (100.0%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 50% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;2022 (40.4%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td style=&quot;border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 239.25pt;&quot; valign=&quot;top&quot; width=&quot;319&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Опоздавшие на 100% и больше&lt;/div&gt;&lt;/td&gt;   &lt;td style=&quot;border-color: -moz-use-text-color windowtext windowtext -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 90.15pt;&quot; valign=&quot;top&quot; width=&quot;120&quot;&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;30 (0.6%)&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy3AQU9EYzjbkSIbpOesZugCTjq4taNw_LJKBi6YevCC-sC9WV-MxwXKBZnmon-jRZkeddoHBolsydCPCviVLt1rFK4fPJUkcynAydQ976KGcL4gGjczvNnvhGTrG7fTlI8wIvlLie4NA/s1600/mc_typical_project.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy3AQU9EYzjbkSIbpOesZugCTjq4taNw_LJKBi6YevCC-sC9WV-MxwXKBZnmon-jRZkeddoHBolsydCPCviVLt1rFK4fPJUkcynAydQ976KGcL4gGjczvNnvhGTrG7fTlI8wIvlLie4NA/s1600/mc_typical_project.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Ни один из 5000 проектов не завершился вовремя. &lt;i&gt;Лучший&lt;/i&gt; из проектов опоздал на 5%. Он содержал 18 Маленьких Побед, 77 Нормальных Задач, 4 Небольших Сдвига и Потраченное Утро. Этот проект счастливо избежал Потерянных Дней и Гадких Утят. И, будучи близким к запланированному времени, он был &lt;i&gt;чрезвычайно&lt;/i&gt; редким. На самом деле, только 16 проектов из 5000 задержались менее чем на 10%.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Это &lt;i&gt;чисто&lt;/i&gt; математические модели. Они игнорируют все, что свойственно самосознающим (self-aware) системам, способы взаимодействия и влияния между системами и их участниками. Единственный использованный здесь вид активности по управлению проектами - моделирование и оценка задач в виде одночасовых кусков. Все, что происходило после этого, сводится к случайности и удаче. Мне кажется, метод Монте-Карло показывает, что при отсутствии управления малое, на наш взгляд, количество сюрпризов и неполадок может иметь большое влияние.&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;Заметьте, что в обоих примерах, по меньшей мере, 85% задач завершались вовремя или даже раньше. Не больше чем 15% задач опаздывали. Это асимметрия влияния запаздывающих задач, приводящая к задержке подавляющего большинства проектов. Задача, занимающая одну шестнадцатую запланированного времени сохраняет менее одной Нормальной Задачи, а стоимость Гадкого Утенка превышает пятнадцать Нормальных Задач. Комбинация математики и неожиданности безжалостна к вам. Чтобы обойти проблему, вам придется &lt;i&gt;управлять&lt;/i&gt; чем-то. Какие стратегии возможны? Об этом поговорим &lt;a href=&quot;http://notsocritical.blogspot.com/2011/01/2.html&quot;&gt;завтра&lt;/a&gt;.&lt;/div&gt;</description><link>http://notsocritical.blogspot.com/2011/01/1.html</link><author>noreply@blogger.com (Pavel )</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLuFmTIelNiIxKbR_65Upmk-wje6uOY-Yw9lOU1Ym0X_8slfZDCsHUNUhZubuQxLG48zAwbnuNTyxnv4Qemfr83SbqvnfVYQyIx3RD0S5MZQhbA2ZW_w9A6nv57_c3oNEUQBcTrjF2mMI/s72-c/mc_standard_project.png" height="72" width="72"/><thr:total>0</thr:total></item></channel></rss>