<?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>Forem: Chris Fung</title>
    <description>The latest articles on Forem by Chris Fung (@aergonaut).</description>
    <link>https://forem.com/aergonaut</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%2F19418%2Ffe9f1da2-4d80-48ee-9752-8ef5a8611954.jpg</url>
      <title>Forem: Chris Fung</title>
      <link>https://forem.com/aergonaut</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/aergonaut"/>
    <language>en</language>
    <item>
      <title>Running Rails 5 System Tests on Travis CI with Chromedriver</title>
      <dc:creator>Chris Fung</dc:creator>
      <pubDate>Sun, 29 Jul 2018 22:35:59 +0000</pubDate>
      <link>https://forem.com/aergonaut/running-rails-5-system-tests-on-travis-ci-with-chromedriver-4nm7</link>
      <guid>https://forem.com/aergonaut/running-rails-5-system-tests-on-travis-ci-with-chromedriver-4nm7</guid>
      <description>&lt;p&gt;Rails 5.1 introduced the concept of &lt;a href="https://weblog.rubyonrails.org/2017/4/27/Rails-5-1-final/#system-tests"&gt;system tests&lt;/a&gt; using Capybara and Selenium. System tests takes the practice of "feature" tests that many Rails apps were already doing and brings it into an official part of the Rails testing strategy. Since system tests utilize a browser, they can execute Javascript, something that Rails integration tests could not do.&lt;/p&gt;

&lt;p&gt;System tests work great out of the box on local machines, but getting them set up to run on a remote server like Travis CI is a little harder. There's not a lot of good documentation out there for what needs to be done, and a lot of solutions have to be dug up through Stack Overflow and GitHub comment threads.&lt;/p&gt;

&lt;p&gt;In this post, I'll show how I set up system tests to run on Travis CI using headless Chrome and Chromedriver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rails 5.1.6
&lt;/h2&gt;

&lt;p&gt;Although system tests were announced with 5.1, you really should make sure you are using Rails 5.1.6 to get the best experience. This is because after the initial release there were a few other small quality of life improvements made to the framework that are great to have.&lt;/p&gt;

&lt;p&gt;Among these are a change to ActiveRecord that allows the Capybara thread and the test server thread to use the same database connection (see &lt;a href="https://github.com/rails/rails/pull/28083"&gt;rails/rails#28083&lt;/a&gt;). This is important when using transactions because otherwise the two threads would not be able to see DB changes made by the other thread.&lt;/p&gt;

&lt;p&gt;In the past, you would have had to work around this by turning off transactions and adding Database Cleaner or some similar gem to clean up data created during test runs. But this would have meant that either Rails would need to pull Database Cleaner in as a dependency, or anyone wanting to use system tests would need to add another gem to their Gemfile manually. Neither of those were good for the future adoption of system tests, so instead the Rails team updated ActiveRecord to allow the connection to be shared.&lt;/p&gt;

&lt;h2&gt;
  
  
  RSpec 3.7
&lt;/h2&gt;

&lt;p&gt;I prefer using RSpec as my test framework. RSpec 3.7 added &lt;a href="http://rspec.info/blog/2017/10/rspec-3-7-has-been-released/#rails-actiondispatchsystemtest-integration-system-specs"&gt;support for system tests&lt;/a&gt; into the framework, replacing the previous feature specs.&lt;/p&gt;

&lt;p&gt;If you are using RSpec, you will need to make sure you are using version 3.7 in order to use system tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Chromedriver
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://chromedriver.chromium.org/"&gt;Chromedriver&lt;/a&gt; allows Chrome to be controlled by Selenium and is necessary in order for us to use Chrome as the browser in system tests.&lt;/p&gt;

&lt;p&gt;You can download Chromedriver from the project's website, or it can be installed with Homebrew Cask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew cask install chromedriver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Removing chromedriver-helper
&lt;/h3&gt;

&lt;p&gt;If you have worked with Chromedriver in the past, you may have installed the Ruby gem &lt;a href="https://rubygems.org/gems/chromedriver-helper"&gt;chromedriver-helper&lt;/a&gt;. If you want to use Chromedriver directly, you will need to remove chromedriver-helper and it's executables from your system.&lt;/p&gt;

&lt;p&gt;If you're using rbenv, you can use the commands I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gem uninstall chromedriver-helper
$ ls ~/.rbenv/versions/*/bin/* | grep chromedriver | xargs rm
$ rbenv rehash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: Removing chromedriver-helper may or may not be necessary for you, depending on your setup. I found it was causing problems for me, so I decided to remove it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Selecting a driver
&lt;/h2&gt;

&lt;p&gt;System tests abstract Capybara's drivers using the &lt;code&gt;driven_by&lt;/code&gt; method. With regular system tests, you would include &lt;code&gt;driven_by&lt;/code&gt; in your &lt;code&gt;ApplicationSystemTestCase&lt;/code&gt;. RSpec, however, does not use &lt;code&gt;ApplicationSystemTestCase&lt;/code&gt;, so you need to configure the driver in a &lt;code&gt;before&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;The easiest way to do this is by adding a global &lt;code&gt;before(:each)&lt;/code&gt; to &lt;code&gt;rails_helper.rb&lt;/code&gt;:&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;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:each&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: :system&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;driven_by&lt;/span&gt; &lt;span class="ss"&gt;:selenium&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;using: :chrome&lt;/span&gt;
  &lt;span class="k"&gt;end&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 will set all system tests to be driven by Selenium using Chrome.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;type: :system&lt;/code&gt; indicates that this &lt;code&gt;before&lt;/code&gt; block will only apply to tests marked as system tests. RSpec will infer that a test is a system test if it is located in &lt;code&gt;spec/system&lt;/code&gt;, or you can tag specs manually.&lt;/p&gt;

&lt;p&gt;Now running &lt;code&gt;bundle exec rspec&lt;/code&gt; should open a Chrome window and run your system specs. Cool!&lt;/p&gt;

&lt;h2&gt;
  
  
  Going headless
&lt;/h2&gt;

&lt;p&gt;Opening a browser window works fine on your local machine, but it won't work on a remote server because there's no monitor to render the window. Instead, we have to use Chrome in headless mode.&lt;/p&gt;

&lt;p&gt;To use headless Chrome, we can pass some extra arguments to &lt;code&gt;driven_by&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; RSpec.configure do |config|
   config.before(:each, type: :system) do
&lt;span class="gd"&gt;-    driven_by :selenium, using: :chrome
&lt;/span&gt;&lt;span class="gi"&gt;+    driven_by :selenium, using: :chrome, options: { args: ["headless"] }
&lt;/span&gt;   end
 end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are other ways to use headless mode, and the downside of this method is that it causes Selenium to throw a deprecation warning. For reasons we'll see later, we have to use this method of passing arguments.&lt;/p&gt;

&lt;p&gt;Now running &lt;code&gt;bundle exec rspec&lt;/code&gt; should &lt;strong&gt;not&lt;/strong&gt; open a browser window. Neat!&lt;/p&gt;

&lt;h2&gt;
  
  
  Running on Travis
&lt;/h2&gt;

&lt;p&gt;Getting the tests to run on Travis is the trickiest part. For my build, I wanted to use Travis's Docker infrastructure with &lt;code&gt;sudo: false&lt;/code&gt; in my &lt;code&gt;.travis.yml&lt;/code&gt; file. This meant that I had to work around several limitations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Chrome and Chromedriver
&lt;/h3&gt;

&lt;p&gt;To install packages on Travis, you need to use the &lt;code&gt;addons&lt;/code&gt; section in your config file. Although Travis has an &lt;a href="https://docs.travis-ci.com/user/chrome"&gt;addon specifically for Chrome&lt;/a&gt;, I ended up having some problems using this. Instead, I used the &lt;code&gt;apt&lt;/code&gt; addon to install both Chrome and Chromedriver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;addons&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;google-chrome-stable&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chromium-chromedriver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Selenium expects to find Chromedriver on the PATH, but the default installation on Travis does not put the binary on the PATH. To fix this, I created a symlink in the &lt;code&gt;before_script&lt;/code&gt; step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ln -s /usr/lib/chromium-browser/chromedriver ~/bin/chromedriver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the Travis environment is set up correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chrome crashes on launch
&lt;/h3&gt;

&lt;p&gt;Even with the environment set up correctly, my tests were still failing because Chrome would immediately crash on launch. After a lot of digging, I found &lt;a href="https://developers.google.com/web/tools/puppeteer/troubleshooting#running_puppeteer_on_travis_ci"&gt;this troubleshooting page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are two takeaways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need to &lt;a href="https://developers.google.com/web/tools/puppeteer/troubleshooting#running_puppeteer_on_travis_ci"&gt;run Chrome with &lt;code&gt;--no-sandbox&lt;/code&gt;&lt;/a&gt; in order for it to work properly on Travis.&lt;/li&gt;
&lt;li&gt;We need to &lt;a href="https://developers.google.com/web/tools/puppeteer/troubleshooting#tips"&gt;disable usage of &lt;code&gt;/dev/shm&lt;/code&gt;&lt;/a&gt; because Docker provisions too little space in that device and Chrome crashes if there's not enough space.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to do this, we need to be able to pass custom arguments to Selenium, which is why we are using the &lt;code&gt;driven_by&lt;/code&gt; options that we have.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; RSpec.configure do |config|
   config.before(:each, type: :system) do
&lt;span class="gd"&gt;-    driven_by :selenium, using: :chrome
&lt;/span&gt;&lt;span class="gi"&gt;+    driven_by :selenium, using: :chrome, options: { args: ["headless", "disable-gpu", "no-sandbox", "disable-dev-shm-usage"] }
&lt;/span&gt;   end
 end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;disable-gpu&lt;/code&gt; argument is there on recommendation from &lt;a href="https://developers.google.com/web/updates/2017/04/headless-chrome#cli"&gt;this page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now your system tests should successfully run on Travis! Awesome!&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra credit: Filter system tests with metadata
&lt;/h2&gt;

&lt;p&gt;As we have it set up now, RSpec will run all system tests whenever we run the full test suite. But system tests are slow and we probably don't want to run them all the time. Luckily RSpec has a way to filter out certain specs from the run based on the metadata on the spec.&lt;/p&gt;

&lt;p&gt;Let's tag all specs in &lt;code&gt;spec/system&lt;/code&gt; with the &lt;code&gt;browser&lt;/code&gt; tag. To do this, we can use &lt;code&gt;define_derived_metadata&lt;/code&gt;:&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;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_derived_metadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;file_path: &lt;/span&gt;&lt;span class="sr"&gt;/spec\/system/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:browser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can use &lt;code&gt;filter_run_excluding&lt;/code&gt; to filter &lt;code&gt;browser&lt;/code&gt; specs by default:&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;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter_run_excluding&lt;/span&gt; &lt;span class="ss"&gt;browser: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when running &lt;code&gt;bundle exec rspec&lt;/code&gt;, system tests will be filtered out. To run the system tests, we can use the &lt;code&gt;-t&lt;/code&gt; option to &lt;strong&gt;include&lt;/strong&gt; &lt;code&gt;browser&lt;/code&gt; specs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ bundle exec rspec -t browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to change your &lt;code&gt;.travis.yml&lt;/code&gt; to use &lt;code&gt;-t&lt;/code&gt; to run the system tests. Having system tests split off from the rest of the test suite allowed me to parallelize running the slow system tests with running the rest of the suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;System tests are a really easy way to get started with feature testing. The default configuration shipped with Rails should work for most people, and extending it to use a different browser or pass different options is straightforward. What was harder was trying to figure out how to use system tests on Travis, with not a lot of documentation or examples to go off of.&lt;/p&gt;

&lt;p&gt;With this post, I have gathered together everything I learned in getting system tests running on Travis CI. I hope it's useful!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>selenium</category>
      <category>chromedriver</category>
      <category>testing</category>
    </item>
    <item>
      <title>Setting up Jest with React and Webpacker</title>
      <dc:creator>Chris Fung</dc:creator>
      <pubDate>Thu, 10 May 2018 06:11:51 +0000</pubDate>
      <link>https://forem.com/aergonaut/setting-up-jest-with-react-and-webpacker-5dmo</link>
      <guid>https://forem.com/aergonaut/setting-up-jest-with-react-and-webpacker-5dmo</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/rails/webpacker"&gt;Webpacker&lt;/a&gt; is a great library that was &lt;a href="http://weblog.rubyonrails.org/2017/4/27/Rails-5-1-final/"&gt;introduced&lt;/a&gt; in Rails 5.1. It gives an easy, out-of-the-box way to configure the latest Javascript tools, including Babel, Webpack, and React, to work seamlessly with Rails.&lt;/p&gt;

&lt;p&gt;Generating a new React project with Webpacker is as easy as running one &lt;code&gt;rails&lt;/code&gt; command. But how to write tests for your new React components is a little less clear. There's a myriad of different testing libraries out there for Javascript code, and the ecosystem can be a little confusing.&lt;/p&gt;

&lt;p&gt;In this post, I'll show how I set up testing for my React components using Jest, and how I integrated Jest into my existing CI workflow for my Rails app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Jest
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://facebook.github.io/jest/"&gt;Jest&lt;/a&gt; is a Javascript testing library that's easy to set up and fast. It was developed by Facebook and has lots of support for testing React components.&lt;/p&gt;

&lt;p&gt;Because Webpacker uses Babel, setting up Jest requires installing one extra package: &lt;code&gt;babel-jest&lt;/code&gt;. This allows Jest to transpile code using Babel while testing. Install them both with &lt;code&gt;bin/yarn&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/yarn install jest babel-jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a test
&lt;/h2&gt;

&lt;p&gt;By default Jest will look for any file in a &lt;code&gt;__tests__&lt;/code&gt; directory or any file ending in &lt;code&gt;*test.js&lt;/code&gt; and treat those files as test suites. "Suite" is Jest's term for a file containing one or more tests.&lt;/p&gt;

&lt;p&gt;With Webpacker, React components are stored in the &lt;code&gt;app/javascript&lt;/code&gt; directory. I had a directory structure like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/javascript
├── packs
└── pulls
    └── components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;components&lt;/code&gt; directory is where all my components live, so I made a &lt;code&gt;__tests__&lt;/code&gt; directory inside that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Jest
&lt;/h2&gt;

&lt;p&gt;To run Jest, I added a new script to my &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run Jest with Yarn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/yarn test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However when I did this initially, I got an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ bin/yarn test
yarn run v1.5.1
$ jest
 FAIL  config/webpack/test.js
  ● Test suite failed to run

    Your test suite must contain at least one test.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's going on here is that Jest is assuming Webpacker's &lt;code&gt;test.js&lt;/code&gt; config file is a test file because it ends in &lt;code&gt;test.js&lt;/code&gt;. That's obviously not right! Luckily we can tell Jest to ignore certain file patterns with the &lt;a href="https://facebook.github.io/jest/docs/en/configuration.html#testpathignorepatterns-array-string"&gt;&lt;code&gt;testPathIgnorePatterns&lt;/code&gt;&lt;/a&gt; configuration option.&lt;/p&gt;

&lt;p&gt;Jest configuration goes in &lt;code&gt;package.json&lt;/code&gt; under the &lt;code&gt;jest&lt;/code&gt; key. We just need to add &lt;code&gt;config/webpack/test.js&lt;/code&gt; to the list of ignored paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"testPathIgnorePatterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"/node_modules/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;rootDir&amp;gt;/config/webpack/test.js"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Babel modules
&lt;/h2&gt;

&lt;p&gt;Another error I ran into was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SyntaxError: Unexpected token import
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem here is that because Jest runs in Node, it needs to compile your code into CommonJS modules. However, by default, Webpacker configures Babel with &lt;code&gt;"modules": false&lt;/code&gt; which tells Babel to skip transpiling ES6 modules into another format.&lt;/p&gt;

&lt;p&gt;There's two ways to fix this. The first way is to remove &lt;code&gt;"modules": false&lt;/code&gt; from Babel in the test environment. You can do this using the &lt;a href="https://babeljs.io/docs/usage/babelrc/#env-option"&gt;env option&lt;/a&gt; in &lt;code&gt;.babelrc&lt;/code&gt;. However, when I tried this, I got different errors when Babel was transpiling my components. Ultimately, I decided that this way was not going to work out for me.&lt;/p&gt;

&lt;p&gt;The second way is to add &lt;code&gt;babel-plugin-transform-es2015-modules-commonjs&lt;/code&gt; to the test environment. This plugin will transform ES modules into CommonJS modules. I installed the plugin and added it to my &lt;code&gt;.babelrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"transform-es2015-modules-commonjs"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now running &lt;code&gt;bin/yarn test&lt;/code&gt; is successful!&lt;/p&gt;

&lt;h2&gt;
  
  
  Running on Travis CI
&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://travis-ci.org/"&gt;Travis CI&lt;/a&gt; to run my tests, so I wanted to run Jest on Travis as well. Adding the test command to my &lt;code&gt;.travis.yml&lt;/code&gt; file was simple enough, but I started getting more errors from Jest trying to run other Javascript files just because they were named with &lt;code&gt;test.js&lt;/code&gt; at the end.&lt;/p&gt;

&lt;p&gt;This turned out to be because Travis installs the Webpacker gem to the &lt;code&gt;vendor&lt;/code&gt; directory in your project, which puts it in the path of searchable directories for Jest to discover tests in. I had to add the vendor directory to my list of ignored paths.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;All in all, setting up Jest to work with Webpacker had a few minor hiccups but they were all easy to overcome. Testing React components with Jest is very easy, and I was surprised that it worked so well with Webpacker's config out of the box!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>webpacker</category>
      <category>jest</category>
      <category>react</category>
    </item>
  </channel>
</rss>
