<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Andrei Solntsev</title>
 <link href="https://asolntsev.github.io/atom.xml" rel="self"/>
 <link href="https://asolntsev.github.io/"/>
 <updated>2026-03-09T06:52:25+00:00</updated>
 <id>https://asolntsev.github.io</id>
 <author>
   <name>Andrei Solntsev</name>
   <email></email>
 </author>

 
 <entry>
   <title>Mockito научился мокать статические методы!</title>
   <link href="https://asolntsev.github.io/ru/2020/07/11/mockito-static-methods/"/>
   <updated>2020-07-11T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2020/07/11/mockito-static-methods</id>
   <content type="html">&lt;p&gt;Горячие новости!&lt;/p&gt;

&lt;p&gt;Mockito только что выпустил версию 3.4.0, в которой он умеет мокать статические методы.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Раньше Mockito этого не умел. Умел мокать только нестатические методы. Зато PowerMock умел. Но PowerMock делал это 
очень медленно, ведь для этого он подменял загрузчик классов (classloader), и весь тест запускал в нём. И перед 
каждым тестов инициализировал загрузчик классов заново.&lt;/p&gt;

&lt;p&gt;А вот новый способ от Mockito 3.4.0 должен быть значительно быстрее, потому что у него меньше скоп: он мокает 
статический метод только в рамках одной маленькой лямбды. Изящно.&lt;/p&gt;

&lt;p&gt;Давайте попробуем!&lt;/p&gt;

&lt;h3 id=&quot;шаг-1-зависимость&quot;&gt;Шаг 1: зависимость&lt;/h3&gt;
&lt;p&gt;В нашем &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.gradle&lt;/code&gt; меняем &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mockito-core:3.3.3&lt;/code&gt; на &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mockito-inline:3.4.0&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-groovy highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;testImplementation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;org.mockito:mockito-inline:3.4.0&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;шаг-2-что-мокаем&quot;&gt;Шаг 2: что мокаем&lt;/h3&gt;
&lt;p&gt;Предположим, у вас есть некий класс со статическим методом, который вы хотите замокать в тесте:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;шаг-3-мокаем-статический-метод&quot;&gt;Шаг 3: Мокаем статический метод&lt;/h3&gt;

&lt;p&gt;Для этого нужно использовать метод &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mockito.mockStatic()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;lookMomICanMockStaticMethods&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MockedStatic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;theMock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockStatic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;theMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Buddy:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rafael&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rafael&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Всё. Mockito подменяет статический метод только в рамках try/catch блока. Быстро и эффективно (
Насколько это быстро, пока проверить не успел, извиняйте. :)
).&lt;/p&gt;

&lt;p&gt;Больше примеров вы можете найти &lt;a href=&quot;https://github.com/mockito/mockito/blob/static-mock/subprojects/inline/src/test/java/org/mockitoinline/StaticMockTest.java&quot;&gt;в тестах самого Mockito&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Отличная работа, &lt;a href=&quot;https://twitter.com/rafaelcodes&quot;&gt;Rafael Winterhalter&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;NB! Не забывайте, что &lt;a href=&quot;https://www.youtube.com/watch?v=4JJNccWtdNI&quot;&gt;статические методы - зло&lt;/a&gt;, и старайтесь их по возможности не использовать.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/ru&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mockito can mock static methods!</title>
   <link href="https://asolntsev.github.io/en/2020/07/11/mockito-static-methods/"/>
   <updated>2020-07-11T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2020/07/11/mockito-static-methods</id>
   <content type="html">&lt;p&gt;Hot news!&lt;/p&gt;

&lt;p&gt;Mockito just released version 3.4.0 which can now mock static methods.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Before 3.4.0, Mockito could not mock static methods. It could only mock non-static methods. 
Though, PowerMock could. But PowerMock did it slowly: it replaced a classloader for every test, and executed the 
whole test within this classloader.&lt;/p&gt;

&lt;p&gt;And the new Mockito 3.4.0 way should be more effective because it has narrower scope: it mock the static method 
only within one small lambda. Graceful.&lt;/p&gt;

&lt;p&gt;Let’s try it!&lt;/p&gt;

&lt;h3 id=&quot;step-1-dependency&quot;&gt;Step 1: dependency&lt;/h3&gt;
&lt;p&gt;In your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.gradle&lt;/code&gt; replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mockito-core:3.3.3&lt;/code&gt; by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mockito-inline:3.4.0&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-groovy highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;testImplementation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;org.mockito:mockito-inline:3.4.0&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;step-2-what-are-we-going-to-mock&quot;&gt;Step 2: what are we going to mock&lt;/h3&gt;

&lt;p&gt;Let’s assume we have a class with static method (that we want to mock in test):&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;step-3-mock-the-static-method&quot;&gt;Step 3: Mock the static method&lt;/h3&gt;

&lt;p&gt;We can use new method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mockito.mockStatic()&lt;/code&gt; for this:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;lookMomICanMockStaticMethods&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MockedStatic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;theMock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockStatic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;theMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Buddy:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rafael&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rafael&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Buddy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it.&lt;br /&gt;
Mockito replaces the static method only with the try/catch block. Fast and simple (I haven’t checked how fast is it actually, sorry. :)
)&lt;/p&gt;

&lt;p&gt;You can see more example &lt;a href=&quot;https://github.com/mockito/mockito/blob/static-mock/subprojects/inline/src/test/java/org/mockitoinline/StaticMockTest.java&quot;&gt;in Mockito own tests&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Great job, &lt;a href=&quot;https://twitter.com/rafaelcodes&quot;&gt;Rafael Winterhalter&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;NB! Don’t forget &lt;a href=&quot;https://www.youtube.com/watch?v=dFQSOlOOoXE&amp;amp;list=PLfazdZ9SzB9eDJIugtfH7KeVLLAP1pDLh&quot;&gt;static methods are evil&lt;/a&gt;. 
Try to avoid them if possible.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Andrei Solntsev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/en&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Миграция на Mockito 2.1</title>
   <link href="https://asolntsev.github.io/ru/2016/10/11/mockito-2.1/"/>
   <updated>2016-10-11T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2016/10/11/mockito-2.1</id>
   <content type="html">&lt;p&gt;На днях мир был ошеломлён неожиданной новостью.&lt;/p&gt;

&lt;p&gt;Шутки ли, вышла Mockito 2.1.0 - после стольких лет ожиданий! Признаться, я уж было отчаялся.&lt;/p&gt;

&lt;p&gt;В Mockito 2 обещается &lt;a href=&quot;https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2&quot;&gt;много всяких вкусняшек&lt;/a&gt;, включая:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Поддержка Java 8&lt;/li&gt;
  &lt;li&gt;Переход с CGLIB на &lt;a href=&quot;http://bytebuddy.net/&quot;&gt;ByteBuddy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Мокинг final классов и методов&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ура! Надо брать!&lt;/p&gt;

&lt;p&gt;Какое же меня ждало разочарование…&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;тотальный-облом&quot;&gt;Тотальный облом&lt;/h2&gt;

&lt;p&gt;Я попробовал перевести на Mockito 2.1.0 свой рабочий проект, и … 
облом. Я получил больше 100 красных юнит-тестов (из ~6000).&lt;/p&gt;

&lt;p&gt;Моя первая эмоция - какого чёрта! В топку этот Mockito 2!&lt;/p&gt;

&lt;p&gt;Но при ближайшем рассмотрении оказалось, что Mockito 2 молодец, а вот эти тесты - плохие.
Новый Mockito обнаружил в моих тестах целый ряд проблем, который старый Mockito не замечал. 
Вот оно чо, Мокитыч…&lt;/p&gt;

&lt;h2 id=&quot;что-надо-сделать&quot;&gt;Что надо сделать&lt;/h2&gt;

&lt;p&gt;Ниже - путеводитель по миграции на Mockito 2. 
Протяни руку, читатель, и проведу тебя по этому тернистому пути к счастливому финалу.&lt;/p&gt;

&lt;h3 id=&quot;первым-делом-ты-заменишь-импорты&quot;&gt;Первым делом ты заменишь импорты&lt;/h3&gt;

&lt;p&gt;Много, много импортов. Придётся поменять много файлов.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Matchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Matchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;anyLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Matchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;anyVararg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// не нужен - меняем на any()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;на&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ArgumentMatchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ArgumentMatchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;anyLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;затем-ты-обновишь-api-функции-doanswer&quot;&gt;Затем ты обновишь API функции doAnswer&lt;/h3&gt;

&lt;p&gt;Было:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userDeviceService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;UserDevice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invocation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getArgumentAt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserDevice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Стало (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getArgumentAt&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getArgument&lt;/code&gt;, убираешь класс):&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userDeviceService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invocationOnMock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invocationOnMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getArgument&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;дальше-ты-обновишь-api-ismock&quot;&gt;Дальше ты обновишь API isMock&lt;/h3&gt;

&lt;p&gt;Было:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.mockito.internal.util.MockUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MockUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Стало:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;internal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;MockUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Новый вариант и правда лучше, не поспоришь. Не нужно создавать ненужный объект.&lt;/p&gt;

&lt;h2 id=&quot;на-какие-грабли-ты-наступишь&quot;&gt;На какие грабли ты наступишь&lt;/h2&gt;

&lt;p&gt;При переходе на Mockito 2.1 cотня-другая твоих тестов сломается, потому что:&lt;/p&gt;

&lt;h3 id=&quot;1-матчер-any-больше-не-срабатывает-на-null&quot;&gt;1) Матчер &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any()&lt;/code&gt; больше не срабатывает на &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Раньше это работало:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Теперь не работает, если хотя бы один из параметров - null.
Да-да, мой друг, тебе придётся перелопатить все тесты, которые почему-то 
передают null вместо настоящего значения, и прописать там правильные значения.&lt;/p&gt;

&lt;p&gt;Но это и к лучшему, ведь и правда новый код лучше:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;или, может, так:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;100.00&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;EEK&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Забыл сказать: если там действительно должен передаваться null, то это в тесте надо прописать явно:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isNull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-матчер-anyint-больше-не-срабатывает-на-параметр-типа-long&quot;&gt;2) Матчер anyInt() больше не срабатывает на параметр типа long&lt;/h3&gt;

&lt;p&gt;Работало с Mockito 1.x, падает с Mockito 2.x:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mqService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;transfer-ref&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Для Mockito 2.1 придётся поменять &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyInt()&lt;/code&gt; на &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyLong()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mqService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;transfer-ref&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Да-да, мой друг, тебе придётся перелопатить все тесты, которые вместо long передают int и т.п.
Но это и к лучшему, ведь эти тесты были &lt;strong&gt;неточные&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;3-ты-обнаружишь-у-себя-плохие-тесты&quot;&gt;3) Ты обнаружишь у себя плохие тесты&lt;/h3&gt;

&lt;p&gt;Просто плохие. Негодные. Например, вот такой:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;checkMoratoriumRunsSilentlyWhenNoMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;doReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;parseMoratoriumMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkForMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Какую хрень мы сюда передаём?&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;С Mockito 1.x этот тест работал, а с Mockito 2.1 уже не хочет. И правильно!&lt;/p&gt;

&lt;p&gt;Очевидно, во второй строке хотели использовать &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt;, а не &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkForMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Хотя мы-то с вами понимаем, что тут не нужен ни &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt;, ни &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any&lt;/code&gt;, а достаточно просто создать объекты:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkForMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;4-ты-обнаружишь-у-себя-много-неряшливых-тестов&quot;&gt;4) Ты обнаружишь у себя много неряшливых тестов&lt;/h3&gt;

&lt;p&gt;… которые проверяют лишь часть параметров и не замечают, что остальные - null.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tokenLogin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;login-key&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    
&lt;span class=&quot;n&quot;&gt;security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;login-key&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Как видите, во второй строке тест передаёт параметр &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;. И только &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;. 
Расследование показало, что ни один тест в системе не передавал туда &lt;strong&gt;ничего, кроме null&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Новый тест гораздо точнее, и не нужны все эти &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eq&lt;/code&gt; и &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyString&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;remoteAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;127.0.0.2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;doReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tokenLogin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;login-key&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;127.0.0.2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;5-ты-обнаружишь-мистические-красные-тесты&quot;&gt;5) Ты обнаружишь мистические красные тесты&lt;/h3&gt;

&lt;p&gt;Ты обнаружишь красные тесты, причину падения которых очень сложно раскопать&lt;/p&gt;

&lt;p&gt;Например, такой:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;requestByReferenceNumberNeverCreatesSubscription&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;RequestByReferenceNumber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestByReferenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RequestByReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;12345678901234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gisgmpService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RequestByDrivingLicense&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;requestByReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;GISGMP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;requestCharges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678901234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;С этим я долго провозился. Я не мог понять, почему он перестал работать.&lt;/p&gt;

&lt;p&gt;Обратите внимание на вторую строку. Очевидно, там хотели написать не 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any(RequestByDrivingLicense.class)&lt;/code&gt;, а &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any(RequestByReferenceNumber.class)&lt;/code&gt; (они оба наследуют один суперкласс).&lt;/p&gt;

&lt;p&gt;Это похоже на багу Mockito 1: он позволял использовать &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any(НеверныйКласс.class)&lt;/code&gt;,
и этот некорректный тест оставался зелёным несколько лет. :(&lt;/p&gt;

&lt;h3 id=&quot;6-ты-нарвёшься-на-то-что-anylist-и-anycollection---теперь-разные-вещи&quot;&gt;6) Ты нарвёшься на то, что anyList() и anyCollection() - теперь разные вещи&lt;/h3&gt;

&lt;p&gt;Например, со старым mockito этот тест работал:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;domesticPaymentInForeignCurrencyCanBeEnabled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;doCallRealMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Payments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accountService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forOperation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DOMESTIC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;Collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accountService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forOperation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DOMESTIC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Обратите внимание, что в моке в первой строчке используется &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyList()&lt;/code&gt;, 
а на самом деле передаётся переменная accounts типа &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Collection&lt;/code&gt; (хотя в душе она List).
Mockito 2 больше не позволяет таких шалостей. Изволь прописать &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyCollection()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;и-будешь-доволен-как-слон&quot;&gt;И будешь доволен как слон&lt;/h2&gt;

&lt;p&gt;В общем, мой друг, придётся помучаться, но в конце будешь доволен. 
Тесты стали лучше, мир стал светлее.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/ru&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Migration to Mockito 2.1</title>
   <link href="https://asolntsev.github.io/en/2016/10/11/mockito-2.1/"/>
   <updated>2016-10-11T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2016/10/11/mockito-2.1</id>
   <content type="html">&lt;p&gt;Recently we got a great news.&lt;/p&gt;

&lt;p&gt;They released Mockito 2.1.0 - after so many years of hopeless waiting!&lt;/p&gt;

&lt;p&gt;There is &lt;a href=&quot;https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2&quot;&gt;a lot of cool updates&lt;/a&gt; in Mockito 2, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Support for Java 8&lt;/li&gt;
  &lt;li&gt;Migration from CGLIB to &lt;a href=&quot;http://bytebuddy.net/&quot;&gt;ByteBuddy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mocking final classes and methods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes! I must use it! - I decided.&lt;/p&gt;

&lt;p&gt;What a huge disappointment it was for me…&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;epic-fail&quot;&gt;Epic fail&lt;/h2&gt;

&lt;p&gt;I tried to upgrade my working project to Mockito 2.1.0, and …
 ups.&lt;/p&gt;

&lt;p&gt;I got over 100 red tests (from ~6000).&lt;/p&gt;

&lt;p&gt;My first emotion was - what the hell! Mockito 2 sucks!&lt;/p&gt;

&lt;p&gt;But the further investigation showed that Mockito 2 is cool, but some of my tests are bad.
The new Mockito found a whole bunch of problems in our tests.&lt;/p&gt;

&lt;p&gt;Let’s discover them together.&lt;/p&gt;

&lt;h2 id=&quot;what-you-need-to-do&quot;&gt;What you need to do&lt;/h2&gt;

&lt;p&gt;Below you can find my tutorial for migration to Mockito 2.&lt;/p&gt;

&lt;p&gt;Let’s start!&lt;/p&gt;

&lt;h3 id=&quot;first-you-will-need-to-replace-import&quot;&gt;First, you will need to replace import&lt;/h3&gt;

&lt;p&gt;A lot of imports. In many files. Replace these lines:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Matchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Matchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;anyLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Matchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;anyVararg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// not needed - replaced by any()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;by these lines:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ArgumentMatchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ArgumentMatchers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;anyLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;second-you-will-update-api-of-doanswer&quot;&gt;Second, you will update API of doAnswer&lt;/h3&gt;

&lt;p&gt;Was:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userDeviceService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;UserDevice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invocation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getArgumentAt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserDevice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userDeviceService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invocationOnMock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invocationOnMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getArgument&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getArgumentAt&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getArgument&lt;/code&gt;, remove the class)&lt;/p&gt;

&lt;h3 id=&quot;third-you-update-api-of-ismock&quot;&gt;Third, you update API of isMock&lt;/h3&gt;

&lt;p&gt;Was:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.mockito.internal.util.MockUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MockUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mockito&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;internal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;MockUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The last version is really better, don’t you think?
No need to create an unused object.&lt;/p&gt;

&lt;h2 id=&quot;what-problems-you-will-experience&quot;&gt;What problems you will experience&lt;/h2&gt;

&lt;p&gt;Some of your tests will break when you upgrade to Mockito 2.1.
Below you will find some of the reasons.&lt;/p&gt;

&lt;h3 id=&quot;1-matcher-any-does-not-match-null-anymore&quot;&gt;1) Matcher &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any()&lt;/code&gt; does not match &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; anymore&lt;/h3&gt;

&lt;p&gt;This code worked before:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But doesn’t work anymore, if some of parameters are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;.
Yes, my friend! You will need to rework &lt;strong&gt;all your tests&lt;/strong&gt; that pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; 
instead of realistic value.&lt;/p&gt;

&lt;p&gt;And it’s great, because the new code is really better:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or this way:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;100.00&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;EEK&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you really need to pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; parameter, you can still do it. 
Just pass null explicitly using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isNull&lt;/code&gt; matcher:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doNothing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;calculateAmounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isNull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-matcher-anyint-does-not-match-long-anymore&quot;&gt;2) Matcher anyInt() does not match long anymore&lt;/h3&gt;

&lt;p&gt;This code worked with Mockito 1.x, but fails with Mockito 2.x:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mqService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;transfer-ref&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You need to replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyInt()&lt;/code&gt; by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyLong()&lt;/code&gt; for Mockito 2.1:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mqService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;transfer-ref&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Yes, my friend. You will need to rework &lt;strong&gt;all your tests&lt;/strong&gt; that pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long&lt;/code&gt; etc.
But it’s great, don’t you think?
Because these tests were &lt;strong&gt;inaccurate&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;3-you-will-discover-bad-tests&quot;&gt;3) You will discover bad tests&lt;/h3&gt;

&lt;p&gt;Yes, my friend. You will discover lot of bad lines among your tests. Just bad.
Like this one:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;checkMoratoriumRunsSilentlyWhenNoMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;doReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;parseMoratoriumMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkForMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// WHAAAAAAAT?&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code worked with Mockito 1.x. Suddenly.
But it fails with Mockito 2.1 - and it’s great, don’t you think?&lt;/p&gt;

&lt;p&gt;Obviously, we should use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any&lt;/code&gt; in the second line:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkForMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;By the way, even better solution is to avoid both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any&lt;/code&gt; and just create plain objects:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;checkForMoratorium&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Mandate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoanApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;4-you-will-discover-a-lot-of-sloppy-tests&quot;&gt;4) You will discover a lot of sloppy tests&lt;/h3&gt;

&lt;p&gt;… that check only &lt;strong&gt;some&lt;/strong&gt; parameters and don’t discover that others are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;doReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tokenLogin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;login-key&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    
&lt;span class=&quot;n&quot;&gt;security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;login-key&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you see, tests passes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; parameter in the second line. And only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;!
I discovered that there was no test that would pass something different from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; there.&lt;/p&gt;

&lt;p&gt;Mockito 2.1 will fail with such a sloppy test, because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyString()&lt;/code&gt; matcher doesn’t allow &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; anymore.&lt;/p&gt;

&lt;p&gt;The newer test that works with Mockito 2.1 is actually more precise:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;remoteAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;127.0.0.2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;doReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tokenLogin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;login-key&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;127.0.0.2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You see it? You don’t need all these obscure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eq&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyString&lt;/code&gt;. Much better!&lt;/p&gt;

&lt;h3 id=&quot;5-you-will-discover-mystical-red-tests&quot;&gt;5) You will discover mystical red tests&lt;/h3&gt;

&lt;p&gt;You will find some red tests for which it’s really hard to understand why they fail.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;requestByReferenceNumberNeverCreatesSubscription&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;RequestByReferenceNumber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestByReferenceNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RequestByReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;12345678901234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gisgmpService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RequestByDrivingLicense&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;thenReturn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;requestByReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;GISGMP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;requestCharges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678901234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It took quite a long time to solve this issue. 
I could not find out why this test started to fail with Mockito 2.&lt;/p&gt;

&lt;p&gt;Please note the second line. Obviously authors wanted to write 
 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any(RequestByReferenceNumber.class)&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any(RequestByDrivingLicense.class)&lt;/code&gt; 
 (they both inherit the same superclass).&lt;/p&gt;

&lt;p&gt;It seems to be a bug of Mockito 1: it allowed using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any(AWrongClass.class)&lt;/code&gt;,
and this incorrect test have been green for several years. :(&lt;/p&gt;

&lt;h3 id=&quot;6-you-will-find-out-that-anylist-and-anycollection-are-now-different-things&quot;&gt;6) You will find out that anyList() and anyCollection() are now different things&lt;/h3&gt;

&lt;p&gt;For example, this code worked with Mockito 1:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;domesticPaymentInForeignCurrencyCanBeEnabled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;doCallRealMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Payments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accountService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forOperation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DOMESTIC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;Collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accountService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forOperation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DOMESTIC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that mock in the first line uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyList()&lt;/code&gt;, but the code 
actually passes variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accounts&lt;/code&gt; of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Collection&lt;/code&gt; (thought it’s actually List).&lt;/p&gt;

&lt;p&gt;Mockito 2 doesn’t allow it anymore. You need to mock more precisely using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyCollection()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;and-you-will-be-happy&quot;&gt;And you will be happy&lt;/h2&gt;

&lt;p&gt;To summarize: you will see a lot of pain, but you will become happy.
The tests got better, the world got lighter.&lt;/p&gt;

&lt;p&gt;Peace 2.1.0!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Andrei Solntsev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/en&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Spring boobs</title>
   <link href="https://asolntsev.github.io/ru/2016/10/03/spring-boobs/"/>
   <updated>2016-10-03T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2016/10/03/spring-boobs</id>
   <content type="html">&lt;p&gt;Шесть лет назад я писал энтерпрайзный проект на Spring framework.&lt;/p&gt;

&lt;p&gt;Мы все считали, что Spring - это кровавый энтерпрайз.&lt;/p&gt;

&lt;p&gt;Мы хотели избавиться от этого бойлерплейта.&lt;/p&gt;

&lt;p&gt;Мы были молоды, мы были горячи, мы хотели перемен.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;и-понеслось&quot;&gt;И понеслось!&lt;/h2&gt;

&lt;p&gt;В 2010 я попал в фирму Codeborne, в которой у нас появилась свобода делать 
проекты на всём, чём душа пожелает.&lt;/p&gt;

&lt;p&gt;Моя душа желала много и разнообразно.&lt;/p&gt;

&lt;p&gt;С тех пор я успел поделать проекты на:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;на Struts2 (Java),&lt;/li&gt;
  &lt;li&gt;на Play 1 framework (Java),&lt;/li&gt;
  &lt;li&gt;на Ruby (Sinatra),&lt;/li&gt;
  &lt;li&gt;на Scala (Scalatra),&lt;/li&gt;
  &lt;li&gt;на Groovy,&lt;/li&gt;
  &lt;li&gt;на Python (Tornado framework),&lt;/li&gt;
  &lt;li&gt;на Kotlin,&lt;/li&gt;
  &lt;li&gt;на Ratpack,&lt;/li&gt;
  &lt;li&gt;на Vert.x,&lt;/li&gt;
  &lt;li&gt;и даже, прости господи, на PHP!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;и-что-теперь&quot;&gt;И что теперь&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Разочаровавшись из-за медленной компиляции Scala,&lt;/li&gt;
  &lt;li&gt;помудохавшись со скриптами Groovy, которые ничерта не поддерживаются никакими IDE,&lt;/li&gt;
  &lt;li&gt;поогрёбши багов с динамическим Питоном, у которого все библиотеки ломаются при малейшем апгрейде,&lt;/li&gt;
  &lt;li&gt;натёрши мозоли на кнопках s, e, l, f - потому что в Python, сцуко, надо везде писать &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self.&lt;/code&gt; при вызове абсолютно любых методов!&lt;/li&gt;
  &lt;li&gt;поматерившись на Ruby, который влёгкую ломается из-за одной случайной строчки чёртового комментария в одной случайной чёртовой зависимости,&lt;/li&gt;
  &lt;li&gt;и - не побоюсь этого слова - понатрахавшись в многочасовых ночных 
дебагах с &lt;a href=&quot;https://www.youtube.com/watch?v=Wi3uLRlOWeU&quot;&gt;многочисленными извращённейшими косяками Play framework&lt;/a&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;я стал искать что-то стабильное.&lt;/p&gt;

&lt;p&gt;Что-то, на что можно положиться.&lt;/p&gt;

&lt;p&gt;Что-то, что просто работает и делает то, что мне надо.&lt;/p&gt;

&lt;h2 id=&quot;и-вот&quot;&gt;И вот…&lt;/h2&gt;

&lt;p&gt;И я снова попробовал Spring framework.&lt;/p&gt;

&lt;p&gt;Решил дать ему второй шанс.&lt;/p&gt;

&lt;p&gt;И оказалось, что&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;бойлерплейта в нём ничуть не больше, чем в Struts2.&lt;/li&gt;
  &lt;li&gt;он умеет перегружать классы на лету &lt;strong&gt;гораздо лучше&lt;/strong&gt;, чем Play framework.&lt;/li&gt;
  &lt;li&gt;естественно, в нём всё логируется, записывается, загружается и читается из коробки. 
Без багов. Без косяков. Без неожиданностей. Без чёрной магии.&lt;/li&gt;
  &lt;li&gt;в нём почти невозможно писать спагетти код, потому что архитектура 
почти заставляет тебя всё делать правильно: сервисы, репозитории, 
идеальный dependency injection - тут просто негде накосячить.&lt;/li&gt;
  &lt;li&gt;в нём всё сделано для того, чтобы нам было легко писать автотесты.
    &lt;ul&gt;
      &lt;li&gt;И юнит-тесты, и интеграционные. В одну команду - взлетает база данных, тестирует твой селект, умирает.&lt;/li&gt;
      &lt;li&gt;И даже UI-тесты. В одну команду - взлетает приложение с БД, открывается браузер, всё прокликивается, умирает.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;и вопреки легендам, в нём не нужен никакой чёртов XML.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Кто-нибудь помнит, за что мы тогда не взлюбили Spring?&lt;/p&gt;

&lt;h2 id=&quot;короче&quot;&gt;Короче&lt;/h2&gt;

&lt;p&gt;Может, это старость, но сейчас я готов сказать, что Spring framework - это
лучший фреймворк на свете. Лучше всего того, что было создано после него.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Пойду пересмотрю “Москва слезам не верит”.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/ru&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Spring boobs</title>
   <link href="https://asolntsev.github.io/en/2016/10/03/spring-boobs/"/>
   <updated>2016-10-03T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2016/10/03/spring-boobs</id>
   <content type="html">&lt;p&gt;Six years ago I developed an enterprise project with Spring framework.&lt;/p&gt;

&lt;p&gt;We believed that Spring is a bloody enterprise.&lt;/p&gt;

&lt;p&gt;We wanted to get rid of this boilerplate.&lt;/p&gt;

&lt;p&gt;We were young and courage, we wanted changes.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;and-it-began&quot;&gt;And it began!&lt;/h2&gt;

&lt;p&gt;At year 2010 I got to Codeborne company where we got a freedom to use whatever tools we wanted.&lt;/p&gt;

&lt;p&gt;I wanted a lot of very different tools.&lt;/p&gt;

&lt;p&gt;Meanwhile I developed projects with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Struts2 (Java),&lt;/li&gt;
  &lt;li&gt;Play 1 framework (Java),&lt;/li&gt;
  &lt;li&gt;Ruby (Sinatra),&lt;/li&gt;
  &lt;li&gt;Scala (Scalatra),&lt;/li&gt;
  &lt;li&gt;Groovy,&lt;/li&gt;
  &lt;li&gt;Python (Tornado framework),&lt;/li&gt;
  &lt;li&gt;Kotlin,&lt;/li&gt;
  &lt;li&gt;Ratpack,&lt;/li&gt;
  &lt;li&gt;Vert.x,&lt;/li&gt;
  &lt;li&gt;and even PHP!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;and-what-now&quot;&gt;And what now?&lt;/h2&gt;

&lt;p&gt;Disappointed with&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;slow compilation Scala;&lt;/li&gt;
  &lt;li&gt;Groovy scripts that are not supported well by any IDE;&lt;/li&gt;
  &lt;li&gt;dynamic Python that fails with any upgrade;&lt;/li&gt;
  &lt;li&gt;annoying keyword &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self.&lt;/code&gt; that you must write in Python before every method call;&lt;/li&gt;
  &lt;li&gt;Ruby that can be broken by single random comment line in single random dependency;&lt;/li&gt;
  &lt;li&gt;endless night debugging sessions with &lt;a href=&quot;https://www.youtube.com/watch?v=Wi3uLRlOWeU&quot;&gt;unbelievably crazy Play framework bugs&lt;/a&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I started to look for something stable.&lt;/p&gt;

&lt;p&gt;Something that I could rely on.&lt;/p&gt;

&lt;p&gt;Something that simply works.&lt;/p&gt;

&lt;h2 id=&quot;and-then&quot;&gt;And then…&lt;/h2&gt;

&lt;p&gt;I decided to try Spring framework once again.&lt;/p&gt;

&lt;p&gt;I decided to give it a chance.&lt;/p&gt;

&lt;p&gt;And I found that&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;it contains no more boilerplate than Struts2 framework.&lt;/li&gt;
  &lt;li&gt;it can reload classes on the fly &lt;strong&gt;much better&lt;/strong&gt; than Play framework.&lt;/li&gt;
  &lt;li&gt;it can log, save, and load data out of the box. With no bugs. With no issues. With no unexpected behaviour. With no black magic.&lt;/li&gt;
  &lt;li&gt;it almost doesn’t allow you to write spaghetti code because built-in architecture 
forces you to write good code: all these services, repositories, 
ideally implemented dependency injection - it’s just impossible to make it bad.&lt;/li&gt;
  &lt;li&gt;it does everything to allow you easily write automated tests.
    &lt;ul&gt;
      &lt;li&gt;Both unit-tests and integration. With just one command - runs database, tests your select and dies.&lt;/li&gt;
      &lt;li&gt;And even UI tests. With just one command - runs application with database, opens a browsers, clicks the buttons and dies.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;and finally, it does not need any XML.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does anybody still remember what we didn’t love Spring six years ago?&lt;/p&gt;

&lt;h2 id=&quot;finally&quot;&gt;Finally&lt;/h2&gt;

&lt;p&gt;Maybe I am just getting old, but now I am ready to say that Spring is the best framework in the world.
Better than anything that was created after it.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Andrei Solntsev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/en&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>О Legacy-коде</title>
   <link href="https://asolntsev.github.io/ru/2016/08/26/legacy-code/"/>
   <updated>2016-08-26T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2016/08/26/legacy-code</id>
   <content type="html">&lt;p&gt;Моё интервью для jug.ru &lt;a href=&quot;https://habrahabr.ru/company/jugru/blog/308528/&quot;&gt;о Legacy-коде без максимализма: что делать&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Про TDD, спорт, Шелока Холмса и реальных пацанов.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>About Legacy code</title>
   <link href="https://asolntsev.github.io/en/2016/08/26/legacy-code/"/>
   <updated>2016-08-26T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2016/08/26/legacy-code</id>
   <content type="html">&lt;p&gt;My interview for jug.ru &lt;a href=&quot;https://habrahabr.ru/company/jugru/blog/308528/&quot;&gt;About Legacy code without maximalism&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Including: TDD, sport, Sherlock Holmes and real men.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Почему разработчики должны быть хорошими тестировщиками</title>
   <link href="https://asolntsev.github.io/ru/2016/08/05/why-programmer-cannot-be-true-tester/"/>
   <updated>2016-08-05T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2016/08/05/why-programmer-cannot-be-true-tester</id>
   <content type="html">&lt;p&gt;Это мой ответ на статью о том, &lt;a href=&quot;http://software-testing.ru/library/testing/general-testing/2277-why-cant-developers-be-good-testers&quot;&gt;почему разработчики не могут быть хорошими тестировщиками&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;вы можете научить собаку нескольким трюкам, но вы уж точно не сможете научить ее летать.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Всё это полная ерунда!
Собаку нельзя научить летать, потому что она физически по-другому устроена.
А разработчики и тестировщики устроены ОДИНАКОВО!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;По каждому приведённому пункту: если это могут тестировщики, то смогут и разработчики.&lt;/p&gt;

&lt;h3 id=&quot;1-родительские-чувства-к-коду&quot;&gt;1. “Родительские чувства” к коду&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;Разработчики привязаны к тому, что они пишут. Может быть это прозвучит глупо, но очень сложно оценивать объективно то, что ты создаешь.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Вы могли обратить внимание на то, что нормальный родитель относится к своим детям наиболее требовательно. Я хочу, чтобы код - моё детище - хорошо работало, и чтобы ни у кого не было ни малейшей причины его критиковать. Поэтому я очень хочу найти в нём баги.&lt;/p&gt;

&lt;h3 id=&quot;2-акцентирование-на-позитивных-моментах&quot;&gt;2. Акцентирование на позитивных моментах&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;Работа разработчика основывается на позитивных сценариях и их реализации в продукте. Чтобы работать тестировщиком нужно иметь диаметрально противоположный склад ума, так как тестировщики всегда акцентируются на негативных сторонах продукта нежели чем на позитивных. Следовательно разработчику нужно поменять склад ума, чтобы стать тестировщиком, а это не кажется столь реальным на мой взгляд.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Это правда, в период “созидания” я концентрируюсь на том, как СДЕЛАТЬ. 
Но я никогда на этом не заканчиваю. Потом наступает следующий период, когда я пересматриваю и улучшаю код, иногда по много раз. Перепроверяю и дописываю тесты. Критически думаю, а что там может СЛОМАТЬСЯ. Ведь я не хочу, чтобы моё детище критиковали.&lt;/p&gt;

&lt;p&gt;Если разработчик после первого этапа считает дело сделанным, то это не разработчик, а ребёнок. Не надо по ним судить.&lt;/p&gt;

&lt;h3 id=&quot;3-работа-на-основе-принципа-упрощения-сложных-вещей&quot;&gt;3. Работа на основе принципа упрощения сложных вещей&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;Рассматривание сложных сценариев с целью нахождения багов является одной из составляющих процесса тестирования. В двух словах мы берем простую вещь и придумываем как ее можно усложнить.
  Разработчики поступают ровно наоборот. Они берут сложный процесс или проект и разбивают его на более мелкие компоненты с целью найти решение проблемы.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ровно то же самое, что п. 2. Вначале я упрощаю, потом усложняю.&lt;/p&gt;

&lt;h3 id=&quot;4-неспособность-видеть-мелкие-детали-на-большой-картине&quot;&gt;4. Неспособность видеть мелкие детали на большой картине&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;Одним из основных качеств любого тестировщика является умение определить что не так на этой картине. Разработчики говорят, что у тестировщиков нюх на баги. Возможно это утверждение не так далеко от истины.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Это правда, такая проблема часто есть у разработчиков. Но если это могут сделать тестировщики, то могут и разработчики. У них точно такой же мозг.&lt;/p&gt;

&lt;p&gt;Да не просто могут, а обязаны! 
Как иначе без видения общей картины они смогут хорошо спроектировать программу?&lt;/p&gt;

&lt;p&gt;Если они сделают программу без учёта всего этого, а потом придут тестировщики и скажут, что не годится - это будет
СЛИШКОМ ПОЗДНО! Придётся переписывать и потратить вдвое больше времени.&lt;/p&gt;

&lt;h3 id=&quot;5-недостаток-опыта-работы-с-типичными-багами-и-программными-ошибками&quot;&gt;5. Недостаток опыта работы с типичными багами и программными ошибками&lt;/h3&gt;
&lt;blockquote&gt;
  &lt;p&gt;Все приходит с опытом, и знание типичных багов и программных ошибок не исключение. Опытный тестировщик видит форму и сразу начинает думать какие типичные баги там могут скрываться и что следовательно может быть протестировано в первую очередь.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Да с какой это стати недостаток? Почему?
За всю свою карьеру я сделал такое множество багов, что опыта работы с ними хоть отбавляй.&lt;/p&gt;

&lt;p&gt;Я думаю, разработчики всё это прекрасно могут, но обычно не хотят. Тупо лень. 
А лень потому, что они знают, что они не последний рубеж. 
За ними есть ещё обезьянки-тестировщики, которые налетят и за них их работу сделают.&lt;/p&gt;

&lt;p&gt;В итоге всем хуже: разработчики сильно не напрягаются, не очень хорошо продумывают дизайн программы, 
не продумывают все крайние случаи, не пишут юнит-тесты. 
Проблемы растут лавинообразно, и тестировщики не могут их всех сдержать.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Тестировщики не могут обнаружить все неучтённые кейсы. Лишь некоторые.&lt;/li&gt;
  &lt;li&gt;Тестировщики не могут найти все баги. Лишь некоторые. Вы знаете, некоторые баги невозможно повторить.&lt;/li&gt;
  &lt;li&gt;Тестировщики-автоматизаторы не могут покрыть интеграционными тестами всё, что должно 
было быть покрыто юнит-тестами. Вы знаете, некоторые баги вообще невозможно покрыть интеграционными тестами, только юнит.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Мир катится в пропасть.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/ru&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Настоящие пэдж-объекты</title>
   <link href="https://asolntsev.github.io/ru/2016/07/09/true-page-object/"/>
   <updated>2016-07-09T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2016/07/09/true-page-object</id>
   <content type="html">&lt;p&gt;Недавно я писал о том, &lt;a href=&quot;/2016/07/08/what-is-hardcode/&quot;&gt;что на самом деле нельзя хардкодить&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Давайте рассмотрим этот принцип на примере пэдж объектов.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;классический-пэдж-обжект&quot;&gt;Классический пэдж обжект&lt;/h3&gt;

&lt;p&gt;У тестировщиков-автоматизаторов очень популярен паттерн “Пэдж Обжект”. 
Собственно, это самый популярный в мире объект поклонения после статуи Будды в Лэшане и Шестого Айфона.&lt;/p&gt;

&lt;p&gt;Суть его в том, что все селекторы, по которым ищутся элементы на веб-страничке тестируемого приложения,
выносятся… точно, в константы:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RegistrationPage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@FindBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;firstName&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@FindBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;lastName&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@FindBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;birthday&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WebElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Красиво, да?
Такие пэдж объекты хороши тем, что один и тот же локатор не приходится дублировать в сотне разных тестов. 
Когда локатор меняется, его нужно поменять всего в одном месте.&lt;/p&gt;

&lt;p&gt;А тесты не нужно часто менять, потому что они используют пэдж объект:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;userCanRegister&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;RegistrationPage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RegistrationPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Bruce&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Willis&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;19.03.1955&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Такой подход стал особенно популярен с лёгкой руки Мартина Фаулера, 
который выдумал Золотое Правило Автоматизаторов:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;В тесте не должно быть ни одного локатора. Локаторы должны быть спрятаны в пэдж объектах. 
Если в тесте виден локатор - это негодный тест.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;в-чём-же-подвох&quot;&gt;В чём же подвох?&lt;/h3&gt;

&lt;p&gt;Мы забываем, что меняются не только локаторы. 
Как я рассказывал в &lt;a href=&quot;/2016/07/08/what-is-hardcode/&quot;&gt;изначальной статье&lt;/a&gt;, меняется логика работы с элементами. 
Допустим, есть у вас сотня тестов, в которых есть такая строчка:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;19.03.1955&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Да, типа хорошо, если меняется локатор - сотня тестов останется нетронутой.&lt;/p&gt;

&lt;p&gt;Но что если этот элемент из &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;input&amp;gt;&lt;/code&gt; вдруг превратиться в контрол типа “календарь”? 
Знаете, в котором нужно сначала кликнуть иконку календаря, потом выбрать год, потом месяц, и только потом день.&lt;/p&gt;

&lt;p&gt;Упс!&lt;/p&gt;

&lt;p&gt;Теперь вам придётся перелопатить всю сотню тестов. 
Да ещё и разобраться хорошенько, в каких нужно выбирать год, а в каких не нужно. 
В каких нужно менять месяц, а в каких не нужно. И как эти тесты будут работать в последний день месяца или года.&lt;/p&gt;

&lt;p&gt;Упс!
Всё пропало, шеф!&lt;/p&gt;

&lt;h2 id=&quot;что-же-делать&quot;&gt;Что же делать?&lt;/h2&gt;

&lt;p&gt;Вот тут и вступает в силу правило: выносить нужно не константы, а логику.
В пэдж объекте должно быть не поле &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;birthday&lt;/code&gt;, а &lt;strong&gt;метод&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RegistrationPage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enterBirthday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  
    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;birthday&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  
    &lt;span class=&quot;c1&quot;&gt;// а потом - вся логика календаря здесь&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вот теперь действительно, если поменяется логика работы с элементом “birthday” (в том число локатор!), 
ни один тест не поменяется - только пэдж объект.&lt;/p&gt;

&lt;p&gt;Понятное дело, в этом случае поля пэдж объекта должны быть приватными, чтобы
никто не мог использовать их напрямую, а только через методы пэдж объекта.&lt;/p&gt;

&lt;p&gt;Ну а в случае Selenide поля так и вовсе становятся ненужными, ведь 
гораздо легче использовать доллар (как в примере выше).&lt;/p&gt;

&lt;p&gt;Вот это труёвый пэдж объект!&lt;/p&gt;

&lt;h2 id=&quot;контрольный-в-мозг&quot;&gt;Контрольный в мозг&lt;/h2&gt;

&lt;p&gt;Давайте проверим, что мы понимаем друг друга правильно.
Если вы согласны с приведёнными выше доводами, то вы тоже считаете, что аннотации &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@FindBy&lt;/code&gt; не нужны, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PageFactory&lt;/code&gt; не нужна.
И инифиализировать пэдж-обжект нужно только с помощью конструктора:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;MyPage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Никаких фабрик, аннотаций и другой чёртовой магии.
Она точно добавляет сложности и точно не решает никаких проблем.&lt;/p&gt;

&lt;p&gt;А если уж по чесноку, я думаю, что пэдж обжекты вообще не нужны. Но об этом отдельная статья.&lt;/p&gt;

&lt;p&gt;Автоматизируйте с умом, други, и не забывайте главное правило из книжки “Design patterns”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Объект - это не данные и операции с ними (как учат в школе).&lt;br /&gt;
Объект - это &lt;em&gt;поведение&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/ru&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Что на самом деле нельзя хардкодить</title>
   <link href="https://asolntsev.github.io/ru/2016/07/08/what-is-hardcode/"/>
   <updated>2016-07-08T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2016/07/08/what-is-hardcode</id>
   <content type="html">&lt;h3 id=&quot;хардкод&quot;&gt;Хардкод&lt;/h3&gt;

&lt;p&gt;Это страшное слово - хардкод. Все боятся это сделать, но иногда каждый из нас это делает.&lt;/p&gt;

&lt;p&gt;Но я утверждаю, что хардкод в привычном нам понимании вовсе не так уж страшен, 
и на самом деле гораздо страшнее, когда в коде прописывают &lt;em&gt;кое-что иное&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Так что же на самом деле нельзя хардкодить?&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;классический-хардкод&quot;&gt;Классический хардкод&lt;/h3&gt;

&lt;p&gt;Все обычно считают, что&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Нельзя хардкодить числа в коде! Надо вынести в константу.&lt;/li&gt;
  &lt;li&gt;Нельзя хардкодить настройки в коде! Надо вынести в файл с настройками (а у некоторых и в базу данных).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;То есть если джуниор девелопер напишет в коде &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (age &amp;gt;= 23)&lt;/code&gt;, ему за это надо дать по рукам.
Так обычно считается.
Чтобы сберечь руки, он должен срочно вынести “23” в константу типа &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MINIMUM_LOAN_AGE&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;давайте-разбираться-в-причинах&quot;&gt;Давайте разбираться в причинах&lt;/h3&gt;

&lt;p&gt;А почему плохо прописать в коде “23”?&lt;/p&gt;

&lt;p&gt;Обычно называют две причины. Их втирают нам в сознание ещё с университетской скамьи.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Когда нужно будет поменять “23” на “24”, её придётся поменять во многих файлах - трудоёмко.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Само по себе “23” плохо читается. Что означает “23” - возраст, длину волос, объём бензобака?
Почему именно 23, а не 22 или 24?&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;почему-эти-причины-не-катят&quot;&gt;Почему эти причины не катят?&lt;/h3&gt;

&lt;p&gt;Эти причины настолько нам привычны, что мы даже не задумываемся, насколько они актуальны в наше время. 
Вы удивитесь, но не очень-то актуальны. Прямо скажем, они &lt;em&gt;устарели&lt;/em&gt;. Смотрите сами.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Во всех современных IDE очень легко поменять “23” на “24”. Одной кнопкой. Ctrl+R -&amp;gt; Enter. Всё. 
Хоть у тебя в проекте три файла, хоть три миллиона.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Да, “23” плохо читается. Но часто при вынесении в константу оно не становится более читаемым. 
Да, название константы &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MINIMUM_LOAN_AGE&lt;/code&gt; говорит о том, что это минимальный возраст, с которого можно
брать кредит. Но и выражение &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (age &amp;gt;= 23)&lt;/code&gt; в методе &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canRequestLoan()&lt;/code&gt; говорит ровно о том же ничуть не хуже.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;А почему именно 23, почему не 22 или 24 - это всё равно непонятно.
Чтобы это узнать, в наше время легче заглянуть в историю изменений (git -&amp;gt; annotate)
или в тесты (Ctrl+Shift+T) - с нашими IDE это легко.&lt;/p&gt;

&lt;h3 id=&quot;ладно-ладно&quot;&gt;Ладно, ладно&lt;/h3&gt;

&lt;p&gt;Я знаю, вас переполняют эмоции. Вы хотели бы вбить мне в грудь осиновый кол за такую ересь.
Но потерпите, сейчас мы дойдём до главного.&lt;/p&gt;

&lt;p&gt;Конечно, всё-таки выносить такие штуки в константы иногда полезно.&lt;/p&gt;

&lt;p&gt;НО&lt;/p&gt;

&lt;p&gt;Я хотел сказать, что самый страшный хардкод - это &lt;em&gt;вовсе не константы&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;а-что-же---самый-страшный-хардкод&quot;&gt;А что же - самый страшный хардкод?&lt;/h3&gt;

&lt;p&gt;Вглядитесь внимательно в это выражение. Все обычно думают, что самый страшный хардкод - это вот:
&lt;img src=&quot;/public/img/hardcode-constant.jpg&quot; alt=&quot;Hardcode&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Но вглядитесь, неужели это действительно самое страшное место? Оглядитесь вокруг, не притаилось ли рядом что-то более опасное?
На самом деле самая страшная часть - это вот:
&lt;img src=&quot;/public/img/hardcode-logic.jpg&quot; alt=&quot;Hardcode&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Потому, что вот её-то поменять во всём коде на порядок сложнее.
Когда однажды выяснится, что для получения кредита нужно стать старше 23 лет, да ещё и найти работу,
нам придётся найти в коде все места, где прописано &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (age &amp;gt;= 23)&lt;/code&gt; и поменять их на 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (age &amp;gt; 23 &amp;amp;&amp;amp; employed)&lt;/code&gt;. Но как найти все знаки все знаки &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;=&lt;/code&gt;? Их же тысячи! Вот это ручная работа на столетия!&lt;/p&gt;

&lt;p&gt;Но самое страшное, что в коде могут быть и выражения вида&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (!(age &amp;lt; 23))&lt;/code&gt;, и&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (23 &amp;gt; age)&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;и даже такие места, которые совсем нереально обнаружить:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// 100500 строк кода&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// можно получить кредит&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;что-же-делать&quot;&gt;Что же делать?&lt;/h3&gt;

&lt;p&gt;Вот почему важно выносить не константы, а логику.
Важно следить, чтобы любое знание в коде было прописано ровно в одном месте.
В данном случае - знание о том, в каких случаях клиент может взять кредит (то самое &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;= 23&lt;/code&gt;) 
должно быть вынесено в отдельный метод.&lt;/p&gt;

&lt;p&gt;Например, так:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;canRequestLoan&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И все остальные места должны использовать этот метод. 
Кажется тривиальным? О нет.
Если это знание действительно в одном месте, зачем вы так рьяно хотите вынести “23” в константу?&lt;/p&gt;

&lt;h3 id=&quot;упростим&quot;&gt;Упростим&lt;/h3&gt;

&lt;p&gt;Всё ещё кажется тривиальным?
Ок, давайте упростим пример. Забудьте 23. Пусть будет 0.&lt;/p&gt;

&lt;p&gt;Я уверен, в вашем коде миллион таких мест:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;balance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// могу сделать платёж&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И я таких видел миллион. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if balance &amp;gt; 0&lt;/code&gt; прописан и на странице 
платежей, и на странице кредитов, и депозитов, и т.д.&lt;/p&gt;

&lt;p&gt;Но однажды приходит новое требование: клиент не может сделать платёж, если на его счёт наложен арест.
Нам приходится добавить условие типа такого:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;balance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;arrested&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// могу сделать платёж&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Но тут… опачки. Оказывается, что в десяти местах прописано &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (balance &amp;gt; 0)&lt;/code&gt;, в ещё двадцати - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (balance &amp;lt;= 0)&lt;/code&gt;,
а в грёбаном яваскрипте и вовсе &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (account.balance)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;И вот тут-то начинаются проблемы. Все эти места нужно анализировать отдельно. 
В некоторые из них нужно добавить &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&amp;amp; !arrested&lt;/code&gt;, а в некоторые не нужно - ведь там речь идёт не о платежах.&lt;/p&gt;

&lt;p&gt;Я не придумываю, это абсолютно &lt;a href=&quot;/2011/03/03/wtf-is-business-logic/&quot;&gt;реальный пример&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;юнит-тесты&quot;&gt;Юнит-тесты&lt;/h3&gt;

&lt;p&gt;Очевидный плюс вынесения логики в методы - её легко тестировать.&lt;/p&gt;

&lt;p&gt;Поначалу этот тест кажется даже избыточным и даже бесполезным:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccountTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;canMakePaymentIfHasMoney&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;canMakePayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;canMakePayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Но всё меняется, как только добавляются ньвые требования:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccountTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;canMakePayment_ifHasMoney_and_notArrested&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;canMakePayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cannotMakePaymentIfHasNoMoney&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;canMakePayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cannotMakePaymentIfArrested&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;canMakePayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;пэдж-обжекты&quot;&gt;Пэдж обжекты&lt;/h3&gt;

&lt;p&gt;Всё ещё кажется, что для разумных людей это очевидные вещи?&lt;/p&gt;

&lt;p&gt;Тогда посмотрите на &lt;a href=&quot;/2016/07/09/true-page-object/&quot;&gt;пэдж обжекты&lt;/a&gt; - воплощение константного антипаттерна во всей красе!
Миллионы людей выносят локаторы в константы и даже не задумываются, что что-то здесь не так…&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io/ru&quot;&gt;asolntsev.github.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Как Java8 может помочь в написании юнит-тестов</title>
   <link href="https://asolntsev.github.io/ru/2016/04/11/unit-tests-with-java8/"/>
   <updated>2016-04-11T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2016/04/11/unit-tests-with-java8</id>
   <content type="html">&lt;h3 id=&quot;проблема&quot;&gt;Проблема&lt;/h3&gt;

&lt;p&gt;Как правило, для тестов нужно создавать много разных объектов с самыми разными состояниями. 
Не всегда есть подходящие конструкторы, и плодить их особо не хочется.&lt;/p&gt;

&lt;p&gt;И вот тут неожиданно на помощь приходит Java 8!
Казалось бы, при чём тут?&lt;/p&gt;

&lt;p&gt;А вот при чём.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;как-решается-сейчас&quot;&gt;Как решается сейчас&lt;/h3&gt;

&lt;p&gt;Допустим, есть у вас класс &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Employee&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Gender&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;В некоторых тестах нас интересуют только имя, в некоторых - только дата рождения, где-то только пол, 
а в большинстве - различные комбинации того и другого.&lt;/p&gt;

&lt;p&gt;Как создавать кучу таких разных объектов в тестах?&lt;/p&gt;

&lt;p&gt;Обычно есть четыре варианта, и все они не очень.&lt;/p&gt;

&lt;h4 id=&quot;вариант-1-засилье-конструкторов&quot;&gt;Вариант 1: засилье конструкторов&lt;/h4&gt;

&lt;p&gt;Создаётся куча разных конструкторов на все случаи жизни.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDay&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDay&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;и так далее.&lt;/p&gt;

&lt;p&gt;Минус этого решения понятен: слишком много конструкторов. 
Учитывая, что используются они только в тестах - сомнительная идея…&lt;/p&gt;

&lt;h4 id=&quot;вариант-2-засилье-null&quot;&gt;Вариант 2: засилье &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;Второй вариант - иметь один “общий” конструктор со всеми возможными параметрами.
Тогда ваши тесты превращаются в кучу “null” через запятую:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Smith&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2011&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Happiness&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Минус и тут очевиден: такие тесты плохо читаются. Непонятно, “Happiness” - это какое именно поле?
Фамилия? Место предыдущей работы? Место отсидки? Ожидания от работы?
Приходится заглядывать внутрь, чтобы понять. IDE, конечно, чуть облегчают эту задачу, но всё же.&lt;/p&gt;

&lt;p&gt;Да, и есть ещё один минус. Когда ты захочешь добавить новое поле в этот класс, придётся перешерстить огромную кучу существующих тестов.
IDE облегчают и эту задачу, но всё же.&lt;/p&gt;

&lt;h4 id=&quot;вариант-3-засилье-вспомогательных-методов&quot;&gt;Вариант 3: засилье вспомогательных методов&lt;/h4&gt;

&lt;p&gt;Можно ещё плодить в тестах вспомогательные методы-фабрики для создания нужных объектов:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenderTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;withBirthdate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;withGender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Gender&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Это вполне себе нормальный вариант. Но всё-таки приходится писать много вспомогательного кода, 
и часто такие методы дублируются в разных тестах.&lt;/p&gt;

&lt;h4 id=&quot;вариант-4-засилье-билдеров&quot;&gt;Вариант 4: засилье билдеров&lt;/h4&gt;

&lt;p&gt;Все любят паттерны. Паттерны-фигаттерны. Паттерн “билдер” не исключение. Его часто советуют.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withFirstName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;john&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withLastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Smith&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withGender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MALE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Выглядит красиво, но на самом деле многовато усилий ради тестов, не?
Кода для билдеров придётся написать довольно прилично.&lt;/p&gt;

&lt;p&gt;Наверное, есть даже библиотеки, автоматизирующие создание билдеров. Это здорово.
Но есть вариант проще - Java 8 предлагает решение из коробки.&lt;/p&gt;

&lt;h3 id=&quot;и-что-же-даст-java-8&quot;&gt;И что же даст Java 8?&lt;/h3&gt;

&lt;p&gt;В Java 8 появились лямбды. Никто не знает, зачем они нужны, но типа круто.
Так вот теперь настало время лямбд - от них появилась реальная польза!&lt;/p&gt;

&lt;p&gt;Смотрите, как теперь можно создавать объекты в тестах:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lastName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Smith&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;birthDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dateX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;birthPlace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;PlaceX&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Каждый тест хорошо читается. Видно, какие поля проставляются, не нужно лезть в дебри конструктора.&lt;/p&gt;

&lt;p&gt;И для этого не надо писать кучу конструкторов, вспомогательных методов или билдеров.
Нужен всего-навсего один конструктор:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Consumer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И всё! Тесты читаемые, лишнего кода почти ноль.&lt;/p&gt;

&lt;p&gt;Будущее уже здесь, йо.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ru.selenide.org&quot;&gt;ru.selenide.org&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>How Java8 can help in writing unit-tests</title>
   <link href="https://asolntsev.github.io/en/2016/04/11/unit-tests-with-java8/"/>
   <updated>2016-04-11T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2016/04/11/unit-tests-with-java8</id>
   <content type="html">&lt;h3 id=&quot;problem&quot;&gt;Problem&lt;/h3&gt;

&lt;p&gt;Typically you need to create a lot of various objects with various states in your tests. 
But you don’t always have appropriate constructors, and probably don’t want to have too many constructors.&lt;/p&gt;

&lt;p&gt;And Java 8 can help here!&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;how-you-solve-it-now&quot;&gt;How you solve it now&lt;/h3&gt;

&lt;p&gt;Let’s suppose that you have a class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Employee&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Gender&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In some tests you want to set only name, in others - only birthday, 
sometimes only gender. In most tests, you want to set different combinations of data.&lt;/p&gt;

&lt;p&gt;How to create so much different objects in tests?&lt;/p&gt;

&lt;p&gt;Typically we have four options, all of which are not very good.&lt;/p&gt;

&lt;h4 id=&quot;option-1-lot-of-constructors&quot;&gt;Option 1: lot of constructors&lt;/h4&gt;

&lt;p&gt;You create a lot of constructors for different data sets.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDay&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDay&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;etc.&lt;/p&gt;

&lt;p&gt;It’s obvious why this is not a very good solution: too many constructors. 
You probably don’t want to have too many constructors, especially if you only use them in tests.&lt;/p&gt;

&lt;h4 id=&quot;option-2-lot-of-nulls&quot;&gt;Option 2: lot of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt;s&lt;/h4&gt;

&lt;p&gt;The next option is to have one “common” constructor with all possible parameters.
In this case your tests soon become to a mass of comma-separated “nulls”:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Smith&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2011&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Happiness&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, it’s obviously not very good. What’s exactly “Happiness” - what field is it?
Is it family name? First name? Previous employer? Job expectations?
You need to dive into the constructor to understand. IDE helps somewhat, but…&lt;/p&gt;

&lt;p&gt;This solution has one more problem. 
When you add new field to this class, you will need to refactor many-many existing tests.
IDE helps somewhat, but still…&lt;/p&gt;

&lt;h4 id=&quot;option-3-lot-of-helper-methods&quot;&gt;Option 3: lot of helper methods&lt;/h4&gt;

&lt;p&gt;You can also create plenty of helper factory methods for creating objects:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenderTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;withBirthdate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthPlace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;withGender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Gender&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s not a bad option. 
But you still need to write a lot of assistance code, and such methods are often duplicated among tests.&lt;/p&gt;

&lt;h4 id=&quot;option-4-the-desolation-of-builders&quot;&gt;Option 4: the desolation of builders&lt;/h4&gt;

&lt;p&gt;We all love patterns. We all love builders. It’s recommended quite often.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withFirstName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;john&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withLastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Smith&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withGender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MALE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It look pretty good.&lt;/p&gt;

&lt;p&gt;But isn’t it too much helper code just for tests?
Yes, you need to write quite a lot of code for builder pattern.&lt;/p&gt;

&lt;p&gt;There probably are some libraries that can generate builders. That’s good.
But we have simpler option: Java 8 suggests a solution out-of-the-box.&lt;/p&gt;

&lt;h3 id=&quot;so-how-java-8-will-solve-this&quot;&gt;So how Java 8 will solve this?&lt;/h3&gt;

&lt;p&gt;Java 8 brings lambdas. Nobody knew why it’s cool, but everybody thought that it’s cool.
Now it’s time for lambdas! Now we will see why they can be useful.&lt;/p&gt;

&lt;p&gt;Look how you can create objects in tests - using lambdas:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lastName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Smith&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;birthDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dateX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;birthPlace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;PlaceX&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Such tests are pretty well readable. You see what fields are initialized. 
You don’t need to dive into constructor.&lt;/p&gt;

&lt;p&gt;You don’t need to write lot of constructors, builders or any other assistance code.
You just need the only constructor:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Consumer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it!
You get pretty readable tests with almost zero investment.&lt;/p&gt;

&lt;p&gt;Future is already here.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://asolntsev.github.io&quot;&gt;Andrei Solntsev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://selenide.org&quot;&gt;selenide.org&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Эффективные UI-тесты на Selenide</title>
   <link href="https://asolntsev.github.io/ru/2015/12/31/selenide-at-advent-calendar/"/>
   <updated>2015-12-31T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2015/12/31/selenide-at-advent-calendar</id>
   <content type="html">&lt;h3 id=&quot;в-ожидании-чудес&quot;&gt;В ожидании чудес&lt;/h3&gt;

&lt;p&gt;Канун Нового Года - время чудес. В преддверии нового года мы все вспоминаем год уходящий и строим планы на следующий. 
И надеемся, что все проблемы останутся в прошлом, а в новом году случится чудо, и мы заживём по-новому.&lt;/p&gt;

&lt;p&gt;Какой же Java разработчик не мечтает о чуде, которое осенит его и позволит стать Самым Крутым На Свете Java Программистом.&lt;/p&gt;

&lt;p&gt;Хорошие новости: я хочу рассказать как раз о таком чуде.&lt;/p&gt;

&lt;p&gt;Имя ему - &lt;em&gt;автоматические тесты&lt;/em&gt;!&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;фу-тесты&quot;&gt;Фу, тесты?&lt;/h3&gt;

&lt;p&gt;Да. Настоящим мастером своего дела вас сделают не чудо-фреймворки, не микро/пико/нано сервисы, а дисциплина.
Дисциплина, которая говорит, что программист может считать дело законченным не тогда, когда код готов, а тогда, когда 
к нему написаны и запущены автоматические тесты. И если с юнит-тестами всё более-менее ясно, то UI-тесты пока остаются
для разработчиков тёмным лесом.&lt;/p&gt;

&lt;h3 id=&quot;да-ну-это-же-нудно&quot;&gt;Да ну, это же нудно?&lt;/h3&gt;

&lt;p&gt;О нет, поверьте мне! Написание &lt;strong&gt;грамотных&lt;/strong&gt; автотестов - это отличный челлендж, тут есть над чем пораскинуть мозгами.
И это может быть очень весело и интересно. Только надо использовать правильные инструменты.&lt;/p&gt;

&lt;p&gt;Правильный инструмент для написания UI-тестов - это:&lt;/p&gt;

&lt;h2 id=&quot;selenide&quot;&gt;Selenide&lt;/h2&gt;

&lt;p&gt;Selenide - это библиотека для написания лаконичных и стабильных UI тестов с открытым исходным кодом.&lt;/p&gt;

&lt;p&gt;Selenide - идеальный выбор для разработчиков, потому что у неё очень низкая кривая обучения. 
Вам не придётся заморачиваться со всеми этими техническими подробностям, на которые обычно тестировщики-автоматизаторы
тратят так много времени: нюансы работы с браузерами, типичные проблемы с таймингом и аяксом.&lt;/p&gt;

&lt;p&gt;Посмотрим, как выглядит простенький тест на Selenide:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GoogleTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;user_can_search_everything_in_google&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://google.com/ncr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;q&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;selenide&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pressEnter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#ires .g&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#ires .g&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Selenide: concise UI tests in Java&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;selenide.org&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(естественно, вместо Google здесь будет ваше веб-приложение)&lt;/p&gt;

&lt;p&gt;Что здесь происходит?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Вы &lt;strong&gt;открываете браузер&lt;/strong&gt; всего-навсего одной командой &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open(url)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Вы &lt;strong&gt;ищете элемент&lt;/strong&gt;  на странице командой &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt;.&lt;br /&gt;Вы можете найти элемент по имени, ID, CSS селектору, атрибуту, xpath и даже по тексту.&lt;/li&gt;
  &lt;li&gt;Вы &lt;strong&gt;совершаете некие действия&lt;/strong&gt; с элементом: в данном случае вводите текст командой &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val()&lt;/code&gt; и нажимаете ввод с помощью команды &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pressEnter()&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Вы &lt;strong&gt;проверяете результат&lt;/strong&gt;: ищете все результаты поиска с помощью &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$$&lt;/code&gt; (она возвращает коллекцию элементов).
Вы проверяете размер и содержимое коллекции.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Этот тест легко читается, не правда ли?&lt;br /&gt;
Этот тест легко пишется, не правда ли?&lt;/p&gt;

&lt;p&gt;А главное, этот тест легко запускается. Убедитесь сами:&lt;/p&gt;

&lt;center&gt;
&lt;iframe src=&quot;https://player.vimeo.com/video/73128965&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;a href=&quot;https://vimeo.com/73128965&quot;&gt;Selenide Harlem Shake&lt;/a&gt; from &lt;a href=&quot;https://vimeo.com/user20427140&quot;&gt;Selenide&lt;/a&gt; on &lt;a href=&quot;https://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;/center&gt;

&lt;h2 id=&quot;погружаемся-глубже&quot;&gt;Погружаемся глубже&lt;/h2&gt;

&lt;p&gt;Конечно, в жизни не всё так просто. Написание автотестов подразумевает кучу проблем, ведь не зря разработчики так 
их боятся - больше, чем любого наисложнейшего фреймворка или технологии.&lt;/p&gt;

&lt;p&gt;Но и здесь Selenide облегчает нашу жизнь, решая большинство этих проблем из коробки.&lt;/p&gt;

&lt;p&gt;Давайте рассмотрим типичные проблемы UI-тестов подробнее.&lt;/p&gt;

&lt;h3 id=&quot;проблемы-с-аяксом-и-таймаутами&quot;&gt;Проблемы с аяксом и таймаутами&lt;/h3&gt;

&lt;p&gt;В наше время веб-приложения все сплошь динамические. Каждый кусочек приложения может быть нарисован/изменён динамически в любой момент времени.
Это создаёт проблемы для автоматических тестов. Тест, который ещё вчера был зелёным, может внезапно стать красным безо всяких изменений в коде.
Просто потому, что браузер сегодня встал не с той ноги и запустил вон тот javascript чуточку медленнее, и тест успел кликнуть кнопочку раньше,
чем она до конца отрисовалась.&lt;/p&gt;

&lt;p&gt;Это прям вечная проблема у всех. Поэтому автоматизаторы пихают везде “слипы”.&lt;/p&gt;

&lt;p&gt;Тем более удивительно, насколько простым и надёжным способом Selenide решает эту проблему.&lt;/p&gt;

&lt;p&gt;Если коротко, в Selenide &lt;strong&gt;каждый метод умеет немножко подождать&lt;/strong&gt;, &lt;em&gt;если надо&lt;/em&gt;. Люди называют это “умными ожиданиями”.&lt;/p&gt;

&lt;p&gt;Когда вы пишете&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#menu&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Selenide проверит, существует ли элемент с ID=”menu”. И если нет, Selenide чуть-чуть подождёт, проверит ещё. Потом ещё подождёт.
И только когда элемент появится, Selenide проверит, что у него нужный текст.&lt;/p&gt;

&lt;p&gt;Конечно, нельзя ждать вечно. Поэтому Selenide ждёт не больше 4 секунд. Естественно, этот таймаут можно настраивать.&lt;/p&gt;

&lt;h3 id=&quot;не-сделает-ли-это-мои-тесты-медленными&quot;&gt;Не сделает ли это мои тесты медленными?&lt;/h3&gt;

&lt;p&gt;Нет, не сделает.
Selenide ждёт, только если надо. Если элемент изначально присутствует на странице - Selenide не ждёт. 
Если элемент появился через 300 мс - Selenide ждёт только 300 мс. Это именно то, что вам нужно.&lt;/p&gt;

&lt;h3 id=&quot;множество-встроенных-проверок&quot;&gt;Множество встроенных проверок&lt;/h3&gt;

&lt;p&gt;А что ещё вы можете проверять на странице, помимо текста?
Довольно много всего.&lt;/p&gt;

&lt;p&gt;Например, вы можете проверить, что элемент видимый (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visible&lt;/code&gt;). Если пока нет, Selenide подождёт &lt;strong&gt;до 4 секунд&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.loading_progress&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вы можете даже проверить, что элемент &lt;strong&gt;не существует&lt;/strong&gt;. Если элемент всё же найден, Selenide предположит, что он вот-вот пропадёт и подождёт до 4 секунд.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gender&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;should&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disappear&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вы можете делать несколько проверок в одной строке (т.н. “fluent API” и “method chain”), что сделает ваши тесты ещё более лаконичными:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#menu&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;коллекции&quot;&gt;Коллекции&lt;/h3&gt;

&lt;p&gt;Selenide позволяет вам очень удобно работать с коллекциями элементов. Вы можете проверять сразу множество элементов в одной строке.&lt;/p&gt;

&lt;p&gt;Например, вы можете проверить, что на странице ровно N таких-то элементов:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.error&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вы можете отфильтровать подмножество элементов:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#employees tbody tr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вы можете проверить тексты элементов. В большинстве случаев этого достаточно, чтобы проверить целую таблицу или строку в таблице:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#employees tbody tr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;texts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;John Belushi&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;Bruce Willis&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;John Malkovich&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;скачиваниезакачивание-файлов&quot;&gt;Скачивание/закачивание файлов&lt;/h3&gt;

&lt;p&gt;С Selenide закачивать файлы предельно просто:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#cv&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;uploadFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И вы даже можете закачать несколько файлов разом:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#cv&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;uploadFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv1.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv2.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv3.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И скачивание файлов тоже крайне просто:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.btn#cv&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;тестирование-динамичных-веб-приложений&quot;&gt;Тестирование “динамичных” веб-приложений&lt;/h3&gt;

&lt;p&gt;Некоторые веб-фреймворки (такие как GWT) генерируют совершенно нечитаемый HTML, не поддающийся анализу. 
Там нет постоянных ID, имён или классов.&lt;/p&gt;

&lt;p&gt;Это прям вечная проблема у всех. Поэтому автоматизаторы пихают везде длиннющие “xpath” и вынуждены их поддерживать до конца жизни.&lt;/p&gt;

&lt;p&gt;Чтобы решить эту проблему, Selenide предлагает искать элементы по тексту.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;codeborne&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;selenide&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Selectors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Привет, октябрята!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// находит элемент по тексту целиком&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;withText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;тябр&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;                         &lt;span class=&quot;c1&quot;&gt;// находит элемент по подстроке&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Привет, октябрята!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вопреки распространённому мнению, поиск элементов по тексту - не такая уж плохая идея. Между прочим, именно так ищет
элементы реальный пользователь. Он не ищет элементы по ID или классу, и уж тем более не по XPATH. Он ищет по тексту. 
(ну, ещё по цвету, но это труднее поддаётся автоматизации).&lt;/p&gt;

&lt;p&gt;Ещё в Selenide есть несколько полезных методов для поиска дочерних или родительских элементов. Это позволяет вам навигировать
между элементами без опознавательных знаков.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;td&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;td&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;closest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.btn&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;closest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.modal&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;q&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Например, вы можете найти ячейку в таблице по тексту, затем найти содержащую её строку &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tr&lt;/code&gt; и найти в этой строке 
кнопку “Save”:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;table#employees&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Joshua&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;closest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tr.employee&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Save&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;pageobject&quot;&gt;PageObject&lt;/h3&gt;

&lt;p&gt;Когда один и тот же элемент или страница используется во многих тестах, имеет смысл вынести логику страницы в отдельный класс.
Такой класс называется Page Object, и их тоже очень удобно делать с Selenide.&lt;/p&gt;

&lt;p&gt;Приведённый выше пример гугла можно переделать на page object таким образом:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;userCanSearch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;GooglePage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://google.com/ncr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GooglePage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;SearchResultsPage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;searchFor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;selenide&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResults&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Selenide: concise UI tests in Java&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Page Object для страницы поиска гугл:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GooglePage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SearchResultsPage&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;searchFor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;q&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pressEnter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;SearchResultsPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И для страницы результатов поиска:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SearchResultsPage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ElementsCollection&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getResults&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#ires .g&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SelenideElement&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#ires .g&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Но хочу обратить ваше внимание, что UI-тестов должно быть &lt;strong&gt;мало&lt;/strong&gt;. По той простой причине, что это всё-таки браузер, 
аякс, javascript, а всё это сравнительно медленно и нестабильно. Напишите один-два UI-теста, которые проверят, что
приложение &lt;em&gt;в целом&lt;/em&gt; работает: страничка открывается, текст отрисовывается, кнопки нажимаются, JavaScript не грохается.&lt;/p&gt;

&lt;p&gt;А всевозможные комбинации и редкие случаи обязательно проверяйте с помощью модульных тестов.&lt;/p&gt;

&lt;p&gt;Типичная ошибка - проверять всё через UI. Этим особенно страдают тестировщики в тех компаниях, где разработчики не пишут
модульных тестов. Бедным тестировщикам просто ничего не остаётся, кроме как городить огромную неповоротливую кучу медленных
и нестабильных UI-тестов и впрягаться в их пожизненную поддержку.&lt;/p&gt;

&lt;p&gt;Но ты ж программист! Не заставляй людей мучаться.&lt;/p&gt;

&lt;h3 id=&quot;-и-много-других-полезняшек&quot;&gt;… и много других полезняшек&lt;/h3&gt;

&lt;p&gt;В Selenide есть ещё много функций, таких как:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;scrollTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;innerText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;innerHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isImage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSelectedText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSelectedValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;doubleClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contextClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hover&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dragAndDrop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;мы не сможем их все здесть описать. Но хорошая новость в том, что вам не нужно всё это запоминать.
Просто наберите &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt;, точку и начните писать &lt;em&gt;примерно&lt;/em&gt;, что вы хотите. Например “val” или “enter”. 
И посмотрите, какие варианты предложит ваша IDE.&lt;/p&gt;

&lt;p&gt;Используйте мощь IDE! Не засоряйте голову деталями и сконцентрируйтесь на бизнес-логике.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://selenide.org/images/ide-just-start-typing.png&quot; alt=&quot;Мощь IDE&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;сделаем-мир-лучше&quot;&gt;Сделаем мир лучше&lt;/h1&gt;

&lt;p&gt;У верю, что мир станет лучше, когда все разработчики будут писать автоматические тесты для своего кода. 
Когда разработчики будут спокойно вставать в 17:00 и идти к своим детям, не боясь, что они что-то сломали своими изменениями.&lt;/p&gt;

&lt;p&gt;Поверьте мне, я чувствую себя уверенно оттого, что пока я ходил за кофе, мои тесты уже проверили мой код. 
И я точно знаю, что то, что я сдаю в тестирование - работает.&lt;/p&gt;

&lt;p&gt;Давайте сделаем мир лучше с помощью автоматических тестов!
Будьте уверены в своём софте, и вам не придётся скрещивать пальцы на удачу перед каждым релизом.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;С Новым Годом!&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Андрей Солнцев&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://ru.selenide.org&quot;&gt;ru.selenide.org&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Effective UI tests with Selenide</title>
   <link href="https://asolntsev.github.io/en/2015/12/31/selenide-at-advent-calendar/"/>
   <updated>2015-12-31T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2015/12/31/selenide-at-advent-calendar</id>
   <content type="html">&lt;h3 id=&quot;waiting-for-miracles&quot;&gt;Waiting for miracles&lt;/h3&gt;

&lt;p&gt;Christmas is a time for miracles. On the eve of the new year we all build plans for the next. 
And we hope that all problems will leave in the ending year, and a miracle happens in the coming year.&lt;/p&gt;

&lt;p&gt;Every Java developer dreams about a miracle that lets him become The Most Effective Java Developer in the world.&lt;/p&gt;

&lt;p&gt;I want to show you such a miracle.&lt;/p&gt;

&lt;p&gt;It’s called &lt;em&gt;automated tests&lt;/em&gt;!&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;ugh-tests&quot;&gt;Ugh, tests?&lt;/h3&gt;

&lt;p&gt;Yes. 
You will not become a real master thanks to micro/pico/nano services. You will become a real master thanks to discipline.
Discipline claiming that developer only then reports jobs as &lt;em&gt;done&lt;/em&gt; when code &lt;strong&gt;and tests&lt;/strong&gt; are written and run.&lt;/p&gt;

&lt;h3 id=&quot;but-isnt-testing-boring&quot;&gt;But, isn’t testing boring?&lt;/h3&gt;

&lt;p&gt;Oh no, believe me! Writing of &lt;strong&gt;fast&lt;/strong&gt; and &lt;strong&gt;stable&lt;/strong&gt; automated tests is a great challenge for smartest heads. 
And it can be very fun and interesting. You only need to use right tools.&lt;/p&gt;

&lt;p&gt;The right tool for writing UI tests is:&lt;/p&gt;

&lt;h2 id=&quot;selenide&quot;&gt;Selenide&lt;/h2&gt;

&lt;p&gt;Selenide is an open-source library for writing concise and stable UI tests.&lt;/p&gt;

&lt;p&gt;Selenide is an ideal choice for software developers because it has a very low learning curve. Thus, you don’t need to
bother with browser details, all these typical ajax and time issues that eat most of QA automation engineers’ time.&lt;/p&gt;

&lt;p&gt;Let’s look at a simplest Selenide test:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GoogleTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;user_can_search_everything_in_google&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://google.com/ncr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;q&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;selenide&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pressEnter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#ires .g&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#ires .g&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Selenide: concise UI tests in Java&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;selenide.org&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Of course, you will test your web application instead of Google).&lt;/p&gt;

&lt;p&gt;Let’s look closer what happens here.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You &lt;strong&gt;open a browser&lt;/strong&gt; with just one command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open(url)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;You &lt;strong&gt;find an element&lt;/strong&gt; on a page with command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt;.&lt;br /&gt;You can find element by name, ID, CSS selector, attributes, xpath and even by text.&lt;/li&gt;
  &lt;li&gt;You &lt;strong&gt;manipulate the element&lt;/strong&gt;: enter some text with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;val()&lt;/code&gt; and press enter with (surprise-surprise!) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pressEnter()&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;You &lt;strong&gt;check the results&lt;/strong&gt;: find all found results with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$$&lt;/code&gt; (it returns a collection of all matched elements).
You check the size and content of the collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isn’t this test easy to read?&lt;br /&gt;
Isn’t this test easy to write?&lt;/p&gt;

&lt;p&gt;I believe it is.&lt;/p&gt;

&lt;p&gt;And it’s easy to &lt;strong&gt;run&lt;/strong&gt;, look at this:&lt;/p&gt;

&lt;center&gt;
&lt;iframe src=&quot;https://player.vimeo.com/video/73128965&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;a href=&quot;https://vimeo.com/73128965&quot;&gt;Selenide Harlem Shake&lt;/a&gt; from &lt;a href=&quot;https://vimeo.com/user20427140&quot;&gt;Selenide&lt;/a&gt; on &lt;a href=&quot;https://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;/center&gt;

&lt;h2 id=&quot;deeper-into-details&quot;&gt;Deeper into details&lt;/h2&gt;

&lt;p&gt;Of course, real life is never that simple.
Writing autotests means a lot of problems, that’s why developers are afraid of tests more than of any complex framework or technology.&lt;/p&gt;

&lt;p&gt;The good news is that Selenide resolves most of these problems.&lt;/p&gt;

&lt;p&gt;Let’s consider typical problems of UI-tests.&lt;/p&gt;

&lt;h3 id=&quot;ajaxtiming-problems&quot;&gt;Ajax/timing problems&lt;/h3&gt;

&lt;p&gt;Nowdays web applications are dynamic. Every single piece of application can be rendered/changed dynamically at any moment. 
This creates a lot of problems for automated tests. Test that is green today can suddenly become red at any moment,
just because browser executed some javascript a little bit longer than usual.&lt;/p&gt;

&lt;p&gt;It’s a real &lt;em&gt;pain in the ajjaxx&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Quite unbelievably, but Selenide resolves most of the these problems in a very simple way.&lt;/p&gt;

&lt;p&gt;Simply said, every &lt;strong&gt;Selenide method waits&lt;/strong&gt; a little bit &lt;em&gt;if needed&lt;/em&gt;. People call it “smart waiting”.&lt;/p&gt;

&lt;p&gt;When you write&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#menu&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Selenide checks if the element exists and contains text “Hello”.&lt;/p&gt;

&lt;p&gt;If not yet, Selenide assumes that probably the element will be updated dynamically soon, and waits a little bit until it happens. 
The default timeout is 4 seconds, which is typically enough for most web applications. 
And of course, it’s configurable.&lt;/p&gt;

&lt;h3 id=&quot;doesnt-it-make-my-tests-slow&quot;&gt;Doesn’t it make my tests slow?&lt;/h3&gt;

&lt;p&gt;No, it doesn’t. Selenide waits only when it’s needed.
If element is already visible on the page - Selenide will not wait. 
If element appears after 300 ms - Selenide will only wait for 300 ms.
That’s perfectly what you need.&lt;/p&gt;

&lt;h3 id=&quot;rich-set-of-matchers&quot;&gt;Rich set of matchers&lt;/h3&gt;

&lt;p&gt;You can check pretty much everything with Selenide. Using “smart waiting” mechanism mentioned above.&lt;/p&gt;

&lt;p&gt;For example, you can check if element exists. If not yet, Selenide will wait &lt;strong&gt;up to&lt;/strong&gt; 4 seconds.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.loading_progress&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can even check that element &lt;strong&gt;does not&lt;/strong&gt; exist. If it still exists, Selenide will wait up to 4 seconds until it disappears.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gender&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;should&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disappear&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And you can use fluent API and chain methods to make your tests really concise:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#menu&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;collections&quot;&gt;Collections&lt;/h3&gt;

&lt;p&gt;Selenide allows you to work with collections, thus checking a lot of elements with one line of code.&lt;/p&gt;

&lt;p&gt;For example, you can check that there are exactly N elements on a page:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.error&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can find subset of collections:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#employees tbody tr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can check texts of elements. In most cases, it’s sufficient to check the whole table or table row:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#employees tbody tr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;texts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;John Belushi&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;Bruce Willis&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;John Malkovich&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;uploaddownload-files&quot;&gt;Upload/download files&lt;/h3&gt;

&lt;p&gt;It’s pretty easy to upload a file with Selenide:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#cv&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;uploadFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can even upload multiple files at once:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#cv&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;uploadFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv1.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv2.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cv3.doc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And it’s unbelievably simple to download a file:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.btn#cv&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;testing-highly-dynamic-web-applications&quot;&gt;Testing “highly dynamic” web applications&lt;/h3&gt;

&lt;p&gt;Some web frameworks (e.g. GWT) generate HTML that is absolutely unreadable. Elements do not have constant IDs or names.&lt;/p&gt;

&lt;p&gt;It’s a real &lt;em&gt;pain in the xpathh&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Selenide suggests to resolve this problem by searching elements by text.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;codeborne&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;selenide&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Selectors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello, Kitty!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// find by the whole text&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;withText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;itt&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;                     &lt;span class=&quot;c1&quot;&gt;// find by substring&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldHave&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello, Kitty!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Searching by text is not bad idea at all. In fact, I like it because it emulates behaviour of real user. 
Real user doesn’t find buttons by ID or XPATH - he finds by text (or, well, color).&lt;/p&gt;

&lt;p&gt;Another useful set of Selenide methods allows you to navigate between parents and children.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;td&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;td&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;closest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tr&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.btn&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;closest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.modal&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;q&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For example, you can find a table cell by text, then by its closest &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tr&lt;/code&gt; descendant and find a “Save” button inside this table row:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;table#employees&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Joshua&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;closest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tr.employee&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Save&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;-and-many-other-functions&quot;&gt;… And many other functions&lt;/h3&gt;

&lt;p&gt;Selenide has many more functions, like:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;scrollTo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;innerText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;innerHtml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isImage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSelectedText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSelectedValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;doubleClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;contextClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hover&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dragAndDrop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;but the good news is that you don’t need to remember all this stuff. 
Just put $, put dot and choose from available options suggested by your IDE.&lt;/p&gt;

&lt;p&gt;Use the power of IDE! Concentrate on business logic.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://selenide.org/images/ide-just-start-typing.png&quot; alt=&quot;Power of IDE&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;make-the-world-better&quot;&gt;Make the world better&lt;/h1&gt;
&lt;p&gt;I believe the World will get better when all developers start writing automated tests for their code. 
When developers will get up at 17:00 and go to their children without fearing that they broke something with last changes.&lt;/p&gt;

&lt;p&gt;Let’s make the world better by writing automated tests!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;Deliver working software.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/asolntsev&quot;&gt;Andrei Solntsev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://selenide.org&quot;&gt;selenide.org&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Почему IDEA лучше Eclipse</title>
   <link href="https://asolntsev.github.io/ru/2012/12/12/why-idea-is-better-than-eclipse/"/>
   <updated>2012-12-12T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2012/12/12/why-idea-is-better-than-eclipse</id>
   <content type="html">&lt;h3 id=&quot;священный-спор&quot;&gt;Священный спор&lt;/h3&gt;

&lt;p&gt;Принято считать, что есть «вечные» вопросы, на которые нет правильного ответа. Например, что лучше: Windows или Linux, Java или C#; Чужой против Хищника или Чак Норрис против Ван Дамма.&lt;/p&gt;

&lt;p&gt;Одним из таких &lt;a href=&quot;http://lurkmore.to/%D0%A5%D0%BE%D0%BB%D0%B8%D0%B2%D0%B0%D1%80/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D1%85%D0%BE%D0%BB%D0%B8%D0%B2%D0%B0%D1%80%D0%BE%D0%B2&quot;&gt;холиваров&lt;/a&gt; считается выбор лучшей IDE для Java.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_vs_idea_eng.png&quot; alt=&quot;Eclipse vs IDEA&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Идут постоянные споры о том, в которой из них больше плагинов, горячих клавиш и т.д. Различий так много, что трудно выбрать, какие из них важнее, и все сходятся в одном: обе IDE примерно одинаковы по своим возможностям, и выбор одной из них — это дело вкуса.&lt;/p&gt;

&lt;p&gt;Так вот, я утверждаю, что это не просто дело вкуса. Есть объективные причины, почему&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;&lt;a href=&quot;http://www.jetbrains.com/idea/&quot;&gt;Intellij IDEA&lt;/a&gt; (как Java IDE) однозначно лучше, чем &lt;a href=&quot;http://www.eclipse.org/&quot;&gt;Eclipse&lt;/a&gt;.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;Подчёркиваю, мы сейчас рассматриваем обе среды именно как Java IDE.&lt;/p&gt;

&lt;p&gt;Я не буду приводить кучу мелких различий вроде плагинов, горячих клавиш и т.п. — этому посвящены многие страницы в интернете,
например, эта: &lt;a href=&quot;http://arhipov.blogspot.com/2011/06/whats-cool-in-intellijidea-part-i.html&quot;&gt;часть 1&lt;/a&gt;, 
&lt;a href=&quot;http://arhipov.blogspot.com/2011/07/whats-cool-in-intellijidea-part-ii-live.html&quot;&gt;часть 2&lt;/a&gt;, 
&lt;a href=&quot;http://arhipov.blogspot.com/2011/08/whats-cool-in-intellijidea-part-iii.html&quot;&gt;часть 3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Объясню лишь одно, самое главное отличие. Как правило, о нём не знают ни идеяшники, ни эклипсофилы, ибо первые 
привыкли к нему и не знают, что в других IDE этого может и не быть, а вторые привыкли жить без него, и даже не 
догадываются, что может быть лучше. Более того, эклипсники его не замечают, когда пробуют IDEA ради интереса, ибо 
привыкли работать по-старому.&lt;/p&gt;

&lt;h3 id=&quot;откуда-такая-уверенность&quot;&gt;Откуда такая уверенность?&lt;/h3&gt;

&lt;p&gt;Но перед тем, как рассказывать про главное отличие IDEA, я хочу объяснить, почему к моему мнению стоит прислушаться.&lt;/p&gt;

&lt;p&gt;Я работал на Eclipse лет 5, знал её очень хорошо, писал под неё плагины, и искренне любил её. 
Потом я перешёл в другую компанию, и был вынужден пересесть на IDEA. 
Пережив серьёзную ломку, я наконец понял, чем же IDEA круче. И вот уже пару лет работаю на IDEA. 
Поэтому я знаю, что говорю.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;основное-различие-между-idea-и-eclipse&quot;&gt;Основное различие между IDEA и Eclipse&lt;/h2&gt;

&lt;p&gt;Главная вещь, отличающая IDEA — она &lt;strong&gt;понимает контекст&lt;/strong&gt;. 
Именно это имеют в виду сотрудники JetBrains, когда называют её «интеллектуальной» (intelligent). 
Что это значит? 
IDEA индексирует весь ваш проект, анализирует всё, что в нём есть, и даже строит синтаксическое дерево. 
Благодаря этому IDEA в любой момент, куда бы вы ни поставили курсор, знает, где мы находимся и что тут можно делать.&lt;/p&gt;

&lt;p&gt;Непонятно? Ещё бы. Ничего, на примерах станет ясно.&lt;/p&gt;

&lt;p&gt;Это умение &lt;em&gt;понимать контекст&lt;/em&gt; выражается во многих и многих аспектах, приведу лишь некоторые.&lt;/p&gt;

&lt;h4 id=&quot;1-отладка&quot;&gt;1. Отладка&lt;/h4&gt;
&lt;p&gt;Чтобы при отладке увидеть значение какого-то выражения, в Eclipse необходимо сначала выделить это выражение. Причём выделить точно, случайно выделите лишний символ — Eclipse не поймёт. После этого жмём Ctrl+Shift+I и видим значение выражения.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_inspect.png&quot; alt=&quot;eclipse_inspect.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;В IDEA же ничего выделять не надо, достаточно просто поставить курсор в нужное место (в данном случае на методе hasAttribute) и нажать Alt+F8. IDEA сама поймёт, какое выражение вам, вероятно, нужно, и тут же откроет диалог, где вы сможете редактировать выражение и сразу видеть его значение:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/idea_inspect.png&quot; alt=&quot;idea_inspect.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Выходит, обе IDE в принципе позволяют делать одно и то же. Но в IDEA это намного удобнее и быстрее. Я серьёзно, разница огромная — это просто небо и земля. В этом маленьком окошке IDEA сделает вам и автозаполнение, и подсветку синтаксиса, и всё на свете.&lt;/p&gt;

&lt;h4 id=&quot;2-автозаполнение-autocomplete&quot;&gt;2. Автозаполнение (autocomplete)&lt;/h4&gt;
&lt;p&gt;Автозаполнение — это то, что выгодно отличает любую IDE от notepad. И в этой области «понимание контекста» даёт IDEA качественное преимущество. Допустим, мы начали писать строчку кода:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;assertElement&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorMessage&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И тут мы хотим узнать, какие у нас есть варианты, чего там может начинаться с букв «vi».&lt;/p&gt;

&lt;p&gt;Что делает IDEA? Не дожидаясь никаких нажатий клавиш, она сразу же понимает, что метод assertElement хочет получить вторым параметром объект класса Condition, а в этом классе как раз есть статическая переменная типа Condition с именем visible. И предлагает единственный возможный вариант:
&lt;img src=&quot;/public/img/idea_autocomplete.png&quot; alt=&quot;idea_autocomplete.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;А что делает Eclipse? Увы, он не понимает контекста. 
Он не знает, что курсор находится на месте второго параметра метода assertElement. 
Поэтому, когда вы нажимаете заветные Ctrl+Space, Eclipse тупо показывает всё, что есть в природе, что начинается на буквы «vi»:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_autocomplete.png&quot; alt=&quot;eclipse_autocomplete.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;В красивом всплывающем окошке мы видим много-много красиво подсвеченной хорошо задокументированной бесполезной информации… :(&lt;/p&gt;

&lt;h4 id=&quot;3-рефакторинг&quot;&gt;3. Рефакторинг&lt;/h4&gt;
&lt;p&gt;Профессиональные программисты умеют быть продуктивными, используя для изменения кода те рефакторинги, которые предлагает их IDE. 
Все современные IDE в принципе предлагают весьма впечатляющий набор рефакторингов, наверное, даже большинство 
программистов не знает и не использует все из них. Но опять же, рефакторинги в IDEA &lt;em&gt;интеллектуальные&lt;/em&gt;. Они догадываются, 
чего вы хотите, и предлагают разные варианты, которые в большинстве ситуаций подходят.&lt;/p&gt;

&lt;p&gt;Например, есть у нас метод &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assertErrorMessageIsHidden&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assertErrorMessageIsHidden&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertElement&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorMessage&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Condition&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И мы хотим сделать так, чтобы строка «errorMessage» приходила в метод как параметр.&lt;/p&gt;

&lt;p&gt;Начнём с IDEA. Ставим курсор на любое место в строке «errorMessage», нажимаем заветные Ctrl+Alt+P (от «parameter»), и 
IDEA подсказывает, какое выражение мы могли бы вынести в параметр:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/idea_refactoring.png&quot; alt=&quot;idea_refactoring.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Как только выражение «errorMessage» выбрано, IDEA подсказывает несколько возможных имён для этого параметра.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/idea_name_parameter.png&quot; alt=&quot;idea_name_parameter.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Вы будете ещё не раз удивлены тем, как умно себя ведёт IDEA, предлагая свои варианты для имени чего-либо. 
Она учитывает и название метода, и тип переменной, и значение, и названия подобных переменных в других местах, и те 
названия, которые вы давали подобным переменным раньше — разве что ваш знак зодиака не учитывается. 
Правда-правда, не проходит и месяца, чтобы я не сказал фразы: «Ого, IDEA и это умеет?»&lt;/p&gt;

&lt;p&gt;Ну и посмотрим, что нам предложит Eclipse.&lt;/p&gt;

&lt;p&gt;Не забываем: выделяем выражение «errorMessage» (обязательно с кавычками, иначе получите дикое сообщение 
«An expression must be select to activate this refactoring»), выбираем рефакторинг «Introduce parameter» 
(из меню, горячей клавиши нет), и получаем тот же результат. Правда, никаких вариантов для имени параметра Eclipse не 
предлагает, но и на том спасибо.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_refactoring.png&quot; alt=&quot;eclipse_refactoring.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;выводы&quot;&gt;Выводы&lt;/h2&gt;
&lt;p&gt;Если мы говорим о Java IDE, то IDEA круче Eclipse. Это не просто дело вкуса. IDEA объективно лучше. 
Она позволяет быстрее и качественне писать и менять код, подсказывает подходящие имена, находит подходящие методы. 
Не требует точно выделить выражение, а по тому, где вы находитесь, угадывает, что вы хотели сделать и как хотели это назвать. 
IDEA предугадывает и подсказывает.&lt;/p&gt;

&lt;h3 id=&quot;ps-оговорки&quot;&gt;P.S. Оговорки&lt;/h3&gt;
&lt;p&gt;Оговорюсь: IDEA лучше Eclipse в качестве Java IDE. Если вы рассматриваете их в каком-то другом качестве — например, как IDE для другого языка (C++, Python, Scala), или как платформу для построения Desktop-приложений, то Eclipse вполне может победить.&lt;/p&gt;

&lt;p&gt;В общем-то, это вытекает и из определения. Eclipse позиционирует себя как абстрактная платформа для построения чего бы то ни было (с помощью дописывания плагинов), а IDEA позиционирует себя как «интеллектуальная IDE для Java». Так оно и есть.&lt;/p&gt;

&lt;p&gt;Интереса ради попробую назвать аспекты, в которых Eclipse, возможно, круче IDEA:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Eclipse красивее. Вся эта суета вокруг SWT и нативных контролов стоила того. 
Eclipse выглядит как солидное приложение с продуманными шрифтами и иконками, в то время как IDEA на первый взгляд выглядит как наколенная поделка с ламерскими иконками и нелепым свинговским интерфейсом.&lt;/li&gt;
  &lt;li&gt;В Eclipse богаче поддережка структуры проекта. В IDEA есть проект, состоящий из модулей, а в Eclipse есть workspace, состоящий из проектов, но их можно ещё и закрывать/открывать, объединять в группы и прятать.&lt;/li&gt;
  &lt;li&gt;Для Eclipse вроде бы проще писать плагины.&lt;/li&gt;
  &lt;li&gt;В конце концов, Eclipse бесплатен. 
Впрочем, &lt;a href=&quot;http://www.jetbrains.com/idea/features/editions_comparison_matrix.html?IC&quot;&gt;бесплатной версии IDEA&lt;/a&gt; мне хватает 
за глаза, ведь я использую &lt;a href=&quot;http://habrahabr.ru/blogs/java/126066/&quot;&gt;запускалку&lt;/a&gt; для разработки веб-приложений.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;итогошки&quot;&gt;Итогошки&lt;/h3&gt;

&lt;p&gt;Если вам нужны красивые иконки, платформа для создания настольных приложений, или IDE для C++, то Eclipse, вероятно, предпочтительнее. Если же вы серьёзный Java-программист, и вам нужна среда, позволяющая быстро и удобно вести разработку, сосредоточившись на проблеме и не отвлекаясь на средство разработки, то IDEA — это то, что нужно.&lt;/p&gt;

&lt;p&gt;На этом, я надеюсь, один вечный спор можно считать законченным.&lt;/p&gt;

&lt;p&gt;Кодьте с удовольствием!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why IDEA is better than Eclipse</title>
   <link href="https://asolntsev.github.io/en/2012/12/12/why-idea-is-better-than-eclipse/"/>
   <updated>2012-12-12T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2012/12/12/why-idea-is-better-than-eclipse</id>
   <content type="html">&lt;h3 id=&quot;holy-war&quot;&gt;Holy war&lt;/h3&gt;

&lt;p&gt;There are “eternal” questions that have no single correct answer. E.g. what is better: Windows or Linux, Java or C#; who is stronger, Chuck Norris or Van Damme.
One of such holywars is selection of the best Java IDE.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_vs_idea_eng.png&quot; alt=&quot;Eclipse vs IDEA&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There is a lot of disputes on this topic discussing which of them has more plugins, shortcuts and so on. 
There is so many differences that it’s difficult to decide what of them are the most important. 
As a result, people typically claim that both IDEs are equal in their capabilities, and choosing of one of them is a matter of taste.&lt;/p&gt;

&lt;p&gt;I claim that it is not just a matter of taste. There are objective reasons why&lt;/p&gt;
&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;&lt;a href=&quot;http://www.jetbrains.com/idea/&quot;&gt;Intellij IDEA&lt;/a&gt; (as a Java IDE) is definitely better than &lt;a href=&quot;http://www.eclipse.org/&quot;&gt;Eclipse&lt;/a&gt;.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am not going to compare lot of tiny differences like plugins, shortcuts etc - there is a plenty of blog posts on 
this topic, like this one: &lt;a href=&quot;http://arhipov.blogspot.com/2011/06/whats-cool-in-intellijidea-part-i.html&quot;&gt;part 1&lt;/a&gt;, 
&lt;a href=&quot;http://arhipov.blogspot.com/2011/07/whats-cool-in-intellijidea-part-ii-live.html&quot;&gt;part 2&lt;/a&gt;,&lt;br /&gt;
&lt;a href=&quot;http://arhipov.blogspot.com/2011/08/whats-cool-in-intellijidea-part-iii.html&quot;&gt;part 3&lt;/a&gt;.
I am going to show just one major difference between IDEA and Eclipse. 
Typically, neither IDEA nor Eclipse fans know it. 
The first ones used to it and cannot imagine that IDE can miss it. 
The second ones used to live without it and cannot imagine that IDE can do such things. 
Moreover, Eclipse users typically don’t notice this difference when trying IDEA for fun, just because they used to work “in Eclipse mode”.&lt;/p&gt;

&lt;h3 id=&quot;why-am-i-so-confident&quot;&gt;Why am i so confident?&lt;/h3&gt;

&lt;p&gt;Before I start, let me explain who I am and why is my opinion worth listening to.&lt;/p&gt;

&lt;p&gt;I’ve been working on Eclipse for 5 years, I knew it very well, I wrote plugins for it and sincerely loved Eclipse.
Then I switched to another company, and was forced to move to IDEA. 
After surviving a serious break-up, I finally realized why is IDEA steeper. 
And now I have been working on IDEA for a couple of years. So I know both IDEs well and can compare them.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-main-difference-between-idea-and-eclipse&quot;&gt;The main difference between idea and eclipse&lt;/h2&gt;

&lt;p&gt;The main reason why IDEA is steeper is: IDEA &lt;strong&gt;feels context&lt;/strong&gt;. 
That’s what JetBrains employees mean when they name IDEA intelligent. 
What it really means? IDEA indexes the whole your project, analyses everything it has, and even builds the syntax tree. 
Thanks to it, at any time, wherever you put the cursor, IDEA knows where you are and what can be done there.&lt;/p&gt;

&lt;p&gt;Still not clear? Do not worry, it will become clear in the following examples.&lt;/p&gt;

&lt;p&gt;This ability &lt;em&gt;to understand the context&lt;/em&gt; is expressed in many, many ways, here are just a few.&lt;/p&gt;

&lt;h4 id=&quot;1-debugging&quot;&gt;1. Debugging&lt;/h4&gt;
&lt;p&gt;As a part of debugging process, we often want to evaluate some expression to see its value. In Eclipse you need to select this expression. It’s important to exactly select the whole expression, otherwise Eclipse cannot evaluate it. Now you press Ctrl+Shift+I and see the value of expression.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_inspect.png&quot; alt=&quot;eclipse_inspect.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With IDEA you don’t need to select anything. 
You just put cursor at any place inside your expression (at method hasAttribute in given case) and press Alt+F8. 
IDEA understands which expression you probably need and shows a dialog window suggesting several possible variants 
for your expression. You can also edit and immediatelly evaluate the expression in this dialog. 
Very convenient! After trying this feature, you just cannot debug in Eclipse anymore.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/idea_inspect.png&quot; alt=&quot;idea_inspect.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It turns out that both IDEs, in principle, allow you to do the same thing. But with IDEA it’s much easier and faster. I’m serious, the difference is huge - it’s just Heaven and Earth. In this small dialog window IDEA will provide autofilling, syntax highlighting and everything you need.&lt;/p&gt;

&lt;h4 id=&quot;2-autocomplete&quot;&gt;2. Autocomplete&lt;/h4&gt;
&lt;p&gt;Autocomplete is what distinguishes any IDE from the notepad. In this area &lt;em&gt;feeling&lt;/em&gt; the context gives IDEA a qualitative advantage. For example, we started writing a line of code:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;assertElement&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorMessage&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and now we want to find what options do we have: what can start with letters “vi”.&lt;/p&gt;

&lt;p&gt;What IDEA does? Not waiting for any keystrokes, it immediately understands that method assertElement wants an Condition class instance as a second parameter, and there is a static variable in class Condition with name visible. 
And IDEA immediately suggests the only valid option:
&lt;img src=&quot;/public/img/idea_autocomplete.png&quot; alt=&quot;idea_autocomplete.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And what Eclipse does? Alas, it does not understand the context. 
It does not know that the cursor is located where the second parameter of the method assertElement should place. 
So when you press the sacred Ctrl + Space, Eclipse simply shows everything in Universe that begins with the letters “vi”:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_autocomplete.png&quot; alt=&quot;eclipse_autocomplete.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In a beautiful pop-up window we see a lot of pretty-highlighted well-documented useless information. :(&lt;/p&gt;

&lt;h4 id=&quot;3-refactoring&quot;&gt;3. Refactoring&lt;/h4&gt;

&lt;p&gt;Professional programmers are able to be productive using refactorings provided by their IDE. 
All modern IDE offer a very impressive set of refactorings. But then again, IDEA refactorings are &lt;em&gt;intelligent&lt;/em&gt;.
They realize what you want, and offer different options that are suitable for most situations.&lt;/p&gt;

&lt;p&gt;For example, suppose we have a method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assertErrorMessageIsHidden&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assertErrorMessageIsHidden&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertElement&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;errorMessage&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Condition&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And we want the String &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;errorMessage&quot;&lt;/code&gt; to come as a parameter to this method.&lt;/p&gt;

&lt;p&gt;Let’s start from IDEA. Put the cursor to any place inside the string “errorMessage”, press Ctrl+Alt+P 
(meaning “parameter”), and IDEA suggests what expression we probably could extract to a parameter:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/idea_refactoring.png&quot; alt=&quot;idea_refactoring.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As soon as the expression “errorMessage” is selected, IDEA suggests several possible names for this parameter.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/idea_name_parameter.png&quot; alt=&quot;idea_name_parameter.png&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;wow-every-month&quot;&gt;Wow every month&lt;/h4&gt;

&lt;p&gt;You will be surprised many, many times at how smart behaves IDEA, offering options for the name of something. 
It takes into account method name, variable type and even value, and names of such variables in other places, and 
those names that you gave such a variable before - except that your zodiac sign is ignored. 
Believe me, you will say: “Wow, IDEA is able to do such thing too?” at least once every month.&lt;/p&gt;

&lt;p&gt;And now let’s look that Eclipse suggests.&lt;/p&gt;

&lt;p&gt;Do not forget: select the entire expression “errorMessage” (always with quotes, or get a wild message 
“An expression must be select to activate this refactoring”), choose a refactoring “Introduce parameter” 
(from the menu, there is no hot key) and get about the same result. However, Eclipse doesn’t suggest options for a 
parameter name, but thanks for that.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/eclipse_refactoring.png&quot; alt=&quot;eclipse_refactoring.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;If we are choosing a Java IDE then Intellij IDEA is definitely better than Eclipse. 
It’s not just a matter of taste. IDEA is objectively better. 
It lets you to quickly and easily write and change the code, suggests appropriate names, finds the appropriate methods. 
It does not require you to exactly select the expressions, but guesses what you want to do and how you wanted to name it. 
IDEA anticipates and suggests.&lt;/p&gt;

&lt;h3 id=&quot;ps-remarks&quot;&gt;P.S. Remarks&lt;/h3&gt;

&lt;p&gt;I claim that IDEA is better Eclipse just as a Java IDE. If you are considering them in some other capacity - such as 
the IDE for other languages ​​(C++, Python, Scala), or as a platform for building desktop application, Eclipse may very well win.&lt;/p&gt;

&lt;p&gt;Actually it follows from their definition. 
Eclipse has positioned itself as an abstract platform for building anything with plug-ins, and IDEA is positioning 
itself as a “intelligent IDE for Java”. So it is.&lt;/p&gt;

&lt;p&gt;For the sake of interest I will try to name some aspects in which the Eclipse is probably better than IDEA:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Eclipse looks better (thought, this is a matter of taste). All this fuss about SWT and native controls was worth it. Eclipse looks like a solid well thought-out application with pretty fonts and icons, while the IDEA at first glance looks like a stunt toy with a lame hack icons and awkward Swing interface.&lt;/li&gt;
  &lt;li&gt;Eclipse has a richer project structure support. In IDEA you have a project consisting of modules. In Eclipse you have a workspace consisting of projects which can be closed/opened, grouped and hidden. But do you actually need it?&lt;/li&gt;
  &lt;li&gt;It seems to be easier to write plugins for Eclipse.&lt;/li&gt;
  &lt;li&gt;IDEA uses more resources (memory) than Eclipse. This actually makes sense - because he knows so much.&lt;/li&gt;
  &lt;li&gt;And finally, Eclipse is free. However, IDEA &lt;a href=&quot;http://www.jetbrains.com/idea/features/editions_comparison_matrix.html?IC&quot;&gt;Community Edition&lt;/a&gt; is just enough for me.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;my-final-recommendation&quot;&gt;My final recommendation&lt;/h3&gt;

&lt;p&gt;If you need pretty icons, platform for creating desktop applications, IDE for C++, or you work on an old weak laptop, 
then Eclipse is problably better choice for you. But if you are a serious Java developer, and you need a fast and 
convenient tool that helps you focus on the problem instead of distracting, then the IDEA this is exactly what you need.&lt;/p&gt;

&lt;p&gt;I hope one more holywar is over today.&lt;/p&gt;

&lt;p&gt;Develop with pleasure!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Где спряталась логика?</title>
   <link href="https://asolntsev.github.io/ru/2011/03/03/wtf-is-business-logic/"/>
   <updated>2011-03-03T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2011/03/03/wtf-is-business-logic</id>
   <content type="html">&lt;h3 id=&quot;вопрос&quot;&gt;Вопрос&lt;/h3&gt;

&lt;p&gt;Очень часто при обсуждении программ употребляется термин «логика» или «бизнес-логика». 
Например:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(о юнит-тестах) не обязательно добиваться стопроцентного покрытия кода тестами, достаточно тестировать лишь &lt;strong&gt;логику&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;(о веб-приложениях) контроллер не должен содержать никакой &lt;strong&gt;бизнес-логики&lt;/strong&gt;, а должен только вызывать методы других классов&lt;/li&gt;
  &lt;li&gt;В слое VIEW (то есть в JSP-файлах) не должно быть &lt;strong&gt;бизнес-логики&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Так вот, кто скажет мне, что такое «логика»?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Надо ли понимать под этим любой IF в коде? Но разве бывает код без IF’ов? Или «бизнес-логика» означает любую информацию, которая исходит от клиента? Но разве можем мы на деньги клиента делать что-то, чего он не заказывал? Не можем. Стало быть, весь наш код — это целиком «бизнес-логика» от клиента. Вот поэтому я никогда не мог понять, что же такое эта чёртова логика.&lt;/p&gt;

&lt;h3 id=&quot;ответ&quot;&gt;Ответ&lt;/h3&gt;

&lt;p&gt;Возможно, ответить на этот вопрос проще, если вместо слова «логика» использовать слово «знание». Логика — это любое знание о коде, или о том, как должен вести себя код. Можно ещё сформулировать так: «логика» — это всё, что вам хотелось хоть раз откомментировать.&lt;/p&gt;

&lt;h3 id=&quot;пример&quot;&gt;Пример&lt;/h3&gt;

&lt;p&gt;Возьмём для примера класс Account, который я недавно откопал в своём проекте.&lt;/p&gt;

&lt;p&gt;Было это так. В один прекрасный день у нас в офисе отрубился интернет на пару часов. Работать я фактически не мог — ну там, svn, jira, база знаний и прочее не были доступны. И решил я в качестве упражнения написать юнит-тест для какого-нибудь класса. И наткнулся на &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Account&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Негативное значение означает, что счёт предоплачен&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// И ещё два десятка геттеров и сеттеров&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Казалось бы, что тут тестировать? Где IF’ы? Где тут логика? Казалось бы, нет её, и тестировать нечего. Я уже хотел было бросить этот класс и найти что-нибудь посложнее, как вдруг заметил комментарий около переменной amount:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Негативное значение означает, что счёт предоплачен&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Это что ещё такое? 
Получается, что «amount» — это суммарная задолженность данного клиента, а если клиент внёс предоплату, то 
эта «задолженность» со знаком минус. Ну вот, это уже какое-то знание о коде. Попробуем-ка 
&lt;a href=&quot;http://habrahabr.ru/blogs/tdd/97320/&quot;&gt;превратить этот комментарий в юнит-тест&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccountTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;negativeAmountMeansThatAccountIsPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prepaidAccount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prepaidAccount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Раз мы проверяем случай негативного «amount», хорошо бы проверить и случай позитивного:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;positiveAmountMeansThatAccountIsInDebt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indebtAccount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;456&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indebtAccount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indebtAccount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isInDebt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вот так ненароком у нас возникло два новых метода &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isPrepaid()&lt;/code&gt; и &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isInDebt()&lt;/code&gt;, реализация которых, конечно, очевидна:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isInDebt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вот видите, уже и IF’ы появились в коде!
Следующая мысль, которая должна при этом прийти в голову: наверное, эти IF’ы уже были где-то раньше?&lt;/p&gt;

&lt;p&gt;Пришлось немножко поискать, но это того стоило. 
Оказалось, что эти IF’ы действительно были в коде, причём не где-нибудь, а в JSP-файле, то есть в слое «view», в 
котором по определению никакой логики быть не должно:&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;%&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Positive&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;means&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debt&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: red;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Оплатите задолженность!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: green;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Предоплата&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Опаньки, как интересно! Вот и мой второй тест-кейс всплыл. Как замечательно. 
Теперь, поскольку у нас есть методы &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isInDebt()&lt;/code&gt; и &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isPrepaid()&lt;/code&gt;, мы можем убрать логику из JSP:&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inDebt&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: red;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Оплатите задолженность!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;prepaid&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: green;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Предоплата&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Стало лучше? Я думаю, что стало. Это уже чуть больше похоже на инкапсуляцию — скрытие реализации от посторонних глаз. Только класс Amount знает, в каком случае клиент должен или не должен денег. Никто больше в целом мире не знает, как это происходит — клиент получает уже готовое решение с помощью методов isInDebt и isPrepaid. Теоретически значения «долг» и «предоплата» вообще могут храниться в разных колонках базы данных, или даже вообще в разных таблицах и вообще в разных базах. Теперь благодаря наличию двух методов эта логика спрятана (инкапсулирована) в классе Account.&lt;/p&gt;

&lt;p&gt;Если вы всё ещё не верите, сравните объём кода.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ДО&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;%-- Негативное значение означает, что счёт предоплачен %--&amp;gt;
&amp;lt;c:if test=&quot;${account.amount &amp;gt; 0}&quot;&amp;gt;
  &amp;lt;span style=&quot;color: red;&quot;&amp;gt;Оплатите задолженность!&amp;lt;/span&amp;gt;
&amp;lt;/c:if&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;ПОСЛЕ&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inDebt&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: red;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Оплатите задолженность!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Можно пойти ещё дальше и вместо метода &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAmount()&lt;/code&gt; сделать два разных метода &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getPrepaidAmount()&lt;/code&gt; и &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getDoubt()&lt;/code&gt;.
Причём внутри них можно проверять, действительно ли у клиента есть долг или предоплата. 
То есть теперь невозможно будет, например, написать такой код:&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;%-- Мало ли что у тебя предоплата, ты всё равно должен. %&amp;gt;
&amp;lt;c:if test=&quot;${account.amount != 0}&quot;&amp;gt;
  &amp;lt;font color=&quot;red&quot;&amp;gt;Оплатите задолженность!&amp;lt;/font&amp;gt;
&amp;lt;/c:if&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Да, это реальный код из того же проекта.
Взгляните на него ещё раз, взгляните внимательно. “Мало ли что у тебя предоплата”. Блестяще! Вот где спраяталась аццкая логика!
Пойди пойми теперь, что там было у людей на уме - у людей, которые не писали юнит-тест.&lt;/p&gt;

&lt;p&gt;В идеале метод &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAmount()&lt;/code&gt; теперь можно вообще стереть. 
Это и есть настоящая инкапсуляция: скрыть данные и код и дать доступ только через методы. 
Я думаю, если бы интернет не починили, я бы избавился и от остальных 20 геттеров-сеттеров.&lt;/p&gt;

&lt;h3 id=&quot;мораль&quot;&gt;Мораль&lt;/h3&gt;

&lt;p&gt;Вот видите, как юнит-тесты приводят к читаемому, объектно-ориентированному коду. 
А вы говорите: «В моём коде нет логики, там нечего тестировать…» Ещё как есть!&lt;/p&gt;

&lt;p&gt;Логика есть, её не может не быть.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>WTF is business logic?</title>
   <link href="https://asolntsev.github.io/en/2011/03/03/wtf-is-business-logic/"/>
   <updated>2011-03-03T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2011/03/03/wtf-is-business-logic</id>
   <content type="html">&lt;h3 id=&quot;question&quot;&gt;Question&lt;/h3&gt;

&lt;p&gt;I have heard many times the term “logic” or “business-logic” in discussions about software development. For instance:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(about unit-tests) it’s not necessary to achieve 100% code coverage, testing of &lt;strong&gt;logic&lt;/strong&gt; is god enough.&lt;/li&gt;
  &lt;li&gt;(about web applications architecture) controller should not contain any &lt;strong&gt;business logic&lt;/strong&gt;, it only should call other classes’s methods.&lt;/li&gt;
  &lt;li&gt;VIEW layer (e.g. JSP files) should not contain any &lt;strong&gt;business logic&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now tell me, what is “logic”?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Does it mean any IF in code? But, I don’t think that code without IFs ever existed. 
Or “business-logic” means any information that came from client? 
Actually I believe that all what we do is initiated by client, so all our code does contain information from client. 
That’s why I never could understand what the fuck is “business logic”.&lt;/p&gt;

&lt;h3 id=&quot;answer&quot;&gt;Answer&lt;/h3&gt;

&lt;p&gt;Probably this question could be easier answered if you use term “knowledge” instead of “logic”. “Logic” is any knowledge about the code, or about how your code should behave. It may be also expressed like “logic is anything that you ever wanted to comment”.&lt;/p&gt;

&lt;h3 id=&quot;example&quot;&gt;Example&lt;/h3&gt;

&lt;p&gt;Let’s consider class Account for example.&lt;/p&gt;

&lt;p&gt;Once upon a time Internet connection disappeared from our office for two hours. I actually could not work because SVN, jira, dabase etc. were not available. And I decided to exercise in writing unit-tests. So I found class Account:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Negative amount means that account is prepaid&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// And 20 getters/setters more&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At the first glance, is there anything to test? Is there any IFs? Is there any logic? It seems that no. 
No logic, no IFs - nothing to test. 
I wanted to skip this class and find something more complicated, but eventually got sight of the comment near the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt; field:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Negative amount means that account is prepaid&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wait, what is that?&lt;/p&gt;

&lt;p&gt;It turns out that the amount is a total debt of the client, and if the client has made an advanced payment, 
then this “debt” is negative. Well, this is some knowledge about the code. Let’s try to 
&lt;a href=&quot;http://asolntsev.blogspot.com.ee/2010/05/why-devil-invented-javadoc.html&quot;&gt;convert this comment to unit-test&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AccountTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;negativeAmountMeansThatAccountIsPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prepaidAccount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prepaidAccount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since we check for negative amount, it also would be reasonable to check for positive amount:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;positiveAmountMeansThatAccountIsInDebt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indebtAccount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;456&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indebtAccount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indebtAccount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isInDebt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We have eventually got two new methods isPrepaid and isInDebt, which implementation is of course straightforward for you:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BigDecimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isInDebt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isPrepaid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You see, we have got IF’s in our code!
What’s next? You should have thought: probably, these IF’s already were somewhere in the code?&lt;/p&gt;

&lt;p&gt;I had to search for such IF’s for a while, but it was worth it. 
These IFs were in JSP files, which is the “view” layer, which should not contain any business logic by definition:&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;%&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Positive&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;means&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debt&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: red;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Please pay your debt!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: green;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Advanced payment&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Wow, we have found the second test-case. Cool. Now, since we have methods isInDebt and isPrepaid, we can abandon logic in JSP:&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inDebt&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: red;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Please pay tour debt!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;prepaid&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: green;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Advanced payment&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Is it better? I believe it is. This is &lt;em&gt;encapsulation&lt;/em&gt; - hiding the implementation of logic from outer code. 
Class Amount is the only in the whole world who knows how to define, if client is in debt or has advanced payment. 
Other code doesn’t ever know how it happens - it can get resulting boolean throught methods &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isInDebt()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isPrepaid()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Theoretically “in debt” and “advanced payment” information could be stored in different columns, or event different 
tables, or even different databases. Nobody knows. Thanks to two methods, this logic is encapsulated in class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Account&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you still don’t believe, compare code size:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;%-- Positive amount means that account is in debt %--&amp;gt;
&amp;lt;c:if test=&quot;${account.amount &amp;gt; 0}&quot;&amp;gt;
  &amp;lt;span style=&quot;color: red;&quot;&amp;gt;Please pay your debt!&amp;lt;/span&amp;gt;
&amp;lt;/c:if&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;c:if &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;test=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inDebt&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;color: red;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Please pay your debt!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/c:if&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can go further and create two different methods &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getPrepaidAmount()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getDebt()&lt;/code&gt; instead of method 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAmount()&lt;/code&gt;. Additionally they can check, if the client has really debt or advanced payment. 
As a result, it’s impossible now to write a code like this one:&lt;/p&gt;

&lt;div class=&quot;language-jsp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;%-- No matter if you have advanced payment, 
I still think that you are in debt! %&amp;gt;
&amp;lt;c:if test=&quot;${account.amount != 0}&quot;&amp;gt;
  &amp;lt;font color=&quot;red&quot;&amp;gt;Please pay your debt!&amp;lt;/font&amp;gt;
&amp;lt;/c:if&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Yeah, it’s a real code snippet. 
Look at this once more. “No matter if you have”. Pretty cool! That is WTF logic!
It’s not possible to get to know what those people though - people who did not write unit-tests.&lt;/p&gt;

&lt;p&gt;Ideally, method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAmount()&lt;/code&gt; should be removed. 
This would be the real encapsulation: hiding of data and code and making them available only throught API. 
I think I would remove all of 20 other getters/setters if internet connection wouldn’t get back to our office that day.&lt;/p&gt;

&lt;h3 id=&quot;moral&quot;&gt;Moral&lt;/h3&gt;

&lt;p&gt;As You see, unit-tests lead you to readable, object-oriented code.&lt;/p&gt;

&lt;p&gt;Are you still thinking that your code doesn’t contain logic? Are you still thinking that you code has nothing to test?&lt;/p&gt;

&lt;p&gt;Of course it has!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Вдохновение для тестов</title>
   <link href="https://asolntsev.github.io/ru/2011/02/10/inspiration-for-unit-tests/"/>
   <updated>2011-02-10T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2011/02/10/inspiration-for-unit-tests</id>
   <content type="html">&lt;p&gt;Много слов сказано о достоинствах юнит-тестов (&lt;a href=&quot;https://www.youtube.com/watch?v=8u6_hctdhqI&amp;amp;feature=youtu.be&amp;amp;a&quot;&gt;TDD&lt;/a&gt;, 
&lt;a href=&quot;http://blog.devclub.eu/2010/10/31/asolntsev-bdd/&quot;&gt;BDD&lt;/a&gt; — в данном случае неважно), а также о том, 
почему люди &lt;a href=&quot;http://habrahabr.ru/post/112685/&quot;&gt;всё-таки их не используют&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Но я думаю, что одна из главных причин заключается в том, что люди не знают, с чего начать. 
Вот прочитал я статью про юнит-тесты, понравилось; решил, что надо бы когда-нибудь попробовать. 
Но что дальше? С чего начать? Как придумывать все эти требования, как называть тест-методы?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;В последнее время набирает популярность тенденция &lt;a href=&quot;/2010/10/29/unit-test-evolution/&quot;&gt;превращать юнит-тесты в BDD-спецификации&lt;/a&gt;,
то есть говорится о том, что хороший юнит-тест должен не тестировать что-то, а описывать поведение программы. Но как описать это чёртово поведение; откуда брать вдохновение, чтобы придумать названия для всех этих тест-кейсов?&lt;/p&gt;

&lt;p&gt;Об этом и пойдёт речь:&lt;/p&gt;

&lt;h3 id=&quot;откуда-брать-вдохновение&quot;&gt;Откуда брать вдохновение&lt;/h3&gt;

&lt;p&gt;Однажды я пришёл к удивительному открытию: это вдохновение — повсюду, оно окружает нас каждый день. 
Тут и придумывать ничего не надо. Его можно просто брать и использовать. 
Это открытие показалось мне настолько важным, что я спешу непременно поделиться им со всеми.&lt;/p&gt;

&lt;p&gt;Итак, мой TOP-5 источников вдохновения для написания юнит-тестов.&lt;/p&gt;

&lt;h4 id=&quot;5-доклад-начальнику&quot;&gt;5. Доклад начальнику&lt;/h4&gt;

&lt;p&gt;Каждое утро на собрании начальник спрашивает тебя:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;– &lt;em&gt;Что ты вчера делал?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;– &lt;em&gt;Багу исправлял.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Начальник так просто на слово не верит и продолжает докапываться:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Какую багу?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Ну, исправил метод validateReferenceNumber.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Конкретнее, что ты там исправил?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Ну, раньше он грохался, если дать ему на входе пустую строку, а теперь он не падает, а возвращает false.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Вот оно!&lt;/p&gt;

&lt;p&gt;Видите, практически готовый юнит-тест висит в воздухе у вас перед носом. После собрания садитесь за компьютер и пишете:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;emptyStringIsNotValidReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validateReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;В идеале вы должны были это сделать ещё вчера, и тогда начальник мог бы посмотреть, какие юнит-тесты вы вчера добавили, и не мучать вас своими вопросами. 
Я не шучу, я знаю примеры весьма успешных компаний, в которых вместо Code Review делается ревью юнит-тестов.&lt;/p&gt;

&lt;h4 id=&quot;4-объяснения-с-коллегами&quot;&gt;4. Объяснения с коллегами&lt;/h4&gt;

&lt;p&gt;К вам каждый день приходит какой-нибудь коллега и спрашивает:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Слушай, я тут твой код дебажу-дебажу, а всё никак не могу понять, как это работает?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ты ему терпеливо объясняешь:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Ну как, ну смотри: сюда приходит Б, а отсюда выходит А.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Всё равно не понимаю, а почему А-то?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Ну потому, что для всех букв, которые меньше Я, этот метод должен возвращать следующую букву.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Ааа, вот теперь понятно.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;И снова оно!&lt;/p&gt;

&lt;p&gt;Вы, сами того не подозревая, только что сформулировали название тест-кейса.
Мысленно послав +1 в карму коллеги, сели и написали:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NanoTechnologySecurityTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shouldReturnNextLetterForAllLettersExceptJa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Б&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encodeLetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;А&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;3-разговор-с-клиентом&quot;&gt;3. Разговор с клиентом&lt;/h4&gt;

&lt;p&gt;В любой прекрасный день клиент может позвонить и сказать:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;-— &lt;em&gt;Помните, мы обсуждали, что все поля на форме должны валидироваться автоматически, как только поле теряет фокус? 
Так вот, я передумал. Я показывал бета-версию моей бабушке, и она сказала, что это не понятно, и вообще ajax sucks.
Давайте поля будут валидироваться только тогда, когда клиент нажмёт кнопку «Submit».&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;И опять оно!&lt;/p&gt;

&lt;p&gt;Клиент только что сформулировал за нас текст тест-кейса.&lt;/p&gt;

&lt;p&gt;Мысленно послав -10 в карму клиента, мы сели и написали… UI тесты, конечно, чуток сложнее, чем обычные юнит-тесты,
но это могло бы выглядеть как-то так:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TimotiFanClubRegistrationFormTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shouldValidateFieldsOnFormSubmission&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Form&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isValid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isSubmitted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isValid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Baba Njura&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setEmail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Baba.Njura@yandex.ru&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isSubmitted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;2-баг&quot;&gt;2. Баг&lt;/h4&gt;

&lt;p&gt;Каждый день вы заходите в Jira (а кому совсем повезло — в Pivotal Tracker) и обнаруживаете, что в вашей программе 
зловредные тестировщики нашли-таки багу. Если вам повезло с тестировщиком, то описание баги звучит примерно 
так:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;«Если ввести три раза неправильный пароль, то учётная запись должна заблокироваться, а у меня не блокируется. 
Я уже раз пятнадцать ввёл.»&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Мысленно сказав тестировщику спасибо (хватит с него и спасиба, его карму всё равно не спасёшь), садимся и пишем:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginPageTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shouldBlockAccountAfter3UnsuccessfulTries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;LoginPage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoginPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;vasjok47&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Toiota&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;vasjok47&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Tojota&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;vasjok47&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tayota&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AccountDAO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAccount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;vasjok47&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isBlocked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Есть даже отдельный термин для этого: &lt;a href=&quot;http://geektimes.ru/post/69515/&quot;&gt;Bug driven development&lt;/a&gt;.
Я сам этот подход не жалую, так как юнит-тесты (они же спецификация) всё-таки должны писаться ДО кода 
(основной принцип TDD), но как источник вдохновения баг-трекер вполне подходит.&lt;/p&gt;

&lt;h4 id=&quot;1-commit-message-как-это-по-русски&quot;&gt;1. Commit message (как это по-русски?)&lt;/h4&gt;

&lt;p&gt;Это мой любимый пункт, на нём я хотел бы остановиться подробнее.&lt;/p&gt;

&lt;p&gt;Когда вы меняете код, для этого обычно есть причина. 
Причина обычно заключается в том, что вы хотите, чтобы этот код что-то делал по-другому (исключаем рефакторинг, 
улучшение производительности и расставление скобочек по фэншую).&lt;/p&gt;

&lt;p&gt;Допустим, был у нас код, который валидировал email. 
В частности, он проверял, что в конце email должна быть точка и два символа. 
И даже есть для него юнит-тест, всё как у людей. 
И тут &lt;a href=&quot;http://lurkmore.to/%D0%92%D0%BD%D0%B5%D0%B7%D0%B0%D0%BF%D0%BD%D0%BE&quot;&gt;внезапно&lt;/a&gt; выясняется, что после точки 
может быть и больше букв, например, у некоторых клиентов email заканчивается на “.info”.&lt;/p&gt;

&lt;p&gt;Сказано-сделано, код исправили, и даже в существующий юнит-тест добавили одну строчку:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmailValidatorTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testValidateEmail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validateEmail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;timati@rambler.ru&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validateEmail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tina.turner@music.info&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 4 letters now allowed!&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И теперь хотим это дело закоммитить в &lt;a href=&quot;http://habrahabr.ru/post/112648/&quot;&gt;CVS&lt;/a&gt; (а кому повезло, те в SVN, а кто 
вообще счастливчик, те в &lt;a href=&quot;http://habrahabr.ru/post/68341/&quot;&gt;GIT&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Для коммита надо написать пояснение (commit message), в котором обычно пишут, а что же в коде изменилось. 
И вот пишите вы:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;svn commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Теперяча мыло и на четыре буквы может заканчиваться.&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;И вот это самое настоящее оно-оно-оно!&lt;/p&gt;

&lt;p&gt;Это то, что нам надо. Не нажимайте пока enter.&lt;/p&gt;

&lt;p&gt;Остановились, выделили этот текст мышкой. 
Открыли класс юнит-теста. 
Написали Test, вставили скопированный текст и перевели на английский. 
Можно немножко уточнить или обобщить по вкусу.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmailValidatorTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validEmailShouldEndWithDotFollowedBySeveralLetters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validateEmail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;timati@rambler.ru&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validateEmail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tina.turner@music.info&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Вот теперь можете смело закоммитить и мысленно послать +1 себе в карму. 
Сегодня мы смогли материализовать некоторые знания из воздуха во что-то более ощутимое. 
Теперь эти знания никуда не пропадут и будут автоматически проверяться при каждой сборке проекта.&lt;/p&gt;

&lt;p&gt;Ну не здоровско ли, а?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Inspiration for tests</title>
   <link href="https://asolntsev.github.io/en/2011/02/10/inspiration-for-unit-tests/"/>
   <updated>2011-02-10T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2011/02/10/inspiration-for-unit-tests</id>
   <content type="html">&lt;p&gt;not translated yet&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Эволюция юнит-теста</title>
   <link href="https://asolntsev.github.io/ru/2010/10/29/unit-test-evolution/"/>
   <updated>2010-10-29T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2010/10/29/unit-test-evolution</id>
   <content type="html">&lt;p&gt;Много слов сказано о том, как правильно писать юнит-тесты, и вообще о пользе TDD.
Потом ещё и какое-то BDD замаячило на горизонте. 
Приходится разбираться, что из них лучше и между ними какая разница. 
Может, это и есть причина, почему большинство разработчиков решили не заморачиваться и до сих пор не используют ни того, ни другого?&lt;/p&gt;

&lt;p&gt;Коротко: BDD — это дальнейшее развитие идей TDD, стало быть, его и надо использовать. А разницу между TDD и BDD я попробую объяснить на простом примере.&lt;/p&gt;

&lt;p&gt;Рассмотрим 3 ревизии одного юнит-теста, который я нашёл в одном реальном проекте. Мы увидим, как он меняется от “обычного” до “хорошего” и “полезного”.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;попытка-номер-1-типичный-тест&quot;&gt;Попытка номер №1: типичный тест&lt;/h3&gt;

&lt;p&gt;Первая версия этого юнит-теста была такой:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testValidate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567890123&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Мы называем это &lt;strong&gt;типичным&lt;/strong&gt; юнит-тестом. 
Он тестирует код, но и только. Больше никаких преимуществ у него нет. Он не объясняет, почему именно такие значения. 
Почему “12345678” - корректное значение? Почему “1234567” - некорректное? Кто сказал?&lt;br /&gt;
Именно после такого кода скептики делают вывод, что от юнит-тестов нет особой пользы.&lt;/p&gt;

&lt;h3 id=&quot;попытка-номер-2-хороший-тест&quot;&gt;Попытка номер №2: хороший тест&lt;/h3&gt;

&lt;p&gt;В какой-то момент пришёл разработчик и решил применить к этому коду некоторые “best practices” из TDD: 
разбить тест-метод на несколько маленьких, так чтобы каждый из них тестировал только одну вещь, и дать им соответствующие имена.&lt;/p&gt;

&lt;p&gt;Вот что у него получилось:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testTooLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len13&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1234567891111&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testTooShort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testOk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
  
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len12&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;123456789111&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Мы называем это &lt;strong&gt;хорошим&lt;/strong&gt; юнит-тестом. 
Он гораздо легче читается: по названиям переменных легко догадаться, что 13 символов — это слишком много, 7 — слишком мало, а 8 символов — это нормально.&lt;/p&gt;

&lt;h3 id=&quot;попытка-номер-3-спецификация&quot;&gt;Попытка номер №3: спецификация&lt;/h3&gt;

&lt;p&gt;Спустя какое-то время приходит ещё один разработчик и замечает, что даже этот хороший юнит-тест не является вполне читабельным и 
не предоставляет достаточно информации о том, как работает класс ReferenceNumber. 
Его можно понять, но для этого всё-таки надо залезть в код и немножко подумать.&lt;/p&gt;

&lt;p&gt;Разработчик продолжает процесс разбивки и переименования:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nullIsNotValidReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;referenceNumberShouldBeShorterThan13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567890123&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;referenceNumberShouldBeLongerThan7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;referenceNumberShouldContainOnlyNumbers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567ab&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abcdefghi&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;---------&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;         &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
  
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;  
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validReferenceNumberExamples&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;123456789&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678901&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;123456789012&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;  
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;  
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Мы называем это &lt;strong&gt;спецификацией&lt;/strong&gt; в стиле BDD.&lt;/p&gt;

&lt;p&gt;Названия методов говорят почти на человеческом языке о том, как должен работать код. 
Мысленно вставив перед заглавными буквами пробелы, мы получаем спецификацию кода на английском языке. 
Чтобы понять, как работает класс, мы не должны залезать в код — достаточно прочитать называния. 
А если в ходе изменения кода в него внесли ошибку, и юнит-тест сломался, мы по названию сломавшегося тест-метода наверняка 
сможем определить, что за ошибка допущена в коде.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Между прочим, с этим примером произошла интересная история.
Однажды я собирался показать этот пример эволюции юнит-теста на семинаре devclub.eu по BDD в Таллине. 
И вот, за день до семинара я обнаружил, что я забыл скопировать исходный код самого класса ReferenceNumber, который 
мы тут всю дорогу тестируем. Что делать? Паника! До семинара остался один день! Мне нужно было срочно самому написать его заново.&lt;/p&gt;

  &lt;p&gt;А теперь посмотрите на эти три тест-класса и подумайте, какой из них помог мне восстановить логику класса ReferenceNumber.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;и-наконец-bdd&quot;&gt;И наконец, BDD&lt;/h3&gt;

&lt;p&gt;Можно сказать, третья версия отличается от предыдущих тем, что она описывает поведение класса. 
Это достигается за счёт использования таких слов как «should» и «contain»: «мой класс должен вести себя так-то и так-то», «мой метод должен делать то-то и то-то».&lt;/p&gt;

&lt;p&gt;Так вот, идея BDD как раз и заключается в том, чтобы вместо слов «test» и «assert» использовать слова «spec» и «should». 
Да-да, разница всего лишь в словах, но именно это, по замыслу авторов BDD, и делает спецификации удобочитаемыми, а 
написание тестов спецификаций до кода — естественным для человеческого мозга.&lt;/p&gt;

&lt;p&gt;Убедиться в этом вы можете, взглянув на тот же пример, переведённый с языка &lt;a href=&quot;http://junit.org/&quot;&gt;JUnit&lt;/a&gt; на язык &lt;a href=&quot;http://easyb.org/&quot;&gt;Easyb&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-groovy highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ReferenceNumber&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should not be null&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should be shorter than 13&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567890123&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should be longer than 7&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should contain only numbers&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567ab&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;abcdefghi&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;---------&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;         &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;valid reference number examples&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;123456789&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;12345678901&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;123456789012&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Отчёт о запуске этих тестов спецификаций фактически может служить документацией:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/easyb-report.png&quot; alt=&quot;EasyB report&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Кроме it и should, в BDD есть и другие важные слова, такие как given, when и then, а также before и after, 
ну и вдобавок ensure, narrative и «should behave as». 
Также BDD подходит не только для юнит-тестов, но и для функциональных/интеграционных тестов, но это уже выходит 
за рамки данной статьи. Сейчас нас интересует уровень юнит-тестов. 
Цель данной статьи — показать, что их можно писать по-разному.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Осталось добавить, что библиотеки для написания BDD спецификаций есть и для других языков: Java 
(&lt;a href=&quot;http://jdave.org/examples.html&quot;&gt;JDave&lt;/a&gt;, &lt;a href=&quot;http://jbehave.org/reference/latest/getting-started.html&quot;&gt;JBehave&lt;/a&gt;),
Ruby (&lt;a href=&quot;http://rspec.info/&quot;&gt;RSpec&lt;/a&gt;, &lt;a href=&quot;http://blog.dannorth.net/2007/06/17/introducing-rbehave/&quot;&gt;RBehave&lt;/a&gt;, 
&lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt;), Groovy (&lt;a href=&quot;http://easyb.org/&quot;&gt;Easyb&lt;/a&gt;), Scala (&lt;a href=&quot;http://www.scalatest.org/&quot;&gt;Scala-test&lt;/a&gt;), 
PHP (&lt;a href=&quot;http://everzet.com/Behat/&quot;&gt;Behat&lt;/a&gt;), CPP (&lt;a href=&quot;http://www.laughingpanda.org/projects/cppspec/example.html&quot;&gt;CppSpec&lt;/a&gt;),
.Net (&lt;a href=&quot;http://specflow.org/&quot;&gt;SpecFlow&lt;/a&gt;, &lt;a href=&quot;https://github.com/robconery/shouldly&quot;&gt;Shouldly&lt;/a&gt;), 
Python (&lt;a href=&quot;http://lettuce.it/&quot;&gt;Lettuce&lt;/a&gt;, &lt;a href=&quot;https://github.com/aslakhellesoy/cucumber/wiki/Python&quot;&gt;Cucumber&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;А если по независящим от вас причинам вы не можете пересесть с JUnit на что-то другое — тоже ничего, только помните о третьем примере. 
Кстати, в этом случае вам пригодится библиотека &lt;a href=&quot;https://code.google.com/p/hamcrest/wiki/Tutorial&quot;&gt;Harmcrest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Как завещал Козьма Прутков: товарищ, BDDи!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Unit-test evolution</title>
   <link href="https://asolntsev.github.io/en/2010/10/29/unit-test-evolution/"/>
   <updated>2010-10-29T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2010/10/29/unit-test-evolution</id>
   <content type="html">&lt;p&gt;TDD is not absolute goodness. Tests can be different.&lt;/p&gt;

&lt;p&gt;Let’s consider how bad can be unit-test and how can it evolve.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;typical-test&quot;&gt;Typical test&lt;/h3&gt;

&lt;p&gt;This is an example of unit-test evolution which I presented on recent devclub.eu workshop.
Let’s consider 3 revisions of the same unit-test class.
This is the first revision of this class:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testValidate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567890123&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We call it a &lt;strong&gt;typical unit-test&lt;/strong&gt;.
It’s not ideal: it fixes behaviour, but does not explain it. Why is “12345678” valid? Why “1234567” is not?
One monolithic test verifies multiple requirements. If one check fails - the whole test fails.&lt;/p&gt;

&lt;h3 id=&quot;good-test&quot;&gt;Good test&lt;/h3&gt;
&lt;p&gt;At some moment, some developer decides to apply some TDD best practices and split this test-method into 3 with some meaningful names.
This is what he got:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testTooLong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len13&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1234567891111&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testTooShort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testOk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;


    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len12&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;123456789111&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We call it good unit-test.&lt;/p&gt;

&lt;h3 id=&quot;executable-specification&quot;&gt;Executable specification&lt;/h3&gt;
&lt;p&gt;After some time, some developer decides that even this good unit-test is not human-readable and does not provide enough information about how class ReferenceNumber should work. 
He continued splitting and renaming.
This is what he got at the end:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceNumberTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nullIsNotValidReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;referenceNumberShouldBeShorterThan13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567890123&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;referenceNumberShouldBeLongerThan7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;referenceNumberShouldContainOnlyNumbers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567ab&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abcdefghi&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;---------&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;validReferenceNumberExamples&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;123456789&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;12345678901&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;123456789012&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We call it BDD style specification.
It explains requirements. It explains how code should behave and why. It explains customer’s expectations.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;And finally, the most interesting part.
I had to show this example on devclub.eu session.
But.. at some moment I discovered that I haven’t copied the original source code of the class ReferenceNumber being tested.&lt;/p&gt;

  &lt;p&gt;Panic!&lt;/p&gt;

  &lt;p&gt;One day left!&lt;/p&gt;

  &lt;p&gt;I had to urgently re-create it from scratch!
Now look at these 3 test-classes, and imagine, which of them helped me to create class ReferenceNumber.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;and-finally-bdd&quot;&gt;And finally, BDD&lt;/h3&gt;

&lt;p&gt;You could observe that the third test is different because it describes behaviour of class.
It’s accomplished by using words «should» and «contain»: «my class should behave like that», 
«my method should do this».&lt;/p&gt;

&lt;p&gt;So, BDD idea is to use words “spec” and “should” instead of «test» and «assert».
Yes, the difference is only a few words, but it makes tests (sorry, specifications) more readable, and writing tests 
before code more natural for human brains.&lt;/p&gt;

&lt;p&gt;You can make sure in it if you look at the same example translated from &lt;a href=&quot;http://junit.org/&quot;&gt;JUnit&lt;/a&gt; to 
&lt;a href=&quot;http://easyb.org/&quot;&gt;Easyb&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-groovy highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ReferenceNumber&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should not be null&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should be shorter than 13&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567890123&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should be longer than 7&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;should contain only numbers&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567ab&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;abcdefghi&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;---------&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;         &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;valid reference number examples&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;123456789&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567890&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;12345678901&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ReferenceNumber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;123456789012&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;shouldBe&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Test report can server as a documentation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/easyb-report.png&quot; alt=&quot;EasyB report&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In addition to &lt;em&gt;it&lt;/em&gt; and &lt;em&gt;should&lt;/em&gt;, BDD also suggests using other keywords, such as &lt;em&gt;given&lt;/em&gt;, &lt;em&gt;when&lt;/em&gt; and &lt;em&gt;then&lt;/em&gt;,
also &lt;em&gt;before&lt;/em&gt; and &lt;em&gt;after&lt;/em&gt;, and &lt;em&gt;ensure&lt;/em&gt;, &lt;em&gt;narrative&lt;/em&gt; and &lt;em&gt;«should behave as»&lt;/em&gt;.&lt;/p&gt;

  &lt;p&gt;BDD suits not only for unit-tests, but also for functional/integrations tests. 
You can see that tests can be different.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I must remain that there is also a plenty of BDD frameworks for different languages: Java 
(&lt;a href=&quot;http://jdave.org/examples.html&quot;&gt;JDave&lt;/a&gt;, &lt;a href=&quot;http://jbehave.org/reference/latest/getting-started.html&quot;&gt;JBehave&lt;/a&gt;),
Ruby (&lt;a href=&quot;http://rspec.info/&quot;&gt;RSpec&lt;/a&gt;, &lt;a href=&quot;http://blog.dannorth.net/2007/06/17/introducing-rbehave/&quot;&gt;RBehave&lt;/a&gt;, 
&lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt;), Groovy (&lt;a href=&quot;http://easyb.org/&quot;&gt;Easyb&lt;/a&gt;), Scala (&lt;a href=&quot;http://www.scalatest.org/&quot;&gt;Scala-test&lt;/a&gt;), 
PHP (&lt;a href=&quot;http://everzet.com/Behat/&quot;&gt;Behat&lt;/a&gt;), CPP (&lt;a href=&quot;http://www.laughingpanda.org/projects/cppspec/example.html&quot;&gt;CppSpec&lt;/a&gt;),
.Net (&lt;a href=&quot;http://specflow.org/&quot;&gt;SpecFlow&lt;/a&gt;, &lt;a href=&quot;https://github.com/robconery/shouldly&quot;&gt;Shouldly&lt;/a&gt;), 
Python (&lt;a href=&quot;http://lettuce.it/&quot;&gt;Lettuce&lt;/a&gt;, &lt;a href=&quot;https://github.com/aslakhellesoy/cucumber/wiki/Python&quot;&gt;Cucumber&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;But if you still need to use JUnit — it’s also ok, just remember the third example. And try using 
&lt;a href=&quot;https://code.google.com/p/hamcrest/wiki/Tutorial&quot;&gt;Harmcrest&lt;/a&gt; with JUnit.&lt;/p&gt;

&lt;p&gt;Do you feel BDDevolution?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Зачем дьявол придумал javadoc</title>
   <link href="https://asolntsev.github.io/ru/2010/05/02/javadoc/"/>
   <updated>2010-05-02T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/ru/2010/05/02/javadoc</id>
   <content type="html">&lt;p&gt;Есть мнение, что хорошая программа должна быть хорошо задокументирована.&lt;/p&gt;

&lt;p&gt;Компания SUN даже придумала специальный формат &lt;a href=&quot;https://ru.wikipedia.org/wiki/Javadoc&quot;&gt;javadoc&lt;/a&gt; - “стандарт для документирования классов Java”. 
В моей практике было совершенно обычным явлением, когда какой-то код не проходил Code Review, потому что в нём 
у некоторых методов отсутствовали комментарии.&lt;/p&gt;

&lt;p&gt;Сегодня я расскажу, почему комментарии - это зло.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;например&quot;&gt;Например&lt;/h3&gt;

&lt;p&gt;Возьмём пример из жизни. 
Это реальный код, написанный вполне старательным программистом, который не поленился и написал комментарий к своему методу. 
Довольный собой, но пошёл налить себе чашечку кофе из аппарата, а мы давайте-ка пока посмотрим, что же тут у нас есть.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddressUtil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;cm&quot;&gt;/**
    * Format string as address, expected input
    * format:&quot;EE ; ;Tallinn;Narva mnt;120B;831;10127&quot;
    *
    * @param flatAddress
    * @return Formatted address
    */&lt;/span&gt;
   &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{......}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Отлично! 
У нас есть корректно оформленный комментарий в формате javadoc, из которого специальная программа сможет сгенерировать 
HTML-документацию. По нему легко можно понять, что (теоретически) делает этот метод.&lt;/p&gt;

&lt;h3 id=&quot;где-же-спрятался-дьявол&quot;&gt;Где же спрятался дьявол?&lt;/h3&gt;

&lt;p&gt;Но где же те мелочи, в которых спрятался дьявол? А вот они:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Очень скоро эта документация &lt;strong&gt;устареет&lt;/strong&gt;, потому что придёт другой девелопер и поменяет код, но забудет поменять документацию. 
Это может быть даже тот же самый девелопер, потому что пока он стоял в очереди за кофе, ему пришло в голову, что он 
забыл обработать один редкий случай. Вернувшись, он добавит нужный IF в код, но забудет о том, что у него уже есть 
javadoc, который &lt;em&gt;необходимо поддерживать&lt;/em&gt;.&lt;/li&gt;
  &lt;li&gt;В документации &lt;strong&gt;не описаны&lt;/strong&gt; масса случаев: как поведёт себя метод, если на входе придёт null или пустая строка? 
Что, если в адресе есть номер дома, но нет номера квартиры (то есть буржуй занял дом целиком)? 
Что там за пустой параметр между &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EE&lt;/code&gt; и &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tallinn&lt;/code&gt;?&lt;/li&gt;
  &lt;li&gt;В документации нет ни слова о том, что этот метод &lt;strong&gt;возвращает&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;В документации есть целых три &lt;strong&gt;лишних&lt;/strong&gt; строчки: “*”, “@param flatAddress” и “@return Formatted address”. 
Только подумайте: они занимают большую часть документации, и они абсолютно бесполезны!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;волшебство&quot;&gt;Волшебство&lt;/h3&gt;

&lt;p&gt;А теперь давайте поиграем в волшебников и превратим несколько цветных кусочков в гирлянду. 
Сделаем несколько магических пассов. Сим-салябим, Ахалай-махалай, Ляськи-масяськи….&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Пасс номер 1: Основной текст из комментария &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Format string as address&lt;/code&gt; превращаем в название метода: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toString&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;formatAddress&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Пасс номер 2: Описание параметра &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expected input, expected: ...&lt;/code&gt; из комментария переносим в &lt;em&gt;юнит-тест&lt;/em&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Пасс номер 3: (мой любимый) Весь остальной комментарий &lt;strong&gt;стираем нахрен&lt;/strong&gt;. Не жалейте его, он зря появился на свет! Это кодская спарта!&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Что у нас получилось в итоге?&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddressUtil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;formatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{......}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddressUtilTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testFormatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Narva mnt 120B-831  10127 Tallinn&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;nc&quot;&gt;AddressUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;formatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;EE ; ;Tallinn;Narva mnt;120B;831;10127&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Чем же новый вариант лучше старого?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Он тупо &lt;strong&gt;короче&lt;/strong&gt;: было 8 строк, стало 4.&lt;/li&gt;
  &lt;li&gt;Этот тест &lt;strong&gt;никогда не устареет&lt;/strong&gt;, т.к. он будет запускаться автоматически каждый раз при сборке проекта, и если 
программист поменяет код, а о методе забудет, это сразу всплывёт.&lt;/li&gt;
  &lt;li&gt;Можно описать &lt;strong&gt;все редкие случаи&lt;/strong&gt;: пустые строки, отсутствующие параметры, недопустимые значения и т.д.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;одним-словом&quot;&gt;Одним словом,&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;ХОРОШЕЕ НАЗВАНИЕ + ТЕСТЫ = ДОКУМЕНТАЦИЯπ&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;а точнее, “запускаемая документация” (executable documentation), то есть документация, которую можно не просто читать, 
но ещё и “запускать”, автоматически проверяя, что она всё ещё адекватна.&lt;/p&gt;

&lt;p&gt;Говорят, у Конфуция над кроватью висел плакат:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;Convert comments to executable documentation&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;послесловие&quot;&gt;Послесловие&lt;/h3&gt;

&lt;p&gt;Боюсь только, что наш доблестный программист, вернувшись с кухни, фокуса не поймёт, ведь он не видел наших 
волшебных движений. Ему снесёт башню от одного только факта, что его комментарии КТО-ТО НАГЛО ПОТЁР, и он постарается 
нас найти и уничтожить за такую подрывную деятельность.&lt;/p&gt;

&lt;p&gt;А его кофе тем временем остынет. Ну что ж, и то неплохо: ведь кофе, говорят, вреден. 
Значит, одно хорошее дело мы всё-таки сегодня сделали.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/confucius.jpg&quot; alt=&quot;Confucius&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why the devil invented javadoc?</title>
   <link href="https://asolntsev.github.io/en/2010/05/02/javadoc/"/>
   <updated>2010-05-02T00:00:00+00:00</updated>
   <id>https://asolntsev.github.io/en/2010/05/02/javadoc</id>
   <content type="html">&lt;p&gt;It is believed that a good program should be well documented.&lt;/p&gt;

&lt;p&gt;SUN company even creared a special format &lt;a href=&quot;https://ru.wikipedia.org/wiki/Javadoc&quot;&gt;javadoc&lt;/a&gt; - “a standard for 
documenting classes Java”. In fact, it was quite a common case in my experience, when a code did not pass Code Review 
just because some of its methods lacked comments.&lt;/p&gt;

&lt;p&gt;Today I’ll tell you why the comments are evil.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;start-from-example&quot;&gt;Start from example&lt;/h3&gt;

&lt;p&gt;Consider the real example from live code. 
This is a real code written quite diligent programmer who was not lazy and wrote a commentary on his method. 
Pleased with himself, he went to pour himself a cup of coffee from the machine. 
While he is going to the office kitchen, let’s take a look at what we have here.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddressUtil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;cm&quot;&gt;/**
    * Format string as address, expected input
    * format:&quot;EE ; ;Tallinn;Narva mnt;120B;831;10127&quot;
    *
    * @param flatAddress
    * @return Formatted address
    */&lt;/span&gt;
   &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{......}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Excellent! We have a correctly designed a format javadoc, from which a special program can generate HTML-documentation.
As it is easy to see that (theoretically) makes this method.&lt;/p&gt;

&lt;h3 id=&quot;where-is-the-hidden-devil&quot;&gt;Where is the hidden devil?&lt;/h3&gt;

&lt;p&gt;But where are those little things that hid the devil? And here they are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Very soon this documentation &lt;strong&gt;becomes outdated&lt;/strong&gt;, because some other developer will come and change the code, but 
forget to change the documentation. It may even be the same developer, because while he was standing in line for coffee, 
it occurred to him that he forgot to process one rare case. When he comes back, he adds the desired IF into the code, 
but forgets that he already has javadoc, which &lt;strong&gt;needs to be maintained&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;This documentation &lt;strong&gt;does not describe&lt;/strong&gt; the mass of cases: how the method behaves, if the input comes null or empty 
string? What if address contains house number, but misses apartment number (ie bourgeois took home a whole)? 
What’s that empty parameter between the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EE&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tallinn&lt;/code&gt;?&lt;/li&gt;
  &lt;li&gt;Documentation doesn’t describe what this method &lt;strong&gt;returns&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;There are three &lt;strong&gt;extra lines&lt;/strong&gt; in the documentation: “*, “@ param flatAddress” and “@ return Formatted address”. 
Just think: they occupy a large part of the documentation, and they are absolutely useless!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can be summarized in two words:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;Comments lies!&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s all. You cannot do anything with this, except the cases when you have a special position for people how review 
all the documentation periodically. Damn, do you really want to do that?&lt;/p&gt;

&lt;h3 id=&quot;the-magic&quot;&gt;The magic&lt;/h3&gt;

&lt;p&gt;Now let’s do a focus-pocus and create The Magic. We make a few magical passes. Sim salyabim, Ahalan-mahalay, Lyaska-masyaski ….&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Pass # 1: Transform the main comment &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Format string as address&lt;/code&gt; to a method name: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toString&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;formatAddress&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pass #2: Transform parameter description &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expected input, expected: ...&lt;/code&gt; from comment to a &lt;em&gt;unit-test&lt;/em&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pass #3 (my favorite): (мой любимый) All other comment text - wipe fuckin! Do not spare him, it was born in vain! This is coding sparta!&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we have in the end?&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddressUtil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;formatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{......}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddressUtilTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;@Test&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testFormatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assertEquals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Narva mnt 120B-831  10127 Tallinn&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;nc&quot;&gt;AddressUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;formatAddress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;EE ; ;Tallinn;Narva mnt;120B;831;10127&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What the new version better than the old?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It’s just &lt;strong&gt;shorter&lt;/strong&gt;: there are now 4 rows compared to former 8.&lt;/li&gt;
  &lt;li&gt;This test will &lt;strong&gt;never becomes obsolete&lt;/strong&gt;, because it will run automatically every time you build the project, and 
if the programmer change the code, and forget about the method, it immediately pops up.&lt;/li&gt;
  &lt;li&gt;You can describe &lt;strong&gt;all the rare cases&lt;/strong&gt;: the empty string, missing keys, invalid values, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;in-short&quot;&gt;In short,&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;GOOD TITLE + TESTS = DOCUMENTATION&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;rather, executable documentation, or documentation that can not only read but also “run”, automatically checking that it is still adequate.&lt;/p&gt;

&lt;p&gt;It is said that Confucius was a poster over the bed:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;Convert comments to executable documentation&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;afterword&quot;&gt;Afterword&lt;/h3&gt;

&lt;p&gt;I’m just afraid that our brave programmer, returning from the kitchen, will not understand the focus, because he had not 
seen our magical movements. He will get mad only because SOMEONE Nagle has deleted his comments, and he will try to 
find us and kill for such subversive activities.&lt;/p&gt;

&lt;p&gt;… And his coffee gets cool in the meantime. Well, no so bad: after all, coffee, they say, is harmful. So, we did today did one good thing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/img/confucius.jpg&quot; alt=&quot;Confucius&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 

</feed>
