Skip to content

Instantly share code, notes, and snippets.

@systemnate
Last active August 8, 2017 14:19
Show Gist options
  • Save systemnate/1c2c360c9d55aed87ca3197864ee1653 to your computer and use it in GitHub Desktop.
Save systemnate/1c2c360c9d55aed87ca3197864ee1653 to your computer and use it in GitHub Desktop.
Single File Component Testing with Vue and Rails (Karma, Jasmine, Avoriaz)

Unit Testing

This wiki will demonstrate how to setup and test Vue components. I am assuming that Vue is already setup in the project using the webpacker gem.

This guide will use Karma, Jasmine, and Avoriaz for testing.

Karma - A test runner for unit tests.

Karma is essentially a tool which spawns a web server that executes source code against test code for each of the browsers connected. The results of each test against each browser are examined and displayed via the command line to the developer such that they can see which browsers and tests passed or failed.

Jasmine - A testing framework.

Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.

Avoriaz - A testing library specific to Vue that makes testing components easy.

a Vue.js testing utility library

Step 1: Setting up Jasmine

Install through Yarn:

yarn add jasmine --dev

Run the executable to create a jasmine.json file:

./node_modules/.bin/jasmine init

In package.json, setup the "scripts" section to run Jasmine:

"scripts": { "test": "jasmine" }

Now you can run the test suite by running yarn test

You should see "No specs found" since there are none yet.

Next, decide on a directory for placing your tests. I will use spec/javascript:

mkdir spec/javascript

Modify spec/support/jasmine.json to use your chosen directory. Specifically note the "spec_dir" section and the "spec_files" section. In this example it is looking for any files that end in spec.js or Spec.js placed in the spec/javascript directory.

{
  "spec_dir": "spec",
  "spec_files": [
    "javascript/*[sS]pec.js"
  ],
  "helpers": [
    "helpers/**/*.js"
  ],
  "stopSpecOnExpectationFailure": false,
  "random": false
}

Create a test file to make sure everything is working:

touch spec/javascript/test_spec.js. Inside the file:

describe('a simple test to get started', () => {
  it('false should be false', () => {
    let b = false;
    expect(b).toBe(false);
  });
});

Now running yarn test should show "1 spec, 0 failures".

Step 2: Setting up Karma

Install dependencies via yarn:

yarn add karm karma-jasmine karma-chrome-launcher jasmine-core --dev

Install the CLI tool as well:

yarn add karma-cli

Initialize karma:

karma init karma.conf.js

Answer the questions. Here is what I used:

Press tab to list possible options. Enter to move to the next question.
> jasmine

Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no

Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
>

What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
> spec/javascript/*[sS]pec.js

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>

Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes

You can now run Karma by running karma start (press CTRL+C to stop)

Step 3 - Setup karma-webpack

This step will allow your tests to fully support ECMAScript 2015 (ES6) including using import statements.

Install karma-webpack via yarn:

yarn add karma-webpack --dev

Now modify karma.js.conf so that it knows where your test files are:

    preprocessors: {
      'spec/javascript/*[sS]pec.js': ['webpack']
    },

Running karma start should still work.

Step 4 - Install Avoriaz

Install via yarn:

yarn add avoriaz --dev

In test_spec.js, add to the top of the file:

import { mount } from 'avoriaz'

Running karma start should work. If there are no errors then it is working successfully. You should see something like:

webpack: Compiled successfully.
Chrome 59.0.3071 (Mac OS X 10.12.4): Executed 1 of 1 SUCCESS (0.005 secs / 0.001 secs)

Step 5 - Testing Single File Components in Vue

Modify karma.js.conf so that it uses babel-loader and vue-loader. Here is my full karma.js.conf file:

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      'spec/javascript/*[sS]pec.js'
    ],
    exclude: [
    ],
    preprocessors: {
      'spec/javascript/*[sS]pec.js': ['webpack']
    },
    reporters: ['progress'],
    port: 9876,
    colors: true,
config.LOG_DEBUG
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: true,
    webpack: {
          module: {
            loaders: [
              {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
              },
              {
                test: /\.vue$/,
                loader: 'vue-loader'
              }
            ]
          }
        },
    concurrency: Infinity
  })
}

If you setup Vue using the webpacker gem then you should have a file in app/javascript/packs/app.vue that looks like this:

<template>
  <div id="app">
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data: function () {
    return {
      message: "Hello Vue!"
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

Here is a test spec/javascript/app_spec.js that uses all of these components together to make an assertion on a data property (message) of App.vue. Note that mount and #setData are from Avoriaz.

import { mount } from 'avoriaz'
import App from '../../app/javascript/packs/app.vue';

describe('the App.vue component', () => {
  it('It should have a message property of "Test Message"', () => {
    const appComponent = mount(App);
    appComponent.setData({message: 'Test Message'});
    expect(appComponent.data().message).toBe('Test Message');
  });
});

With both tests in place, you should now see something like:

Chrome 59.0.3071 (Mac OS X 10.12.4): Executed 2 of 2 SUCCESS (0.017 secs / 0.011 secs)

Now in package.json, replace "scripts" section with this:

  "scripts": {
    "test": "karma start"
  },

Now tests can be run by typing yarn test

Feature Specs

I have not been able to get feature specs working with capybara-webkit or poltergeist. However I have with ChromeDriver. Derek Prior from Thoughtbot has an excellent guide on getting this working: https://robots.thoughtbot.com/headless-feature-specs-with-chrome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment