Watch and rerun Jest JS tests - npm

The Jest documentation suggests using npm test to execute tests.
Is there a way of watching your source and tests to rerun Jest tests automatically when relevant files have been changed?

Thanks to Erin Stanfill for pointing out, Jest already has support for automatically re-running. The better configuration for package.json would be
{
"scripts": {
"test": "jest"
}
}
To turn on the watch mode, just use
$ npm run test -- --watch
Or
$ yarn run test --watch

If you have npm test configured, you can just run npm test -- --watch.

As a complement suggestion you can add "--watchAll"
into your package.json file like this:
"scripts": {
"test": "jest --watchAll"
},
Each time you run npm test, the watch mode will be enable by default.
For more info npm CLI docs

Start you tests in watch mode.
jest --watch fileName.test.js
As per documentation
Run tests that match this spec name (match against the name in describe or test, basically).
jest -t name-of-spec
// or in watch mode
jest --watch -t="TestName"

This example shows how to use gulp to run your Jest tests using jest-cli, as well as a tdd gulp task to watch files and rerun Jest tests when a file changes:
var gulp = require('gulp');
var jest = require('jest-cli');
var jestConfig = {
rootDir: 'source'
};
gulp.task('test', function(done) {
jest.runCLI({ config : jestConfig }, ".", function() {
done();
});
});
gulp.task('tdd', function(done) {
gulp.watch([ jestConfig.rootDir + "/**/*.js" ], [ 'test' ]);
});
gulp.task('default', function() {
// place code for your default task here
});

install a couple of Grunt packages:
npm install grunt-contrib-watch grunt-exec --save-dev
make a Gruntfile.js with the following:
module.exports = function(grunt) {
grunt.initConfig({
exec: {
jest: 'node node_modules/jest-cli/bin/jest'
},
watch: {
files: ['**/*.js'],
tasks: ['exec:jest']
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-exec');
}
then simply run:
grunt watch

If you want to run a single file in watch mode:
yarn run test --watch FileName.test.jsx

I personally use the npm package jest-watch-typeahead.
You need to do 3 steps:
Install npm packege:
npm install --save-dev jest jest-watch-typeahead
Add to jest.config.js next code:
module.exports = {
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
};
Run Jest in watch mode
yarn jest --watch

Related

How to get code coverage report from jest-junit in React project

According to this article I'd like to get jest-junit code coverage report (Option 2 in article)
So, in my package.json I invoke jest like this: "test": "jest --config=jest.config.js",
jest.config.js includes these settings:
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
setupFiles: ['./jest.setup.js'],
collectCoverage: true,
coverageDirectory: 'src/testCoverage',
coverageReporters: [ "text"],
reporters: ["default",
["jest-junit", {usePathForSuiteName: true, outputDirectory: 'src/testCoverage'}]
],
testResultsProcessor: "jest-junit"
};
I did in this way because the written jest code in package.json doesn't work for me.
When I execute npm run test I get coverage data in src/testCoverage folder and junit.xml
Then I execute test stage in Jenkins pipeline:
stage('test') {
steps{
sh script:'''
#!/bin/bash
npm install -g yarn
yarn install
yarn add --dev jest-junit
npm run test
'''
}
post {
always {
junit 'src/testCoverage/junit.xml'
}
}
}
But I don't see junit coverage report in Jenkins, while the article says that
The line calling junit will publish the report that npm run test created
The only thing that I have - this is test result report of passed and failed tests.
Why I don't get junit coverage report in Jenkins? What should I do or change?
This happens because the junit.xml contains only the list of test cases executed and their duration.
In order to export the line coverage, you need some other coverage reported, for example, cobertura:
coverageReporters: ['text', 'cobertura'],
It will produce coverage/cobertura-coverage.xml file containing the coverage information. Now you can use junit.xml to report the list of tests and cobertura-coverage.xml to report the line coverage to your CICD system.

How add variable npm run build in package.json

I have 6 projects in an Angular workspace and I have to build each. Instead of write six lines in my package.json for each projet, for example :
"build_a":" npm run build a"
"buiild_b": "npm run build b"
I would like to create only one line like this :
"build_app": "npm run build name="aaa""
How I can do it ?
you could rely on environment variables in order to discover such names.
however it depends on which operating system you're using on how to define env variables.
"scripts":{
"build:a":"cross-env NAME=a npm run build",
"build:b":"cross-env NAME=b npm run build",
"build:c":"cross-env NAME=c npm run build",
"build":"browserify src/main.js -o build.js"
}
You would end up with a script section more or less like this.
Finally I found the solution using a node.js script: build-subproject.js.
const { exec } = require('child_process');
const args = process.argv.slice(2).join(' ');
console.log(`RUNNING build with args: ${args}`);
exec(
`ng build ${args} && cd dist/${args} && npm pack `,
(error, stdout) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.info(`stdout: ${stdout}`);
}
);
In package.json,
"build-subproject": "node ./build-subproject.js",
Then run , npm run build-subproject my-project-name

Use ng build watch & gulp watch on the same console

I would like to use ng build --watch & gulp watch:ng on the same console
Here's my task code
gulp.task('watch:ng', function () {
gulp.watch('ng/dist/ng/*', gulp.series('copy-ng'));
});
I want to copy/merge the scripts to another location when angular rebuild the project
I found a solution using npm-run-all
npm install npm-run-all --save-dev
"scripts": {
"build:watch": "ng build --deleteOutputPath=false --watch",
"gulp:watch": "gulp watch:ng",
"rebuild": "run-p build:watch gulp:watch",
}
npm run rebuild

Running Jest tests in Vue.js

Basically, the component isn't getting compiled, so I get an Unexpected token < error when it runs into <template>
I've run the following commands:
$ npm install --save-dev jest
$ npm install --save-dev vue-jest
$ npm install --save-dev vue-test-utils
and I've out the following in package.json:
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js",
"test": "jest"
},
...
"jest": {
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/vue"
],
"moduleFileExtensions": [
"js",
"vue"
],
"scriptPreprocessor": "index.js"
}
I created a __test__ folder in the root directory with a simple test:
const Vue = require("vue");
const VueTestUtils = require("vue-test-utils");
Vue.config.debug = true;
Vue.config.async = false;
Vue.use(VueTestUtils.install);
import Hello from '../src/components/Hello.vue'
const Constructor = Vue.extend(Hello)
const vm = new Constructor().$mount()
describe('initial test', () => {
it('should be 1', () => {
expect(1).toBe(1)
})
})
I recently got this error as well, and not quite sure how to configure Vue.js so it will run using the compiler-included build:
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
Been looking around for a while, so any help would be appreciated
You need to use a Jest transform to transform Jest Vue files. A Jest transformer is a synchronous function, that takes the file and path as input and outputs transpiled code.
I maintain a npm package that does it for you - vue-jest.
npm install --save-dev vue-jest
You need to add a jest section to your package.json (or in a seperate file with --config). Your config should look something like this:
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
"^.+\\.js$": "babel-jest",
".*\\.(vue)$": "vue-jest"
}
}
This tells jest to use jest-vue as a transform for files with a .vue extension.
You can see a working repo using Vue Test Utils here - https://github.com/eddyerburgh/vue-test-utils-jest-example

GULP: gulp is not defined

As shown in the screen shot below I am not able to run gulp to concat the JavaScript files. Its saying that gulp is not defined.
I have tried the following commands:
npm install -g gulp
npm install gulp
npm install gulp --save-dev
I have also set the environment variables as following:
C:\Users\<user>\AppData\Roaming\npm;C:\Python27;C:\Users\<user>\AppData\Roaming\npm\node_modules;C:\Users\<user>\AppData\Roaming\npm\node_modules\gulp;
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
//script paths
var jsFiles = 'scripts/*.js',
jsDest = 'dist/scripts';
gulp.task('scripts', function() {
return gulp.src(jsFiles)
.pipe(concat('scripts.js'))
.pipe(gulp.dest(jsDest));
});
you just need to install and require gulp locally, you probably only installed it globally
At the command line
cd <project-root> && npm install --save-dev gulp
In your gulpfile.js
var gulp = require('gulp');
this is a different dependency than the command line dependency (that you installed globally). More specifically, it is the same NPM package, but the command line program will execute code usually from a different entry point in the NPM package then what require('X') will return.
If we go to the package.json file in the Gulp project on Github, it will tell the whole story:
{
"name": "gulp",
"description": "The streaming build system",
"version": "3.9.1",
"homepage": "http://gulpjs.com",
"repository": "gulpjs/gulp",
"author": "Fractal <contact#wearefractal.com> (http://wearefractal.com/)",
"tags": [ ],
"files": [
// ...
],
"bin": {
"gulp": "./bin/gulp.js"
},
"man": "gulp.1",
"dependencies": {
// ...
},
"devDependencies": {
// ...
},
"scripts": {
"prepublish": "marked-man --name gulp docs/CLI.md > gulp.1",
"lint": "eslint . && jscs *.js bin/ lib/ test/",
"pretest": "npm run lint",
},
"engines": {
"node": ">= 0.9"
},
"license": "MIT"
}
so at the command line:
$ gulp default
will execute this:
"bin": {
"gulp": "./bin/gulp.js"
},
on the other hand, require('gulp') in your code will return the value of this:
https://github.com/gulpjs/gulp/blob/master/index.js
normally we see this in a package.json file as:
"main": "index.js"
but since this is the default, they just omitted it (which is dumb IMO, better to be explicit, but they aren't the first project I have seen take the lame shorthand route.).
Its occurs on Windows and usually one of the following fixes it:
If you didn't, run npm install gulp on the project folder, even if
you have gulp installed globally.
Normally, It isn't a problem on Windows, but it could be a issue with
the PATH. The package will try to get the PATH from the environment,
but you can override it by adding exec_args to your gulp settings.
For example, on Ubuntu:
"exec_args": {
"path": "/bin:/usr/bin:/usr/local/bin"
}
Hope It will be OK.
Source: https://github.com/NicoSantangelo/sublime-gulp/issues/12