<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vasily Polovnyov</title>
    <description>The latest articles on DEV Community by Vasily Polovnyov (@vasily).</description>
    <link>https://dev.to/vasily</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F561972%2F6f2189b2-c0d9-4427-bcf3-cffb42d13abf.jpeg</url>
      <title>DEV Community: Vasily Polovnyov</title>
      <link>https://dev.to/vasily</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vasily"/>
    <language>en</language>
    <item>
      <title>RSpec &amp; Rails: what not to write in `it`</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Thu, 19 May 2022 05:50:12 +0000</pubDate>
      <link>https://dev.to/vasily/rspec-rails-what-not-to-write-in-it-nef</link>
      <guid>https://dev.to/vasily/rspec-rails-what-not-to-write-in-it-nef</guid>
      <description>&lt;p&gt;1. Useless, general words that bring no value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# bad: what value? for what?&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"adds certain value"&lt;/span&gt;

&lt;span class="c1"&gt;# good&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"snoozes for an extra 5 minutes"&lt;/span&gt;


&lt;span class="c1"&gt;# bad: which result is correct?&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"returns correct result"&lt;/span&gt;

&lt;span class="c1"&gt;# good&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"returns user's initials"&lt;/span&gt;


&lt;span class="c1"&gt;# bad: how exactly it fails?&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"fails"&lt;/span&gt;

&lt;span class="c1"&gt;# good&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"raises a not found error"&lt;/span&gt;


&lt;span class="c1"&gt;# bad: formatted how?&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"returns formatted string"&lt;/span&gt;

&lt;span class="c1"&gt;# good&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"returns time in 24-hour format"&lt;/span&gt;

&lt;span class="c1"&gt;# bad: what 'ok' means?&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"is ok"&lt;/span&gt;

&lt;span class="c1"&gt;# good&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"creates draft invoices"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2. Implementation details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# bad&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"changes @scheduled_on"&lt;/span&gt;

&lt;span class="c1"&gt;# good&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"reschedules campaign"&lt;/span&gt;


&lt;span class="c1"&gt;# bad&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"sets @todos"&lt;/span&gt;

&lt;span class="c1"&gt;# good&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"assigns todos to a given user"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3. Lies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"returns time in 24-hour format"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt; &lt;span class="s2"&gt;"9:25"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"strips leading zeroes"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;" 9:25 "&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt; &lt;span class="s2"&gt;"9:25"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See also:&lt;br&gt;
&lt;a href="https://rspec.rubystyle.guide/"&gt;RSpec Style Guide&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.betterspecs.org/"&gt;Better Specs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>RSpec &amp; Rails: how to stub env vars</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Tue, 17 May 2022 09:02:25 +0000</pubDate>
      <link>https://dev.to/vasily/rspec-rails-how-to-stub-env-vars-32m4</link>
      <guid>https://dev.to/vasily/rspec-rails-how-to-stub-env-vars-32m4</guid>
      <description>&lt;p&gt;In order to stub an environment variable in the test (which is probably missing in test environment), stub &lt;code&gt;:[]&lt;/code&gt; or &lt;code&gt;fetch&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# If code relies on ENV["CHARGES_TOKEN"]&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:[]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CHARGES_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"XXX"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# If code relies on ENV.fetch("CHARGES_TOKEN")&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:fetch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CHARGES_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"XXX"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want shorter syntax, take a look at &lt;a href="https://github.com/thoughtbot/climate_control"&gt;ClimateControl&lt;/a&gt; gem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ClimateControl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modify&lt;/span&gt; &lt;span class="no"&gt;CHARGES_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"XXX"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to test code that works with an external API: a stub on Sinatra</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Sat, 14 May 2022 10:15:32 +0000</pubDate>
      <link>https://dev.to/vasily/how-to-test-code-that-works-with-an-external-api-a-stub-on-sinatra-4ccn</link>
      <guid>https://dev.to/vasily/how-to-test-code-that-works-with-an-external-api-a-stub-on-sinatra-4ccn</guid>
      <description>&lt;p&gt;Imagine a situation: your application relies on an external service responsible for card charges. The service has a tiny API: get the card number (mask) by user ID, charge &lt;code&gt;X&lt;/code&gt; dollars from the user. How do we test the code that works with this API?&lt;/p&gt;

&lt;p&gt;Of course, you can actually request that external service in the tests. Maybe it even has a sandbox for such cases. But this solution is not so efficient. First of all, it slows down the tests: every request has a time cost. Secondly, it makes tests flaky: network issues will cause them to randomly fail. Thirdly, it's not always possible: the external service may have no sandbox or have strict request limits.&lt;/p&gt;

&lt;p&gt;In such cases, it is better to use stubs for external services. I use four options of stubs, depending on the external service: is it my own or someone else's, stable or frequently changing?&lt;/p&gt;

&lt;p&gt;One of the options is a fake service on Sinatra. Such as this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:fake_api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="no"&gt;Sinatra&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"/users/:user_id/card"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;content_type&lt;/span&gt; &lt;span class="ss"&gt;:json&lt;/span&gt;

      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;number: &lt;/span&gt;&lt;span class="s2"&gt;"4111...1111"&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;stub_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sr"&gt;/api.nanocashier.com/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_rack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fake_api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two interesting things in the above code. Firstly, &lt;code&gt;Class.new&lt;/code&gt; with the &lt;code&gt;Sinatra::Base&lt;/code&gt; parent in &lt;code&gt;let&lt;/code&gt;, so you don't add a global constant from the test. Secondly, the &lt;code&gt;stub_request&lt;/code&gt; of Webmock, which routes all requests to the rack application.&lt;/p&gt;

&lt;p&gt;I use such rack-based stubs when I have to mock an external service which doesn't have its own stubs (e.g. stripe-ruby-mock) and making adapter-like stub is not possible.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>Quick tip: stub requests to unix sockets</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Thu, 12 May 2022 06:05:26 +0000</pubDate>
      <link>https://dev.to/vasily/quick-tip-stub-requests-to-unix-sockets-4nac</link>
      <guid>https://dev.to/vasily/quick-tip-stub-requests-to-unix-sockets-4nac</guid>
      <description>&lt;p&gt;Sometimes, an application communicates with an external service not via Internet sockets, but via unix sockets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Excon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"unix:///ping"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;socket: &lt;/span&gt;&lt;span class="s2"&gt;"/tmp/unicorn.sock"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To stub requests like this in tests, use Webmock:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;stub_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"http://unix/ping"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>testing</category>
      <category>rspec</category>
    </item>
    <item>
      <title>Using Faker is anti-pattern</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Thu, 05 May 2022 05:36:10 +0000</pubDate>
      <link>https://dev.to/vasily/using-faker-is-anti-pattern-1jgl</link>
      <guid>https://dev.to/vasily/using-faker-is-anti-pattern-1jgl</guid>
      <description>&lt;p&gt;In my opinion, Faker and randomly generated data is usually an anti-pattern in tests.&lt;/p&gt;

&lt;p&gt;First of all, with Faker tests become nondeterministic: run - crashed, run again - passed. Such flaky tests are extremely difficult to debug and annoying on CI.&lt;/p&gt;

&lt;p&gt;Secondly, random data slows down tests. Especially in factories: I worked on a project where switching from Faker to &lt;code&gt;sequence { ... }&lt;/code&gt; accelerated the test suite by 12%.&lt;/p&gt;

&lt;p&gt;Thirdly, Faker overuse leads to code duplication in the tests. For example, take a look at the test method that returns user's initials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"returns initials"&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;described_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="no"&gt;Faker&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initials&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an incomprehensible and confusing test: if the &lt;code&gt;#initials&lt;/code&gt; method changes, the changes will have to be duplicated in the test as well. A better way would be to write it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"returns initials"&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;described_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Daniel Craig Jones"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initials&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"DCJ"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I suggest you to take a closer look at Faker in your test suite: are you sure you need it?&lt;/p&gt;

&lt;p&gt;More on this topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jtway.co/stop-using-faker-and-random-data-in-the-test-fixtures-67332269a64e"&gt;Stop using Faker and random data in the test fixtures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arjanvandergaag.nl/blog/factory_girl_tips.html"&gt;FactoryGirl Tips and Tricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kevin.burke.dev/kevin/faker-js-problems/"&gt;You Shouldn’t Use Faker (or other test randomization libraries)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>Fake data in tests</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Tue, 03 May 2022 14:55:31 +0000</pubDate>
      <link>https://dev.to/vasily/fake-data-in-tests-2208</link>
      <guid>https://dev.to/vasily/fake-data-in-tests-2208</guid>
      <description>&lt;p&gt;Tests are not only a tool to automatically check the code and its correctness, but also an excellent documentation. Every time I don't understand something in the documentation of a library, I look at the specs and quickly find an answer to my question.&lt;/p&gt;

&lt;p&gt;In tests it is the best to use data as close to real-life as possible: "User" → "Ivan Pavlov", "ip" → "82.100.200.3", empty file → jpeg with your cat. This way we get good documentation and good examples of how to use our API.&lt;/p&gt;

&lt;p&gt;To make the tests consistent, I prefer to use a single domain for the test data. For example, I often use:&lt;/p&gt;

&lt;p&gt;1. Characters and quotes from The Simpsons:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Bart Simpson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s2"&gt;"bart@simpson.dev"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt; &lt;span class="s2"&gt;"Bart Simpson &amp;lt;bart@simpson.dev&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2. Characters and quotes from '90s action movies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="ss"&gt;comment: &lt;/span&gt;&lt;span class="s2"&gt;"Dead or alive... you're coming with me"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3. Lyrics of Eminem's or Beyoncé's songs (please don't ask):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;do_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;text: &lt;/span&gt;&lt;span class="s2"&gt;"In my shoes, just to see what it's like to be me"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;P. S. Some of you might mention Faker. I don't use it as I think it's an anti-pattern. I'll elaborate on this &lt;a href="https://dev.to/vasily/using-faker-is-anti-pattern-1jgl"&gt;in next post&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>Linting Ruby right in Neovim</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Thu, 28 Apr 2022 07:18:04 +0000</pubDate>
      <link>https://dev.to/vasily/linting-ruby-right-in-neovim-16d0</link>
      <guid>https://dev.to/vasily/linting-ruby-right-in-neovim-16d0</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvasily.polovnyov.ru%2Fassets%2Fvim-ale.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvasily.polovnyov.ru%2Fassets%2Fvim-ale.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Vim to lint the current file in the background and show errors directly in the editor, you need to do these three steps:&lt;/p&gt;

&lt;p&gt;1. Install &lt;a href="https://github.com/dense-analysis/ale" rel="noopener noreferrer"&gt;ALE&lt;/a&gt; (async code checker with Language Server Protocol support).&lt;/p&gt;

&lt;p&gt;2. Setup it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" What do we use for linting&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;g:ale_linters&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="se"&gt;\&lt;/span&gt; &lt;span class="s1"&gt;'javascript'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'eslint'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="se"&gt;\&lt;/span&gt; &lt;span class="s1"&gt;'ruby'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'rubocop'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;g:ale_linters_explicit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c"&gt;" Lint Ruby files with binstub&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;g:ale_ruby_rubocop_executable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'bin/rubocop'&lt;/span&gt;

&lt;span class="c"&gt;" Tune linter's error and warning signs&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;g:ale_sign_error&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'\u2022'&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;g:ale_sign_warning&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'\u2022'&lt;/span&gt;

&lt;span class="c"&gt;" Let's leave a column for the signs so that the left side of the window doesn't move&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;g:ale_sign_column_always&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3. You're beatiful!&lt;/p&gt;

</description>
      <category>vim</category>
      <category>ruby</category>
      <category>productivity</category>
    </item>
    <item>
      <title>“What” and “For what” in pull requests</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Mon, 25 Apr 2022 09:38:59 +0000</pubDate>
      <link>https://dev.to/vasily/what-and-for-what-in-pull-requests-3dnp</link>
      <guid>https://dev.to/vasily/what-and-for-what-in-pull-requests-3dnp</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--01UXTHeY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ac0exbrt9klxufsic5li.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--01UXTHeY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ac0exbrt9klxufsic5li.png" alt="What? and For what? questions in pull request template" width="880" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few months ago, I came up with a template for pull requests consisting of two questions: "What?" and "For what?". You open a pull request, answer the questions, and send it to the reviewer. The reviewer dives right into the problem, understands faster what we are trying to accomplish, and visualizes a possible solution.&lt;/p&gt;

&lt;p&gt;A couple of examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## What?&lt;/span&gt;
Update Rails to 6.1.3.2.

&lt;span class="gu"&gt;## For what?&lt;/span&gt;
To fix a security vulnerability: CVE-123123.&lt;span class="sb"&gt;


&lt;/span&gt;&lt;span class="gu"&gt;## What?&lt;/span&gt;
Before tracking a coupon, make sure it actually exists in the database.

&lt;span class="gu"&gt;## For what?&lt;/span&gt;
To avoid writing junk data like &lt;span class="sb"&gt;`utm_campaign`&lt;/span&gt;, &lt;span class="sb"&gt;`utm_source`&lt;/span&gt; or &lt;span class="sb"&gt;`utm_medium`&lt;/span&gt; into the analytics.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've also noticed a positive effect for the pull request author: if you can't articulate "For what?", you don't actually understand the task; if the "What?" has "Also..." and "And...", it's better to split the pull request into several ones.&lt;/p&gt;

&lt;p&gt;What are your thoughts on this topic? What kind of pull request templates do you use?&lt;/p&gt;

&lt;p&gt;(All in all, I really recommend trying this!)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>github</category>
    </item>
    <item>
      <title>Rack application as a stub</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Mon, 03 May 2021 05:29:00 +0000</pubDate>
      <link>https://dev.to/vasily/rack-application-as-a-stub-5eif</link>
      <guid>https://dev.to/vasily/rack-application-as-a-stub-5eif</guid>
      <description>&lt;p&gt;Sometimes you need to put a stub on a particular route, but do not want to make a controller for this. In this case use Rack application as a stub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/routes.rb&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"wp-login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>rails</category>
      <category>beginners</category>
      <category>tips</category>
    </item>
    <item>
      <title>Learning Through Overuse</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Sun, 25 Apr 2021 21:00:50 +0000</pubDate>
      <link>https://dev.to/vasily/learning-through-overuse-3c43</link>
      <guid>https://dev.to/vasily/learning-through-overuse-3c43</guid>
      <description>&lt;p&gt;Sometimes it's hard to know how often and in what situations it's best to use any particular technology. How many integration tests do I need? When can I not write them, when can I do without them? When is it better to use vanilla JS and CSS, and when to get into all that post- and preprocessor stuff?&lt;/p&gt;

&lt;p&gt;In these cases, it helps me to bring the situation to the point of overuse. I don't know how many integration tests I need? For the next two weeks, I write &lt;em&gt;only&lt;/em&gt; integration tests. In all cases, no matter what the internet says. Period. I don't know when enough vanilla JS and CSS will suffice? I'm building a page &lt;em&gt;only&lt;/em&gt; with bare JS and CSS.&lt;/p&gt;

&lt;p&gt;This approach gives quick feedback in the form of pain in places where the technology definitely doesn't fit. Oops, integration tests slow down and prevent quick refactoring of the module - I'd rather have unit tests here. Oops, with vanilla JS it's painful to keep track of form state - I'd rather have something reactive and product-ready.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My new favourite programming font: iA Writer Mono S</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Mon, 19 Apr 2021 07:17:20 +0000</pubDate>
      <link>https://dev.to/vasily/my-new-favourite-programming-font-ibm-plex-mono-4m02</link>
      <guid>https://dev.to/vasily/my-new-favourite-programming-font-ibm-plex-mono-4m02</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0yFTMAP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8t3mtymdrkevgjn473t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0yFTMAP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8t3mtymdrkevgjn473t.jpg" alt="IMAGE 2021-04-19 10:14:14"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My new favourite programming font is iA Writer Mono S:&lt;br&gt;
&lt;a href="https://github.com/iaolo/iA-Fonts/tree/master/iA%20Writer%20Mono"&gt;https://github.com/iaolo/iA-Fonts/tree/master/iA%20Writer%20Mono&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P. S. Also check out how they announced this and other fonts:&lt;br&gt;
&lt;a href="https://ia.net/writer/blog/a-typographic-christmas"&gt;https://ia.net/writer/blog/a-typographic-christmas&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Is it time to quit?</title>
      <dc:creator>Vasily Polovnyov</dc:creator>
      <pubDate>Mon, 12 Apr 2021 05:44:08 +0000</pubDate>
      <link>https://dev.to/vasily/is-it-time-to-quit-23k8</link>
      <guid>https://dev.to/vasily/is-it-time-to-quit-23k8</guid>
      <description>&lt;p&gt;The worst thing a programmer can do for his career is to trade ten years of his life not for ten years of experience, but for one year repeated ten times. You're sitting in your own cubicle, programming there, and then you stop and think: 'Wow!  It is amazing how crazy I really am: ten years in the same place with the same Drupal'.&lt;/p&gt;

&lt;p&gt;In order to spot such a problem in time, every six months I ask myself three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;What interesting, significant and important things have I done in the last six months?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What skills have I gained or improved over the past six months? Do I need them at all?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How am I doing with the team and company? What about the trust, values, and mission of the company? Do I still believe in them? Or is everything already filled with cynicism and pessimism?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the answers to two of the three questions are discouraging, it's time to quit.&lt;/p&gt;

</description>
      <category>rant</category>
    </item>
  </channel>
</rss>
