<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Run Faster Ruby on Rails Tests | Infinum</title>
		<atom:link href="https://infinum.com/blog/run-faster-ruby-on-rails-tests/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/run-faster-ruby-on-rails-tests/</link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 17 Apr 2026 13:59:15 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>8018https://infinum.com/uploads/2014/04/run-faster-ruby-on-rails-tests-0.webp</url>
				</image>
				<title>Run Faster Ruby on Rails Tests</title>
				<link>https://infinum.com/blog/run-faster-ruby-on-rails-tests/</link>
				<pubDate>Thu, 17 Apr 2014 12:21:00 +0000</pubDate>
				<dc:creator>Jan Varljen</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/run-faster-ruby-on-rails-tests/</guid>
				<description>
					<![CDATA[<p>Performing tests consumes precious time so we decided to do some tinkering to make our test suite load and execute faster.</p>
<p>The post <a href="https://infinum.com/blog/run-faster-ruby-on-rails-tests/">Run Faster Ruby on Rails Tests</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-202"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	Doing software development with a Continuous Integration process involves a lot of automated testing. Doing tests consumes precious time so we decided to do some tinkering to make our test suite load and execute faster.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	As your test suite grows, it takes longer to run the tests, and soon you have a problem because your test suite is running for over 10 minutes. Now you have two options: reduce the number of tests or optimize the test execution time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-99">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-100'
	>
	Impulse speed</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-102"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-103">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/04/run-faster-ruby-on-rails-tests-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="292"
															width="700"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	A few months ago, we wrote about how we do <a href="https://infinum.com/blog/a-ruby-on-rails-continous-integration-process-using-semaphore-github-codeclimate-and-hipchat/">Continuous Integration in Ruby on Rails</a>. Back then, a test suite for one of our projects (around 1400 tests) ran for about 7 minutes. Today, an even larger test suite (around 1700 tests) runs for 2 and a half minutes. How did we do it?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-108">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-109'
	>
	The mighty Zeus</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	Every time you call a rake task, your Rails application has to be loaded. The time it takes to load the application depends heavily on the size of the application and the number of gems the application is using. In our example, it was around 10 seconds. At first, 10 seconds doesn’t sound that bad, but when you realize you are calling rake tasks all the time and you have to wait for 10 seconds every time, you start to feel unproductive.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	So we started using <a href="https://github.com/burke/zeus">Zeus</a>. Zeus speeds up loading time of your Rails application by <strong>preloading your application only once</strong> and then monitoring file changes in your application directory and doing reloads in the background. Now you can call a rake task with: <strong>Zeus rake task</strong> and it’ll take less than one second to start because the Rails application is already preloaded.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	Running a large test suite with Zeus isn’t a big win (we cut off the first 10 seconds). It’s most useful when you’re doing <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> because you run your tests numerous times while developing. If you have to wait 10 seconds every time, it’s just not doable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	Just take this simple model spec with 9 tests as an example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">time</span><span class="token"> rspec spec/models/balance_spec.rb 
</span></span><span class="line"><span class="token" style="color: #6f42c1;">0m7.355s</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">time</span><span class="token"> zeus rspec spec/models/balance_spec.rb 
</span></span><span class="line"><span class="token" style="color: #6f42c1;">0m0.930s</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-125"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-126">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/04/run-faster-ruby-on-rails-tests-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="279"
															width="700"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Fig 1. Coming up to Warp 4!		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-128">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-129'
	>
	Spring maybe?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-131">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-132'
	>
	With the latest release of <a href="http://edgeguides.rubyonrails.org/4_1_release_notes.html">Rails 4.1</a>, the Spring application preloader was introduced as a part of the standard Rails environment. The idea behind Spring is the same as behind the mighty Zeus – preload your Rails application to speed up development. We tried using Spring on our projects and it works almost equally awesome. We favor Zeus primarily because it’s noticeably faster (roughly 30% faster), but we are eagerly awaiting any future reversals.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-134">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-135'
	>
	Running tests in parallel</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-137">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-138'
	>
	The thing that actually makes a huge difference when running a large test suite is running tests in parallel. Modern CPUs have lots of cores, which makes utilizing those cores for testing very effective.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-140">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-141'
	>
	Luckily, there is a gem called <a href="https://github.com/grosser/parallel_tests">Parallel Tests</a> which does just that. The gem creates multiple test databases (one for each core) and then distributes all tests across those cores and runs them in parallel.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-145"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-143">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-144'
	>
	You can even combine parallel tests with Zeus, using a gem called <a href="https://github.com/sevos/zeus-parallel_tests">Zeus Parallel Tests</a>. With this combination, <strong>we reduced the running time of our test suite by over 50%</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">time</span><span class="token"> rspec
</span></span><span class="line"><span class="token" style="color: #6f42c1;">1m50.843s</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">time</span><span class="token"> zeus parallel_rspec
</span></span><span class="line"><span class="token" style="color: #6f42c1;">0m52.924s</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-148"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-149">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/04/run-faster-ruby-on-rails-tests-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="279"
															width="700"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Fig 2. Approaching Warp 7!		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-151">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-152'
	>
	Mock, extract and refactor</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-156"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-154">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-155'
	>
	When a test is slow, it probably means that the model you’re testing is not optimized and you should be thinking about refactoring.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-159"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-157">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-158'
	>
	A typical antipattern is creating fat models with a lot of business logic and then wondering why tests are slow. It’s because you are testing things which don’t need to be tested (e.g. ActiveRecord) but mocked, and you’re needlessly hitting the database.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-162"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-160">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-161'
	>
	Let’s show this using a simple example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">PriceList</span><span class="token"> </span><span class="token">&lt;</span><span class="token"> </span><span class="token" style="color: #6f42c1;">ActiveRecord</span><span class="token" style="color: #6f42c1;">::</span><span class="token" style="color: #6f42c1;">Base</span><span class="token">
</span></span><span class="line"><span class="token">  has_many </span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">products</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">total_price</span><span class="token">
</span></span><span class="line"><span class="token">    products</span><span class="token">.</span><span class="token" style="color: #6f42c1;">sum</span><span class="token">(</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">price</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-166"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">require</span><span class="token"> ’spec_helper’</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">describe </span><span class="token" style="color: #005cc5;">PriceList</span><span class="token"> </span><span class="token" style="color: #d73a49;">do</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">let</span><span class="token">(</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">price_list</span><span class="token">)</span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #6f42c1;">create</span><span class="token">(</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">price_list</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">  describe ’</span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">total_price’ do</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">    before </span><span class="token" style="color: #d73a49;">do</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #6f42c1;">create</span><span class="token">(</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">product</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">price_list</span><span class="token" style="color: #005cc5;">:</span><span class="token"> price_list</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">price</span><span class="token" style="color: #005cc5;">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">100</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #6f42c1;">create</span><span class="token">(</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">product</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">price_list</span><span class="token" style="color: #005cc5;">:</span><span class="token"> price_list</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">price</span><span class="token" style="color: #005cc5;">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">200</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">    it </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #6f42c1;">expect</span><span class="token">(</span><span class="token">price_list</span><span class="token">.</span><span class="token" style="color: #6f42c1;">total_price</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">to</span><span class="token"> </span><span class="token" style="color: #6f42c1;">eq</span><span class="token">(</span><span class="token" style="color: #005cc5;">300</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-168"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">time</span><span class="token"> rspec spec/model/price_list_spec.rb 
</span></span><span class="line"><span class="token" style="color: #6f42c1;">0m8.396s</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-171"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-169">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-170'
	>
	Now let’s try to refactor our model and extract that <strong>#total_price</strong> functionality to a separate class so we can test it in isolation:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">PriceSheet</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">total_price</span><span class="token">(</span><span class="token">items</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    items</span><span class="token">.</span><span class="token" style="color: #6f42c1;">map</span><span class="token">(</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">price</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">inject</span><span class="token">(</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">+</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">PriceList</span><span class="token"> </span><span class="token">&lt;</span><span class="token"> </span><span class="token" style="color: #6f42c1;">ActiveRecord</span><span class="token" style="color: #6f42c1;">::</span><span class="token" style="color: #6f42c1;">Base</span><span class="token">
</span></span><span class="line"><span class="token">  has_many </span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">products</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">total_price</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">PriceSheet</span><span class="token">.</span><span class="token" style="color: #d73a49;">new</span><span class="token">.</span><span class="token" style="color: #6f42c1;">total_price</span><span class="token">(</span><span class="token">products</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-177"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">require</span><span class="token"> </span><span class="token" style="color: #005cc5;">File</span><span class="token">.</span><span class="token" style="color: #6f42c1;">expand_path</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">../../../lib/price_sheet.rb</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">__FILE__</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">describe </span><span class="token" style="color: #005cc5;">PriceSheet</span><span class="token"> </span><span class="token" style="color: #d73a49;">do</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">  describe ’</span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;">total_price’ do</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">let</span><span class="token">(</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">item_one</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #6f42c1;">double</span><span class="token">(</span><span class="token" style="color: #005cc5;">price</span><span class="token" style="color: #005cc5;">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">200</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">let</span><span class="token">(</span><span class="token" style="color: #005cc5;">:</span><span class="token" style="color: #005cc5;">item_two</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #6f42c1;">double</span><span class="token">(</span><span class="token" style="color: #005cc5;">price</span><span class="token" style="color: #005cc5;">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">100</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    it </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #6f42c1;">expect</span><span class="token">(</span><span class="token" style="color: #005cc5;">PriceSheet</span><span class="token">.</span><span class="token" style="color: #d73a49;">new</span><span class="token">.</span><span class="token" style="color: #6f42c1;">total_price</span><span class="token">(</span><span class="token">[</span><span class="token">item_one</span><span class="token">,</span><span class="token"> item_two</span><span class="token">]</span><span class="token">)</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">to</span><span class="token"> </span><span class="token" style="color: #6f42c1;">eq</span><span class="token">(</span><span class="token" style="color: #005cc5;">300</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">time</span><span class="token"> rspec spec/lib/price_sheet_spec.rb 
</span></span><span class="line"><span class="token" style="color: #6f42c1;">0m1.530s</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">time</span><span class="token"> zeus rspec spec/lib/price_sheet_spec.rb 
</span></span><span class="line"><span class="token" style="color: #6f42c1;">0m0.270s</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-180">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-181'
	>
	Now we don’t need to require the <strong>spec_helper</strong> (which loads Rails), we can mock the items and avoid hitting the database.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-183"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-184">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2014/04/run-faster-ruby-on-rails-tests-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="365"
															width="700"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Fig 3. Warp 9. Engage!		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-186">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-187'
	>
	We like this approach, not only because our tests are faster, but also because it drives us to write better code and avoid writing fat models.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-191"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-189">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-190'
	>
	Mocking external services</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-194"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-192">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-193'
	>
	One important thing to remember is &#8211; don’t let your tests access any external web services. There are several reasons why this is bad:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-195">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-196'
	>
	<li>It really slows down tests</li><li>Tests will fail if you don’t have internet connectivity</li><li>Hitting third party services will unnecessarily use API request limits</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-198">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-199'
	>
	This can be solved by disabling all remote connections in your tests, mocking the external service functionality and testing it in isolation. We use the <a href="https://github.com/bblimke/webmock">WebMock</a> gem for this.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/run-faster-ruby-on-rails-tests/">Run Faster Ruby on Rails Tests</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>