- Notifications
You must be signed in to change notification settings - Fork14
Server and client coverage for Meteor
License
serut/meteor-coverage
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A meteor package that allows you to get the statement, line, function and branch coverage of Meteor project and package.
This package uses theistanbuljs set of packages to generate reports. Starting from Meteor 1.8, this package does not instrument your code to get coverage as you can let babel do it using thebabel plugin istanbul.
It's a debug only package, so it does not affect your production build.
Travis | Circle CI | Coveralls | Codecov | Codacy | |
---|---|---|---|---|---|
lmieulet:meteor-coverage | |||||
meteor-coverage-app-exemple |
meteor-coverage | Meteor | spacejam & practicalmeteor | meteortesting:mocha |
---|---|---|---|
1.x | <1.6.0 | ✔ | ✘ |
not supported | 1.6.0 <1.6.1 | ✘ | ✘ |
2.x | >=1.6.1 and < 1.8 | ✘ | ✔ |
3.x | >=1.8 | ✘ | ✔ |
Table of Contents
- Installation
- Advanced setup for CI
- Global environment variable
- Config file
- My files are missing from my app coverage report
- Meteor ignored folders and files
- How to use another test runner
- I want my reports referred to my original source files
- Client API
- Contributing
- Credits
Ensure you use at least Meteor versionv1.8
. If you are using Typescript, jumphere
Then, run the following :
meteor add lmieulet:meteor-coverage meteortesting:mochameteor npm init # If the package.json file does not existmeteor npm install --save-dev babel-plugin-istanbul
In order to instrument your code, you need to add thebabel-plugin-istanbul
to your babel config. If you don't have a babel config file, edit your package.json file, or useany other babel configuration file (see .babelrc.js).
{"name":"my-package","version":"1.0.0","babel": {"env": {"COVERAGE": {"plugins": ["istanbul" ] } } }}
You must wrap the istanbul plugin with theenv
setting to disable the file-instrumentation of your project when you are not running the test coverage script. Just keep in mind that if you follow the here under script, babel will use theistanbul
package only whenBABEL_ENV=COVERAGE
.
Now, to run the coverage process, just add these new scripts inside yourpackage.json
in the root folder of your app:
"scripts": {"coverage:unit":"BABEL_ENV=COVERAGE TEST_BROWSER_DRIVER=puppeteer COVERAGE=1 COVERAGE_OUT_HTML=1 COVERAGE_APP_FOLDER=$PWD/ meteor test --once --driver-package meteortesting:mocha","coverage:watch":"BABEL_ENV=COVERAGE COVERAGE=1 COVERAGE_VERBOSE=1 COVERAGE_APP_FOLDER=$PWD/ TEST_WATCH=1 meteor test --driver-package meteortesting:mocha" }
You can find more options on themeteortesting readme. Let's try the watch mode :
meteor npm run test:watch:coverage
Now open yourbrowser test page localhost:3000/ and the pagelocalhost:3000/coverage. You can notice the client coverage is completly missing but server one is there. A missing feature would be to save your client coverage with a widget. Instead, you need to enter this javascript in your browser console (in the page where tests are executed):
Meteor.sendCoverage(function(stats,nbErr) {console.log(stats,nbErr);});# Reopen localhost:3000/coverage to see that client coverage have been saved on server# Creates an html export inside coverage_app_folder/output_folder/index.htmlMeteor.exportCoverage("html", function(err) {console.log(err)})
Refresh thelocalhost:3000/coverage in your browser to see there is client coverage now.
In a meteor package, you need to add inside thepackage.js
file:
[...]Package.onTest(function(api){api.use(['lmieulet:meteor-legacy-coverage@0.2.0','lmieulet:meteor-coverage@3.0.0','meteortesting:mocha']);[...]});
Creating a Meteor package in 2018 is a nightmare, so please stay calm when you discover the followingpackage.json
that prevents so many issues :
"scripts": { "setup-test": "rm -rf ./someapp && meteor create --bare someapp && cd someapp && cp ../.coverage.json . && meteor npm i --save puppeteer && mkdir packages && ln -s ../../ ./packages/meteor-coverage", "test": "meteor npm run setup-test && cd someapp && TEST_BROWSER_DRIVER=puppeteer COVERAGE_VERBOSE=1 COVERAGE=1 COVERAGE_OUT_LCOVONLY=1 COVERAGE_APP_FOLDER=$(pwd)/ meteor test-packages --once --driver-package meteortesting:mocha ./packages/meteor-coverage", "test:watch": "cd someapp && TEST_WATCH=1 COVERAGE=1 COVERAGE_APP_FOLDER=$(pwd)/ meteor test-packages --driver-package meteortesting:mocha ./packages/meteor-coverage" }
The tasksetup-test
is the cutting edge workaround that creates an empty meteor app that will run your test later.
If you use Typescript, you cannot use babel to instrument your code, you need to rely onlmieulet:meteor-legacy-coverage
(like packages).
The installation is almost the same as normal Meteor application, but you don't need to install all the babel stuff, you just need to run the following :
meteor add lmieulet:meteor-legacy-coverage
You can look at thedeskoh/Meteor-React-Typescript-Starter if you need to see a working exemple.
Install
meteor npm i --save-dev coveralls
Add this after tests execution:
# Send coverage reportcat .coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js || true # ignore coveralls error
Install
meteor npm i --save-dev codecov.io
Add this after tests execution:
cat .coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js || true # ignore codecov error
DeprecatedYou can provides settings by setting these environment variables:
COVERAGE=1
to enable coverageCOVERAGE_APP_FOLDER=/path/to/your/meteor/app/
- Used to see if you have a customized
.coverage.json
file - Used by istanbul in reports if the file has source map
- Needs to end with a trailing slash
- Used when importing or exporting coverage reports
- Used to see if you have a customized
COVERAGE_VERBOSE=1
to see logs (optional)
If you have packages used by your project (ex: aldeed:simple-schema) or libraries on your client side (ex: OpenLayers, Jquery), you can hide the coverage of these files from reports. You can specify which files will not be covered in a.coverage.json
file inside theCOVERAGE_APP_FOLDER
folder.
If you do not have this file, this package will use the default one (conf/default-coverage.json
). If you do not define a key in the.coverage.json
file, the default one will be used.
Exemple:
"--": "Meteor app does not require any specific configuration", "--": "If you want to instrument a package, you need to add the following", "remapFormat": ["html", "cobertura", "clover", "json", "json-summary", "lcovonly", "teamcity", "text", "text-summary"], "output": "./.coverage"}
Details :
- The glob syntax can be foundhere.
- To create your custom config file, run the project with
COVERAGE_VERBOSE=1
env variable and use logs to see which filenames were hooked or hidden. PR welcome. - The output folder needs to starts with a dot to exclude that folder from Meteor build.
If you haveinternal packages inside your app and you want to get theirserver side coverage. Open the file.meteor/packages
and move the linelmieulet:meteor-coverage
to be above these packages.
- hidden folders like .npm, .coverage or .meteor.
- special folders like node_modules.
- all meteor packages (bundled and/or manually installed ones) like meteor/underscore, meteor/accounts-password or aldeed:simple-schema.
- all tests file(s) containing
spec?|test?|specs?|tests?|app-specs?|app-tests?
and all folder(s) namedspecs?|tests?|app-specs?|app-tests?
You can findhere the diff between "spacejam without coverage" and "spacejam coverage", so you can build something else, with grunt for example, that exports your test. meteortesting:mocha did also the same.
If you are using a language that compiles to JavaScript (there arelots of them), you may want to see your coverage reports referred to the original source files (prior to compilation).
To remap your source files, you have to provide the report typeout_remap
explicitly when usingspacejam
:spacejam-mocha --coverage out_remap
You'll get your remapped coverage reports at./.coverage/.remap
(orcustom_output/.remap
if you're customized the output folder through the file.coverage.json
).
The coverage is remapped toall the available reports (listed in the following example) by default. If you only want some of them, you need to request them explicitly through the keyremap.format
in.coverage.json
like this:
{"remap": {"format": ["html","clover","cobertura","json","json-summary","lcovonly","teamcity","text","text-summary"] }}
If you want to remap the coverage withMeteor.exportCoverage()
, then you must use the report typeremap
.
This feature has only been tested with TypeScript, but it should work for any language compiled to JavaScript, justmake sure you generate source maps (*.js.map) for all the compiled files and that source maps are located next to their respective compiled JavaScript file (*.js), just like this:
COVERAGE_APP_FOLDER├── tsconfig.json├── src| ├── my-file.ts| └── my-file.d.ts├── build| ├── my-file.js| └── my-file.js.map
Run the following command in your browser and the client coverage will be saved into the server coverage report.
Meteor.sendCoverage(function(stats,nbErr){console.log(stats,nbErr);});
Why? When a browser opens the client side of your application, this package intercepts all queries matching*.js
to respond the instrumented version of the original script, if they are not ignored by the configuration file. All these instrumented scripts are autonomous and they save the coverage in a global variable when you execute a line of a file. This global variable needs to be sent back to the server to create a full coverage report.
type: the type of report you want to create inside your
COVERAGE_APP_FOLDER
- Default:
coverage
, used to dump the coverage object in a file because when there are several types of test, we want to merge results, and the server reloads between each one. - Allowed values:
coverage
,html
,json
,json-summary
,lcovonly
,remap
,text-summary
- Not working values:
clover
,cobertura
,lcov
,teamcity
,text
,text-lcov
, PR welcome - Except for
coverage
, the file generation is handled byistanbuljs/istanbul-reports
- Default:
Meteor.exportCoverage(null,function(err){console.log(err)})
Import acoverage
export.
Meteor.importCoverage(function(err){console.log(err)})
Anyone is welcome to contribute.
# You should fork this repo firstgit clone https://github.com/serut/meteor-coverage# I have a preference to always execute npm action# throw the integrated meteor npm (npm --v !== meteor npm --v)meteor npm install# Edit the app_folder key to match your app folder, don't forget the ending slashnano settings.coverage.json# Then run mocha watch testsmeteor npm run start
This package would not exist without the amazing work of:
- Contributors and testers for their help
- Xolv.io and their work on the originalmeteor-coverage package;
- All contributors ofistanbuljs project.
All of them were very helpful in the development of this package. Merci !
About
Server and client coverage for Meteor