<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.2">Jekyll</generator><link href="https://www.gravitystorm.co.uk/blog/tag/tests/feed/index.xml" rel="self" type="application/atom+xml" /><link href="https://www.gravitystorm.co.uk/" rel="alternate" type="text/html" /><updated>2026-05-13T14:06:51+00:00</updated><id>https://www.gravitystorm.co.uk/blog/tag/tests/feed/index.xml</id><title type="html">Gravitystorm Blog</title><author><name>Andy Allan</name></author><entry><title type="html">Factory Refactoring - Done!</title><link href="https://www.gravitystorm.co.uk/blog/2017/06/01/factory-refactoring-done/" rel="alternate" type="text/html" title="Factory Refactoring - Done!" /><published>2017-06-01T00:00:00+00:00</published><updated>2017-06-01T00:00:00+00:00</updated><id>https://www.gravitystorm.co.uk/blog/2017/06/01/factory-refactoring-done</id><content type="html" xml:base="https://www.gravitystorm.co.uk/blog/2017/06/01/factory-refactoring-done/"><![CDATA[<p>After over 50 Pull Requests spread over the last 9 months, I’ve <a href="https://github.com/openstreetmap/openstreetmap-website/pull/1556">finally finished</a> refactoring the <a href="https://github.com/openstreetmap/openstreetmap-website">openstreetmap-website</a> test suite to use factories instead of fixtures. Time for a celebration!</p>

<p>As I’ve discussed in <a href="/blog/2016/09/15/refreshing-the-openstreetmap-codebase/">previous</a> <a href="/blog/2017/02/21/steady-progress-osm-website/">posts</a>, the openstreetmap-website codebase powers the main OpenStreetMap website and the map editing API. The test suite has traditionally only used <a href="http://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures">fixtures</a>, where all test data was preloaded into the database and the same data used for every test. One drawback of this approach is that any change to the fixtures can have knock-on effects on other tests. For example, adding another diary entry to the fixtures could break a different test which expects a particular number of diary entries to be found by a search query. There are also more subtle problems, including the lack of clear intent in the tests. When you read a test that asserts that a given Node or Way is found, it was often not clear which attributes of the fixture were important - perhaps that Node belonged to a particular Changeset, or had a particular timestamp, or was in a particular location, or a mixture of other attributes. Figuring out these hidden intents for each test was often a major source of the refactoring effort - and there’s 1080 tests in the suite, with more than 325,000 total assertions!</p>

<p>Changing to <a href="https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#defining-factories">factories</a> has made the tests independent of each other. Now every test starts with a blank database, and only the objects that are needed are created, using the factories. This means that tests can more easily create a particular database record for the test at hand, without interfering with other tests. The intent of the test is often clearer too, since creating objects from factories happens in the test itself and are therefore explicit about what attributes are the important ones.</p>

<p>An example of the benefits of factories was when I <a href="https://github.com/openstreetmap/openstreetmap-website/pull/1348/files">fixed a bug</a> around encoding of diary entry titles in our RSS feeds. I easily created a diary entry with a specific and unusual title, without interfering with any other tests or having to create yet another fixture.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">test_rss_character_escaping</span>
  <span class="n">create</span><span class="p">(</span><span class="ss">:diary_entry</span><span class="p">,</span> <span class="ss">:title</span> <span class="o">=&gt;</span> <span class="s2">"&lt;script&gt;"</span><span class="p">)</span>
  <span class="n">get</span> <span class="ss">:rss</span><span class="p">,</span> <span class="ss">:format</span> <span class="o">=&amp;</span><span class="n">gt</span><span class="p">;</span> <span class="ss">:rss</span>

  <span class="n">assert_match</span> <span class="s2">"&lt;title&gt;&amp;lt;script&amp;gt;&lt;/title&gt;"</span><span class="p">,</span> <span class="n">response</span><span class="p">.</span><span class="nf">body</span>
<span class="k">end</span>
</code></pre></div></div>

<p>All in all, this took much, much longer than I was expecting! <a href="https://github.com/openstreetmap/openstreetmap-website/pull/1279">Looking back</a>, I feel I might have <a href="https://github.com/gravitystorm/openstreetmap-website/issues">picked a different task</a>, but I’m glad that it’s all done now. I’m certainly glad that I won’t have to do it all again! Moving on, it’s now easier for me and the other developers to write robust tests, and this will help us implement new features more quickly.</p>

<p>Big thanks go to Tom Hughes for reviewing all 51 individual pull requests! Thanks also to everyone who lent me their encouragement.</p>

<p>So the big question is - what will I work on next?</p>]]></content><author><name>Andy Allan</name></author><category term="development" /><category term="OpenStreetMap" /><category term="rails" /><category term="refactoring" /><category term="tests" /><summary type="html"><![CDATA[After over 50 Pull Requests spread over the last 9 months, I’ve finally finished refactoring the openstreetmap-website test suite to use factories instead of fixtures. Time for a celebration!]]></summary></entry></feed>