Currently only the following languages/frameworks are supported:
- Languages:
- ES6 (ECMAScript2015)
- Testing frameworks:
mocha
(throughatom-mocha
)
- Coverage frameworks:
Feel free (and encouraged!) to contribute and improve this package to work with other languages/frameworks!
$ cd your-atom-pkg
$ npm install babel-cli babel-core babel-plugin-istanbul \
babel-preset-env nyc atom-mocha atom-coverage --save-dev
$ npm run test:coverage
After installing, you'll have two new NPM scripts (won't be overwritten if already present):
test:coverage
: runs your specs and generates code coverage reports on finish.check:coverage
: checks if your coverage is above your thresholds. Read how to configure thresholds withnyc
.
I strongly recommend you to define your tests script as
cross-env NODE_ENV=test atom --test spec/*.spec.js spec/**/*.spec.js
.
apm test
does not allow for subdirectories, as opposed to atom --test
.
Having subfolders allows a clearer, properly scoped structure for your
tests/specs.
NOTE:
atom --test spec/*.js
will fail if no.js
files present atspec/
, andatom --test spec/**/*.js
will fail if no.js
files present in any subfolder underspec/
. This has nothing to do with AtomMocha, but Atom itself, so define yourtest
script congruently/coherently with your project structure.
atom-coverage
uses the config files of the involved frameworks if present.
If any of them is missing or has an incorrect configuration, it will
automatically create them or solve the conflicts for you (to some extent, of
course).
Assuming atom-pkg/
is the root folder of your Atom package, let's dig into
each config file...
This is the configuration file for atom-coverage
itself. You can also provide
this configuration through the property atomCoverage
inside your Atom
package's package.json
.
The list of currently supported options are:
Option | Type | Description | Default | Valid |
---|---|---|---|---|
instrumenter |
String | The coverage framework to use | nyc |
nyc |
transpiler |
String | The transpiler to use | babel |
babel |
sourcesRoot |
String | The relative path to the root of your Atom package's source files | lib/ src/ |
- |
testScript |
Script | The NPM script to execute your tests and get them covered with the configured instrumenter |
test |
- |
This is the configuration file for babel
, which
atom-coverage
uses to transpile your ES6 code into ES5 that nyc
understands.
The minimum required configuration is:
{
"env": {
"test": {
"plugins": [
// You must install as devDep any babel plugin that your Atom package
// requires to get successfully transpiled, and include it here
"...",
"istanbul"
],
"sourceMaps": "inline"
}
},
"presets": ["env"]
}
Helpful links:
NOTE 1: The order of the Babel plugins matters, so you must find the correct order for your code to get transpiled, being
istanbul
always the last one (AtomCoverage enforces this).NOTE 2:
atom-coverage
does NOT currently support Babel config inpackage.json
.
This is the configuration file for nyc
, which
atom-coverage
uses to analyze the code coverage of your pre-instrumented files.
Some nyc
options don't work when pre-instrumenting source files. You don't
need to care about this, since atom-coverage
fixes them for you! The list of
fixed options includes (but is not limited to, since I haven't thoroughly tested
all options):
include: String[]
: array ofglob
-compliant strings. If you provide a folder instead of a glob (i.e.,lib
orlib/
), it will be extended to recursively get all JavaScript files in that folder (previous example would be extended tolib/**/*.js
).all: boolean
: setall=true
inside yournyc
config file to recursively, automagically get all your source files undersourcesRoot
folder included and covered.
Helpful links:
nyc
official sitenyc
code for its settings API
NOTE:
atom-coverage
does NOT currently supportnyc
config inpackage.json
.
We will refer to you files/modules as UUT (Units Under Test) from here on.
AtomCoverage wraps your NPM test command to analyze the code coverage based on
your package tests. It doesn't make any magic to infer how to test your specs.
You must define that in an NPM script, given by the option testScript
(which
defaults to test
script if not provided).
You need to require()
your pre-instrumented files instead your source files
inside your tests/specs for the code coverage to work, but this would break your
tests when running without coverage (in that case you should only request your
source files). That's why this package exports an alternative require()
called
testquire()
, which loads your source files or the pre-instrumented ones,
depending if you request code coverage (thus loading pre-instrumented files) or
not (thus loading source files). You don't need to configure anything. It
resolves both cases automatically for you. The only thing you need inside your
tests/specs is:
const { testquire } = require('atom-coverage');
const uut = testquire('path/relative/to/sources/root/for/uut');
NOTE: You don't need to care about the depth level of your source/test files!
atom-coverage
automatically takes charge of that for you too!
Let's assume you keep your source files under lib/
, and you want
to load a file placed at lib/folder1/folder2/file.js
. Then you require it
inside your test/spec as:
const { testquire } = require('atom-coverage');
const uut = testquire('folder1/folder2/file');
If you run npm test
, testquire()
will require your source file at
lib/folder1/folder2/file.js
.
If you run npm run test:coverage
, testquire()
will require your instrumented
file at coverage/.instrumented/folder1/folder2/file.js
(assuming that you're
using the default options for nyc
and atom-coverage
).
What if you want to stub some of your files/modules inside your instrumented
files? You can do that with the awesome
proxyquire
package.
You need to feed proxyquire()
with the path to your instrumented files to
inject your stubs, but hardcoding the paths would be unmaintainable (and it
would break running only your specs, in addition). That's why you can pass a
second parameter requireIt
to testquire()
, which manages whether (1) to
require the file and return it (requireIt=true
) or (2) not (requireIt=false
).
So you could use proxyquire
as follows:
const { testquire } = require('atom-coverage');
const proxyquire = require('proxyquire');
const uutPath = testquire('folder1/folder2/file', false);
const uutDepStub = {};
const uut = proxyquire(uutPath, {
'path/to/dep/exactly/as/required/inside/uut': uutDepStub,
});
NOTE: Requiring NodeJS core modules or external dependencies is done as usual (i.e.,
require('fs')
orrequire('npmPackage')
).
If you would like to contribute to projects
, please, read carefully the
semantic-release
contributing guidelines,
which I adhere to, and do the following:
# 01. Clone your fork of this repository into a local folder.
$ git clone git@github.com:your-user/atom-coverage.git
# 02. Enter the cloned package.
$ cd ./atom-coverage
# 03. Assign the original repo to a remote called "upstream".
$ git remote add upstream https://github.com/cgalvarez/atom-coverage
# 04. Create a new topic branch off the master branch that describe
# what your PR does and use it.
$ git checkout -b 'your-pr-topic'
# 05. Choose on command to install the package dependencies based on
# your package manager.
$ (yarn|npm) install
# 06. Make your changes and write specs to test them.
# 07. Ensure that your changes pass the project requirements
# (linting, tests, coverage...).
$ (yarn|npm) run check
# 08. Once you've finished, commit your changes with commitizen.
$ (yarn|npm) run semantic-commit
# 09. Send a pull request describing what you have done.
If you want to support a different testing/coverage framework, please, help other developers with the same needs/preferences/desires as you 😊, help the open source community ❤️ and contribute to the project by making an awesome pull request! ✨
© 2018 Carlos García (@cgalvarez), All rights reserved.
AtomCoverage is released under the MIT License.