Jest stop test suite after first fail

后端 未结 3 1398
清酒与你
清酒与你 2020-12-20 11:12

I am using Jest for testing.

What I want, is to stop executing the current test suite when a test in that test suite fails.

The option --bail is

相关标签:
3条回答
  • 2020-12-20 11:28

    hack the global.jasmine.currentEnv_.fail works for me.

          describe('Name of the group', () => {
    
            beforeAll(() => {
    
              global.__CASE_FAILED__= false
    
              global.jasmine.currentEnv_.fail = new Proxy(global.jasmine.currentEnv_.fail,{
                apply(target, that, args) {
                  global.__CASE__FAILED__ = true
                  // you also can record the failed info...
                  target.apply(that, args)
                  }
                }
              )
    
            })
    
            afterAll(async () => {
              if(global.__CASE_FAILED__) {
                console.log("there are some case failed");
                // TODO ...
              }
            })
    
            it("should xxxx", async () => {
              // TODO ...
              expect(false).toBe(true)
            })
          });
    
    0 讨论(0)
  • 2020-12-20 11:33

    I guess that other tests in that suite depend on all previous tests be successful. This is a bad practice in unit testing. Try using beforeEach and afterEach to decouple individual test cases within a suite, so that they don't rely on each other.

    0 讨论(0)
  • 2020-12-20 11:42

    I've made some kludge but it works for me.

    stopOnFirstFailed.js:

    /**
     * This is a realisation of "stop on first failed" with Jest
     * @type {{globalFailure: boolean}}
     */
    
    module.exports = {
        globalFailure: false
    };
    
    // Injects to jasmine.Spec for checking "status === failed"
    !function (OriginalSpec) {
        function PatchedSpec(attrs) {
            OriginalSpec.apply(this, arguments);
    
            if (attrs && attrs.id) {
                let status = undefined;
                Object.defineProperty(this.result, 'status', {
                    get: function () {
                        return status;
                    },
                    set: function (newValue) {
                        if (newValue === 'failed') module.exports.globalFailure = true;
                        status = newValue;
                    },
                })
            }
        }
    
        PatchedSpec.prototype = Object.create(OriginalSpec.prototype, {
            constructor: {
                value: PatchedSpec,
                enumerable: false,
                writable: true,
                configurable: true
            }
        });
    
        jasmine.Spec = PatchedSpec;
    }(jasmine.Spec);
    
    // Injects to "test" function for disabling that tasks
    test = ((testOrig) => function () {
        let fn = arguments[1];
    
        arguments[1] = () => {
            return module.exports.globalFailure ? new Promise((res, rej) => rej('globalFailure is TRUE')) : fn();
        };
    
        testOrig.apply(this, arguments);
    })(test);
    

    Imports that file before all tests (before first test(...)), for ex my index.test.js:

    require('./core/stopOnFirstFailed'); // before all tests
    
    test(..., ()=>...);
    ...
    

    That code marks all next tests failed with label globalFailure is TRUE when first error happens.

    If you want to exclude failing, for ex. some cleanup tests you can do like this:

    const stopOnFirstFailed = require('../core/stopOnFirstFailed');
    
    describe('some protected group', () => {
        beforeAll(() => {
            stopOnFirstFailed.globalFailure = false
        });
        test(..., ()=>...);
        ...
    

    It excludes whole group from failing.

    Tested with Node 8.9.1 and Jest 23.6.0

    0 讨论(0)
提交回复
热议问题