Support running jasmine multiple times
Add support for running jasmine multiple times.
```js
const Jasmine = require('jasmine');
async function main() {
const jasmine = new Jasmine({ projectBaseDir: process.cwd() });
let specId = 'spec0';
jasmine.loadConfigFile('./spec/support/jasmine.json');
jasmine.env.configure({
specFilter(sp) {
return sp.id === specId;
},
autoCleanClosures: false
});
jasmine.exit = () => {};
await jasmine.execute();
specId = 'spec2';
await jasmine.execute();
}
main().catch((err) => {
console.error(err);
process.exitCode = 1;
});
```
With `jasmine.env.configure({ autoCleanClosures: false })` you disable Jasmine's feature to automatically clean closures (functions) during the test run. This is a requirement to be able to rerun.
When `execute` is called more than once, the `topSuite.reset` is called, which will reset the state for the next run as well as reset any child suites.
Add a function `exclude` to the `Suite` and `Spec` clases. This functions similar to `pend`, but will allow the "pending" state to persist over multiple runs. This is useful when `xit` is used.
Revert changes to jasmine.js
fix: make sure to call hooks during second run
Remove jsdoc from private apis
Fix elint issue
Add new line
This commit is contained in:
@@ -265,13 +265,13 @@ describe('Env', function() {
|
||||
});
|
||||
|
||||
describe('#xit', function() {
|
||||
it('calls spec.pend with "Temporarily disabled with xit"', function() {
|
||||
var pendSpy = jasmine.createSpy();
|
||||
it('calls spec.exclude with "Temporarily disabled with xit"', function() {
|
||||
var excludeSpy = jasmine.createSpy();
|
||||
spyOn(env, 'it').and.returnValue({
|
||||
pend: pendSpy
|
||||
exclude: excludeSpy
|
||||
});
|
||||
env.xit('foo', function() {});
|
||||
expect(pendSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
|
||||
expect(excludeSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
|
||||
});
|
||||
|
||||
it('throws an error when it receives a non-fn argument', function() {
|
||||
@@ -521,5 +521,18 @@ describe('Env', function() {
|
||||
jasmine.getEnv().requireNoPromises();
|
||||
expect(env.execute()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should reset the topSuite when run twice', function() {
|
||||
jasmine.getEnv().requirePromises();
|
||||
spyOn(env.topSuite(), 'reset');
|
||||
return env
|
||||
.execute() // 1
|
||||
.then(function() {
|
||||
return env.execute(); // 2
|
||||
})
|
||||
.then(function() {
|
||||
expect(env.topSuite().reset).toHaveBeenCalledOnceWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -142,4 +142,86 @@ describe('Suite', function() {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('attr.autoCleanClosures', function() {
|
||||
function arrangeSuite(attrs) {
|
||||
var suite = new jasmineUnderTest.Suite(attrs);
|
||||
suite.beforeAll(function() {});
|
||||
suite.beforeEach(function() {});
|
||||
suite.afterEach(function() {});
|
||||
suite.afterAll(function() {});
|
||||
return suite;
|
||||
}
|
||||
|
||||
it('should clean closures when "attr.autoCleanClosures" is missing', function() {
|
||||
var suite = arrangeSuite({});
|
||||
suite.cleanupBeforeAfter();
|
||||
expect(suite.beforeAllFns[0].fn).toBe(null);
|
||||
expect(suite.beforeFns[0].fn).toBe(null);
|
||||
expect(suite.afterFns[0].fn).toBe(null);
|
||||
expect(suite.afterAllFns[0].fn).toBe(null);
|
||||
});
|
||||
|
||||
it('should clean closures when "attr.autoCleanClosures" is true', function() {
|
||||
var suite = arrangeSuite({ autoCleanClosures: true });
|
||||
suite.cleanupBeforeAfter();
|
||||
expect(suite.beforeAllFns[0].fn).toBe(null);
|
||||
expect(suite.beforeFns[0].fn).toBe(null);
|
||||
expect(suite.afterFns[0].fn).toBe(null);
|
||||
expect(suite.afterAllFns[0].fn).toBe(null);
|
||||
});
|
||||
|
||||
it('should NOT clean closures when "attr.autoCleanClosures" is false', function() {
|
||||
var suite = arrangeSuite({ autoCleanClosures: false });
|
||||
suite.cleanupBeforeAfter();
|
||||
expect(suite.beforeAllFns[0].fn).not.toBe(null);
|
||||
expect(suite.beforeFns[0].fn).not.toBe(null);
|
||||
expect(suite.afterFns[0].fn).not.toBe(null);
|
||||
expect(suite.afterAllFns[0].fn).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#reset', function() {
|
||||
it('should reset the "pending" status', function() {
|
||||
var suite = new jasmineUnderTest.Suite({});
|
||||
suite.pend();
|
||||
suite.reset();
|
||||
expect(suite.getResult().status).toBe('passed');
|
||||
});
|
||||
|
||||
it('should not reset the "pending" status when the suite was excluded', function() {
|
||||
var suite = new jasmineUnderTest.Suite({});
|
||||
suite.exclude();
|
||||
suite.reset();
|
||||
expect(suite.getResult().status).toBe('pending');
|
||||
});
|
||||
|
||||
it('should also reset the children', function() {
|
||||
var suite = new jasmineUnderTest.Suite({});
|
||||
var child1 = jasmine.createSpyObj(['reset']);
|
||||
var child2 = jasmine.createSpyObj(['reset']);
|
||||
suite.addChild(child1);
|
||||
suite.addChild(child2);
|
||||
|
||||
suite.reset();
|
||||
|
||||
expect(child1.reset).toHaveBeenCalled();
|
||||
expect(child2.reset).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should reset the failedExpectations', function() {
|
||||
var suite = new jasmineUnderTest.Suite({
|
||||
expectationResultFactory: function(error) {
|
||||
return error;
|
||||
}
|
||||
});
|
||||
suite.onException(new Error());
|
||||
|
||||
suite.reset();
|
||||
|
||||
var result = suite.getResult();
|
||||
expect(result.status).toBe('passed');
|
||||
expect(result.failedExpectations).toHaveSize(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1026,4 +1026,209 @@ describe('spec running', function() {
|
||||
env.stopOnSpecFailure(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('run multiple times', function() {
|
||||
beforeEach(function() {
|
||||
env.configure({ autoCleanClosures: false, random: false });
|
||||
});
|
||||
|
||||
it('should be able to run multiple times', function() {
|
||||
var actions = [];
|
||||
|
||||
env.describe('Suite', function() {
|
||||
env.it('spec1', function() {
|
||||
actions.push('spec1');
|
||||
});
|
||||
env.describe('inner suite', function() {
|
||||
env.it('spec2', function() {
|
||||
actions.push('spec2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return env.execute().then(function() {
|
||||
expect(actions).toEqual(['spec1', 'spec2']);
|
||||
return env.execute().then(function() {
|
||||
expect(actions).toEqual(['spec1', 'spec2', 'spec1', 'spec2']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should reset results between runs', function() {
|
||||
var specResults = {};
|
||||
var suiteResults = {};
|
||||
var firstExecution = true;
|
||||
|
||||
env.addReporter({
|
||||
specDone: function(spec) {
|
||||
specResults[spec.description] = spec.status;
|
||||
},
|
||||
suiteDone: function(suite) {
|
||||
suiteResults[suite.description] = suite.status;
|
||||
},
|
||||
jasmineDone: function() {
|
||||
firstExecution = false;
|
||||
}
|
||||
});
|
||||
|
||||
env.describe('suite0', function() {
|
||||
env.it('spec1', function() {
|
||||
if (firstExecution) {
|
||||
env.expect(1).toBe(2);
|
||||
}
|
||||
});
|
||||
env.describe('suite1', function() {
|
||||
env.it('spec2', function() {
|
||||
if (firstExecution) {
|
||||
env.pending();
|
||||
}
|
||||
});
|
||||
env.xit('spec3', function() {}); // Always pending
|
||||
});
|
||||
env.describe('suite2', function() {
|
||||
env.it('spec4', function() {
|
||||
if (firstExecution) {
|
||||
throw new Error('spec 3 fails');
|
||||
}
|
||||
});
|
||||
});
|
||||
env.describe('suite3', function() {
|
||||
beforeEach(function() {
|
||||
throw new Error('suite 3 fails');
|
||||
});
|
||||
env.it('spec5', function() {});
|
||||
});
|
||||
env.xdescribe('suite4', function() {
|
||||
// Always pending
|
||||
env.it('spec6', function() {});
|
||||
});
|
||||
env.describe('suite5', function() {
|
||||
env.it('spec7');
|
||||
});
|
||||
});
|
||||
|
||||
return env.execute().then(function() {
|
||||
expect(specResults).toEqual({
|
||||
spec1: 'failed',
|
||||
spec2: 'pending',
|
||||
spec3: 'pending',
|
||||
spec4: 'failed',
|
||||
spec6: 'pending',
|
||||
spec7: 'pending'
|
||||
});
|
||||
expect(suiteResults).toEqual({
|
||||
suite0: 'passed',
|
||||
suite1: 'passed',
|
||||
suite2: 'passed',
|
||||
suite3: 'failed',
|
||||
suite4: 'pending',
|
||||
suite5: 'passed'
|
||||
});
|
||||
return env.execute().then(function() {
|
||||
expect(specResults).toEqual({
|
||||
spec1: 'passed',
|
||||
spec2: 'passed',
|
||||
spec3: 'pending',
|
||||
spec4: 'passed',
|
||||
spec6: 'pending',
|
||||
spec7: 'pending'
|
||||
});
|
||||
expect(suiteResults).toEqual({
|
||||
suite0: 'passed',
|
||||
suite1: 'passed',
|
||||
suite2: 'passed',
|
||||
suite3: 'passed',
|
||||
suite4: 'pending',
|
||||
suite5: 'passed'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should execute before and after hooks per run', function() {
|
||||
var timeline = [];
|
||||
var timelineFn = function(hookName) {
|
||||
return function() {
|
||||
timeline.push(hookName);
|
||||
};
|
||||
};
|
||||
var expectedTimeLine = [
|
||||
'beforeAll',
|
||||
'beforeEach',
|
||||
'spec1',
|
||||
'afterEach',
|
||||
'beforeEach',
|
||||
'spec2',
|
||||
'afterEach',
|
||||
'afterAll'
|
||||
];
|
||||
|
||||
env.describe('suite0', function() {
|
||||
env.beforeAll(timelineFn('beforeAll'));
|
||||
env.beforeEach(timelineFn('beforeEach'));
|
||||
env.afterEach(timelineFn('afterEach'));
|
||||
env.afterAll(timelineFn('afterAll'));
|
||||
env.it('spec1', timelineFn('spec1'));
|
||||
env.it('spec2', timelineFn('spec2'));
|
||||
});
|
||||
return env.execute().then(function() {
|
||||
expect(timeline).toEqual(expectedTimeLine);
|
||||
timeline = [];
|
||||
return env.execute().then(function() {
|
||||
expect(timeline).toEqual(expectedTimeLine);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to filter out different tests in subsequent runs', function() {
|
||||
var specResults = {};
|
||||
var focussedSpec = 'spec1';
|
||||
|
||||
env.configure({
|
||||
specFilter: function(spec) {
|
||||
return spec.description === focussedSpec;
|
||||
}
|
||||
});
|
||||
|
||||
env.addReporter({
|
||||
specDone: function(spec) {
|
||||
specResults[spec.description] = spec.status;
|
||||
}
|
||||
});
|
||||
|
||||
env.describe('suite0', function() {
|
||||
env.it('spec1', function() {});
|
||||
env.it('spec2', function() {});
|
||||
env.it('spec3', function() {});
|
||||
});
|
||||
|
||||
return env
|
||||
.execute()
|
||||
.then(function() {
|
||||
expect(specResults).toEqual({
|
||||
spec1: 'passed',
|
||||
spec2: 'excluded',
|
||||
spec3: 'excluded'
|
||||
});
|
||||
focussedSpec = 'spec2';
|
||||
return env.execute();
|
||||
})
|
||||
.then(function() {
|
||||
expect(specResults).toEqual({
|
||||
spec1: 'excluded',
|
||||
spec2: 'passed',
|
||||
spec3: 'excluded'
|
||||
});
|
||||
focussedSpec = 'spec3';
|
||||
return env.execute();
|
||||
})
|
||||
.then(function() {
|
||||
expect(specResults).toEqual({
|
||||
spec1: 'excluded',
|
||||
spec2: 'excluded',
|
||||
spec3: 'passed'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user