Disable Jasmine's fdescribe() and fit() based on environment
Asked Answered
U

6

24

fdescribe() and fit() are great for reducing noise when you're working on a subset of tests. I sometimes forget to change them back to describe()/it() before merging my branch into master. (It's okay to have them in separate branch while working on code - i.e. a pre-commit check wouldn't work for me.)

My CI environment is Codeship. Is there a solution to this problem that would fail the tests in Codeship if it came across any focused methods?

Using something like no-focused-tests would be okay. Any idea how to enable this rule as an error in Codeship and disable it locally?

Uppity answered 8/7, 2015 at 21:49 Comment(3)
no-focused-tests saved me so often before :). How about something like a pre-merge hook? (#19103214)Charlyncharm
Unfortunately the merge takes place on GitHub so unless it can be triggered as rule on the GitHub servers I don't think that would work. Thanks for the idea though! +1Uppity
I run jshint as part of my build it catches this sort of thing.Lucio
M
4

Using something like no-focused-tests would be okay. Any idea how to enable this rule as an error in Codeship and disable it locally?

You could use a combination of environment variables and redefining the fdescribe/fit global functions:

  1. npm i --save cross-env

  2. package.json:

    "scripts": {
      "test": "jasmine",
      "test-safe": "cross-env FOCUSED_TESTS=off jasmine"
    },
    
  3. disableFocusedTestsIfNecessary.js (included after jasmine defines its globals):

    if (process.env.FOCUSED_TESTS === "off") {
      console.log("Focused tests must be off");
      global.fdescribe = global.fit = function() {
        throw new Error("fdescribe and fit are disabled in this environment");
      };
    }
    else {
      console.log("Focused tests enabled");
    }
    
  4. Tell codeship to run npm run test-safe instead of npm run test

Midwife answered 27/4, 2016 at 6:32 Comment(0)
C
7

Edit 14.11.19:

To make things easier I created an installable package you can find at https://www.npmjs.com/package/tslint-jasmine

Original post:

If you're using TSLint and (like me) found that all the defocus and tslint-jasmine-noSkipOrFocus checkers are not working for you, I created a Gist for that: https://gist.github.com/djungowski/7d9126bb79970446b4ffeb5656c6bf1f

How to use:

  1. Save Gist in a a folder called TSLint/Rules as noJasmineFocusRule.js
  2. Add the Rules folder to your TSLint config: rulesDirectory: 'TSLint/Rules'
  3. Enable option with "no-jasmine-focus": true
Chough answered 18/7, 2018 at 13:47 Comment(2)
That's an elegant way of doing it. Thank's.Chanterelle
This works great with husky "pre-push" hook to prevent an fdescribe or fit from limiting your deployment pipeline automated tests. e.g. package.json "husky": { "hooks": { "pre-push": "ng lint && ng test --watch=false --browsers=ChromeHeadless" } }Hyperbole
M
4

Using something like no-focused-tests would be okay. Any idea how to enable this rule as an error in Codeship and disable it locally?

You could use a combination of environment variables and redefining the fdescribe/fit global functions:

  1. npm i --save cross-env

  2. package.json:

    "scripts": {
      "test": "jasmine",
      "test-safe": "cross-env FOCUSED_TESTS=off jasmine"
    },
    
  3. disableFocusedTestsIfNecessary.js (included after jasmine defines its globals):

    if (process.env.FOCUSED_TESTS === "off") {
      console.log("Focused tests must be off");
      global.fdescribe = global.fit = function() {
        throw new Error("fdescribe and fit are disabled in this environment");
      };
    }
    else {
      console.log("Focused tests enabled");
    }
    
  4. Tell codeship to run npm run test-safe instead of npm run test

Midwife answered 27/4, 2016 at 6:32 Comment(0)
A
3

For those interested, if you are using jasmine and eslint, you can use this plugin to ensure no focused tests: https://github.com/tlvince/eslint-plugin-jasmine.

  1. First install eslint globally npm install -g eslint.
  2. Then install the eslint-plugin-jasmine library npm install --save-dev eslint-plugin-jasmine.
  3. Create a .eslintrc file which would look something like this:

    {
      "rules": {
        "semi": 2
      },
      "plugins": ["jasmine"],
      "env": {
        "jasmine": true
      },
      "extends": "plugin:jasmine/recommended",
    }
    
  4. Then you are ready to run the linter eslint -c ./.eslintrc app.js

Aegyptus answered 6/9, 2016 at 21:11 Comment(0)
U
1

I'm late to the party.

I had a similar issue with my builds. We don't use ts / eslint so I just wrote a quick script to throw an error that would fail my dockerfile / build.

Here it is.

#!/bin/sh
files=$(find "./.." -type f -name '*.spec*')
errored=false

echo "Checking for focused tests"

for file in $files
do
    if grep -E "fdescribe|fit" $file; [ $? -eq 0 ]; then
        echo "-Focusing a test in the file $file"
        errored=true
    fi
done

if $errored; then
    echo "Some tests were focused"
    exit 1
else
    echo "No tests were focused"
fi
Unplaced answered 17/1, 2020 at 14:56 Comment(0)
E
0

This isn't the best solution. But it works for my needs.

To setup:

npm i lodash
npm i minimist

I call this from my gulp tasks:

node .\\build\\throwIfFocusedTest.js e2e/
node .\\build\\throwIfFocusedTest.js src/

throwIfFocusedTest.js:

const walkSync = require('./walkSync').default;
const _ = require('lodash');
const argv = require('minimist')(process.argv);
const fs = require('fs');

if (argv._.length !== 3) {
    throw 'expecting 1 command line argument';
}

const directory = argv._[2];

const files = walkSync(directory);
const scriptFiles = _.filter(files, f => f.endsWith('.js') || f.endsWith('.ts'));

const invalidStrings = [
    'fdescribe',
    'fit',
];

_.each(scriptFiles, fileName => {
    const contents = fs.readFileSync(fileName, 'utf8');
    invalidStrings.forEach(is => {
        if (contents.includes(is)) {
            console.error(`throwIfFocusedTest: ${directory}: File contains ${is}: ${fileName}`);
            process.exit(1);
        }
    });
});
console.log(`throwIfFocusedTest: ${directory}: No files contain: ${invalidStrings.join(', ')}`);

walkSync.js:

/**
 * From: https://gist.github.com/kethinov/6658166 
 */
exports.default = function walkSync(dir, filelist) {
    var fs = fs || require('fs'),
        files = fs.readdirSync(dir);
    filelist = filelist || [];
    files.forEach(function (file) {
        var path = dir + file;
        if (fs.statSync(dir + file).isDirectory()) {
            filelist = walkSync(dir + file + '/', filelist);
        }
        else {
            filelist.push(path);
        }
    });
    return filelist;
};
Expressly answered 7/9, 2018 at 0:28 Comment(0)
W
0

If you're willing to fail on when tests are marked for focus or skip (fit + xit), there's a relatively new Karma feature that solves the problem with no plugins. Karma now supports a failOnSkippedTests config file / CLI option, which, per the docs, causes "failure on tests deliberately disabled, eg fit() or xit()".

Washrag answered 4/11, 2020 at 16:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.