Added the ability to associate trace information with failing specs
This is meant to aid in debugging failures, particularly intermittent failures, in cases where interactive debugging or console.log aren't suitable.
This commit is contained in:
@@ -228,7 +228,8 @@ describe('Spec', function() {
|
||||
deprecationWarnings: [],
|
||||
pendingReason: '',
|
||||
duration: jasmine.any(Number),
|
||||
properties: null
|
||||
properties: null,
|
||||
trace: null
|
||||
},
|
||||
'things'
|
||||
);
|
||||
@@ -516,4 +517,110 @@ describe('Spec', function() {
|
||||
args.cleanupFns[0].fn();
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
describe('#trace', function() {
|
||||
it('adds the messages to the result', function() {
|
||||
var timer = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: {
|
||||
fn: function() {}
|
||||
},
|
||||
queueRunnerFactory: function() {},
|
||||
timer: timer
|
||||
}),
|
||||
t1 = 123,
|
||||
t2 = 456;
|
||||
|
||||
spec.execute();
|
||||
expect(spec.result.trace).toBeNull();
|
||||
timer.elapsed.and.returnValue(t1);
|
||||
spec.trace('msg 1');
|
||||
expect(spec.result.trace).toEqual([{ message: 'msg 1', timestamp: t1 }]);
|
||||
timer.elapsed.and.returnValue(t2);
|
||||
spec.trace('msg 2');
|
||||
expect(spec.result.trace).toEqual([
|
||||
{ message: 'msg 1', timestamp: t1 },
|
||||
{ message: 'msg 2', timestamp: t2 }
|
||||
]);
|
||||
});
|
||||
|
||||
describe('When the spec passes', function() {
|
||||
it('omits the messages from the reported result', function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: {
|
||||
fn: function() {}
|
||||
},
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: function(config) {
|
||||
spec.trace('msg');
|
||||
config.cleanupFns.forEach(function(fn) {
|
||||
fn.fn();
|
||||
});
|
||||
config.onComplete(false);
|
||||
}
|
||||
});
|
||||
|
||||
spec.execute(function() {});
|
||||
expect(resultCallback).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({ trace: null }),
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it('removes the messages to save memory', function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: {
|
||||
fn: function() {}
|
||||
},
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: function(config) {
|
||||
spec.trace('msg');
|
||||
config.cleanupFns.forEach(function(fn) {
|
||||
fn.fn();
|
||||
});
|
||||
config.onComplete(false);
|
||||
}
|
||||
});
|
||||
|
||||
spec.execute(function() {});
|
||||
expect(resultCallback).toHaveBeenCalled();
|
||||
expect(spec.result.trace).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the spec fails', function() {
|
||||
it('includes the messages in the reported result', function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
timer = jasmine.createSpyObj('timer', ['start', 'elapsed']),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: {
|
||||
fn: function() {}
|
||||
},
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: function(config) {
|
||||
spec.trace('msg');
|
||||
spec.onException(new Error('nope'));
|
||||
config.cleanupFns.forEach(function(fn) {
|
||||
fn.fn();
|
||||
});
|
||||
config.onComplete(true);
|
||||
},
|
||||
timer: timer
|
||||
}),
|
||||
timestamp = 12345;
|
||||
|
||||
timer.elapsed.and.returnValue(timestamp);
|
||||
|
||||
spec.execute(function() {});
|
||||
expect(resultCallback).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
trace: [{ message: 'msg', timestamp: timestamp }]
|
||||
}),
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -186,4 +186,12 @@ describe('base helpers', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('trace', function() {
|
||||
it("forwards to the current env's trace function", function() {
|
||||
spyOn(jasmineUnderTest.getEnv(), 'trace');
|
||||
jasmineUnderTest.trace('a message');
|
||||
expect(jasmineUnderTest.getEnv().trace).toHaveBeenCalledWith('a message');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3234,4 +3234,87 @@ describe('Env integration', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sends traces to the reporter when the spec fails', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['specDone']),
|
||||
startTime,
|
||||
endTime;
|
||||
|
||||
env.addReporter(reporter);
|
||||
env.configure({ random: false });
|
||||
|
||||
env.it('fails', function() {
|
||||
startTime = new Date().getTime();
|
||||
env.trace('message 1');
|
||||
env.trace('message 2');
|
||||
env.expect(1).toBe(2);
|
||||
endTime = new Date().getTime();
|
||||
});
|
||||
|
||||
env.it('passes', function() {
|
||||
env.trace('message that should not be reported');
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
function numberInRange(min, max) {
|
||||
return {
|
||||
asymmetricMatch: function(compareTo) {
|
||||
return compareTo >= min && compareTo <= max;
|
||||
},
|
||||
jasmineToString: function(pp) {
|
||||
return '<number from ' + min + ' to ' + max + ' inclusive>';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var duration;
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(2);
|
||||
duration = reporter.specDone.calls.argsFor(0)[0].duration;
|
||||
expect(reporter.specDone.calls.argsFor(0)[0]).toEqual(
|
||||
jasmine.objectContaining({
|
||||
trace: [
|
||||
{
|
||||
timestamp: numberInRange(0, duration),
|
||||
message: 'message 1'
|
||||
},
|
||||
{
|
||||
timestamp: numberInRange(0, duration),
|
||||
message: 'message 2'
|
||||
}
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(reporter.specDone.calls.argsFor(1)[0].trace).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('reports an error when trace is used when a spec is not running', function(done) {
|
||||
var reporter = jasmine.createSpyObj('reporter', ['suiteDone']);
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.beforeAll(function() {
|
||||
env.trace('a message');
|
||||
});
|
||||
|
||||
env.it('a spec', function() {});
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
env.execute(null, function() {
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
failedExpectations: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringContaining(
|
||||
"'trace' was called when there was no current spec"
|
||||
)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user