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
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