-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get currently executed test name in beforeEach #611
Comments
You can try this: describe('TestCase', function() {
var mySpec = it('should return the spec', function() {
console.log(mySpec);
expect(mySpec.getFullName()).toEqual('TestCase should return the spec');
});
}); |
Nice to see that there is a way to access the spec created by describe('specs', function() {
beforeEach(function() {
// get current spec
// append <h1>{{ currentSpec.getFullName() }}</h1> before spec runs
});
it('should append elements to body', function() { /* */ });
it('should append some other elements to body', function() { /* */ });
}); Any ideas? |
I don't think that there is a way to get the current spec in the beforeEach callback. |
It would be good testing practice to inject a DOM selector into your drawing function. I could imagine a test helper that makes unique DOM ids and you can call that helper in each spec. You shouldn't need to get ahold of the spec to do this. As for captioning, you could build a reporter - and add it in I think this helper/reporter combo could be a generally useful add-on. Good idea. ps: there may be more suggestions on the mailing list: [email protected] |
Thanks for the suggestions @infews. As it turns out a custom reporter can easily be abused as a test environment 😃. var JsApiReporter = jasmine.JsApiReporter;
function Env(options) {
JsApiReporter.call(this, options);
this.specStarted = function(result) {
this.currentSpec = result;
var label = document.createElement('div');
label.innerHTML = result.fullName;
document.body.appendChild(label);
};
this.specDone = function(result) {
this.currentSpec = null;
};
} Need to register it with jasmine, too: var environment = new Env({
timer: new jasmine.Timer()
});
jasmine.getEnv().addReporter(environment); The reporter will be notified by Jasmine and print a caption before each executed test case. |
It looks like you're using Jasmine 1.3? Is that right? With 2.0 the interface has changed a little, making currentSpec harder to get (on purpose). So caveat emptor. Can we close this issue? |
The above example is running fine against Jasmine 2.0. |
Just in case anyone is interested: I created the library jasmine-test-container-support that provides test containers + captioning for Jasmine 2.0. |
I find I'm struggling without this feature as well. My use case for needing the spec name is a bit different than @nikku's. In my case, I have about 100 it() tests which all share the same 250 lines of code. So the beforeEach() statement makes total sense. However, I have 2 tests (in those 100) where I need an additional extra variable configured in my 250 lines of beforeEach code. Sure. I can just have those 2 tests duplicate the 250 lines of code and not use the beforeEach(), but that's a lot of code duplication, and it also requires me to move them out into a separate describe() block -- putting those tests out of context. It would be fantastic if each it() test could pass a configuration variable into its beforeEach() call somehow. Any suggestions? |
👍 such failure not to have this feature |
+1 It's useful for logging and debugging to be able to get hold of the current full name somehow - it would be great to see this feature come back. |
+1 |
+1 for @juliemr's use case. |
+1@juliemr's use case is reason enough to restore the feature |
+1 |
+1 I wanted this just so I could see which of my 700 tests was the slow one... there's probably some other idiomatic way to do that, but it would have been nice to just add timings to beforeEach and afterEach and console.log out the slow ones... |
I got my adapter working by doing this: let beforeAllMock = jasmine.Suite.prototype.beforeAll
jasmine.Suite.prototype.beforeAll = function (...args) {
self.lastSpec = this.result
beforeAllMock.apply(this, args)
}
let executeMock = jasmine.Spec.prototype.execute
jasmine.Spec.prototype.execute = function (...args) {
self.lastTest = this.result
executeMock.apply(this, args)
} |
+1 |
+1. A link to the justification for making 'spec' harder to get to would be nice. I can see wanting to prevent adding tests while executing tests and all that... but seriously: I just want the name of the test that's running. A stats object would be spiffy too. But making 'spec' harder to get without replacing it with something seems rather cruel. |
Definitely a +1 on this. I have a situation where I have a test that passes in isolation but is failing when the entire suite is executed. I suspect this is an issue with ng-mock and want to add logging in a bunch of places based on the test name, but I'm currently unable to do this. |
+1 |
+1 |
+1 |
So you can do this by abusing reporters as @nikku suggests, but it needn't be as complex as that. The simplest solution I could come up with was (tested on 2.5.2): jasmine.getEnv().addReporter({
specStarted: function(result) {
console.log(result.fullName);
}
}); You only need to add the reporter once and it will work for all test suites/cases in all files. |
Most of the reasons I'm seeing in this thread for wanting to get the spec name are probably best solved with a custom reporter that can do timing, or a different style of report, or screenshots based on pass/fail etc. In general, we don't think you should have Hope this helps. Thanks for using Jasmine! |
@slackersoft : I still don't see the reason to be so concerned with hiding this information and I really would like to understand the point of doing so. Regardless. One of my use cases is simple. I want to use the name of the test in data that gets written out as part of the test, so that if something fails and the data isn't flushed correctly I know which test created what. Is it super hard to write the name of the test out twice? No. Does it feel really stupid? Yes, yes it does. I just want to use the name of the test within the body of the test. That may include using it in beforeEach to do some prep work for the subset of tests within the set. Obviously others agree. I doubt anyone considers knowing the currently running test name a big deal. I think you mostly have power users hitting this ticket, so, at a guess, not a huge number really want to do conditional branching based on test name. Sure, some do. Maybe for good reason. Probably for bad ones. But we can't save everybody from themselves. Sure, fine, there are other priorities. But if this isn't happening because of some desire to babysit the people who will abuse the information... it isn't going to work. Those who would abuse it are just going to abuse something even more complex, making it even harder to understand when someone has to un-cruft their workaround. Meanwhile, my goals are slightly more difficult to achieve. And that's really quite annoying. |
@slackersoft : We've actually ended up moving away from Jasmine to Mocha (and related libs) much to my dismay. We wanted I love the "batteries-included" nature of Jasmine over the other test frameworks, but there's often so little to differentiate picking one framework over the other that the small niggles like this can make all the difference. Sadly for us, this was one annoyance too many. |
I'm also interested in getting the name of the current running test for this specific reason: I am using Approvals JS and trying to capture the test name so the approval can be written to a file. This is not for every test, but only for tests which use this external library. Moreover, no reporting should occur if the test passes normally, but if something fails I want to ensure approvals actually reports correctly and interacts with the correct file. These requirements are actually not mine, but rather they are the requirement of the external dependency, which no longer works as designed and has ceased support for Jasmine and only supports Mocha. Currently this is actually causing my team a significant amount of pain since they are testing Angular code which recommends Jasmine, but they have to duplicate magic strings all over the place rather than naming the tests and relying on an API which provides the name to external libraries. For now I am going to have to set up a reporter that monkey patches the Jasmine library, which is tremendously disappointing. |
Seriously annoying issue. How hard could it be to e.g. pass this info in the this object, for example? |
I've created a patch library to do this. Check https://github.com/Quramy/jasmine-spec-name-patch out 😄 require('jasmine-spec-name-patch');
describe('My awesome function', function() {
beforeEach(function() {
console.log(this.fullName); // -> My awesome function should returns ...
});
// or
beforeEach((done, { fullName }) => {
console.log(fullName); // -> My awesome function should returns ...
done();
});
it('should returns...', function() { /* test code */ });
afterEach(function() {
console.log(this.fullName); // -> My awesome function should returns ...
});
// or
afterEach((done, { fullName }) => {
console.log(fullName); // -> My awesome function should returns ...
done();
});
}); |
@Quramy It doesn't work for me :( |
My use case for this issue is -
Why can I not access the spec name in I can't do this with a reporter without building all of my browser setup/teardown into the reporter, instead of the individual specs. If I do that, then I would have to pass the Browser instance between the reporter and the specs, which seems dirty since I can't pass context on The only workaround I have managed to use successfully is from @stoeffel, but it's clumsy: describe("contrived example", function(){
beforeEach(function(){
browser.create();
});
let mySpec = it("tests a feature", function(){
this.specName = mySpec.getFullName();
browser.goto("https://google.com");
expect(browser.title).toContain("Google");
});
afterEach(function(){
browser.screenshot(this.specName);
browser.close();
});
}); It feels weird to need to do the |
I did this instead:
usage:
Works in jest as well. |
I needed the test name in my describe("tests", () => {
let currentTest;
afterEach(() => {
const {
result: { fullName }
} = currentTest;
console.log(fullName); // "test 1", then "test 2"
});
currentTest = it("test 1", () => {
// ...
});
currentTest = it("test 2", () => {
// ...
});
}); |
@monkpit Any clue ? |
@abhilash04 since 2.0, Jasmine supplies a fresh empty object to each spec. This object is setup as |
Here's my (super hacky) solution: https://github.com/Jezorko/smack-my-jasmine-up |
After lots of writing new tests and wishing for this feature, I found a great way to fix this (at least, for my purposes)... Put this somewhere that will run before your tests - for me this was in protractor's jasmine.getEnv().addReporter({
specStarted: result => (jasmine.currentTest = result),
specDone: result => (jasmine.currentTest = result),
}); If you're using typescript you might have to add in a The contents of type Result {
id: 'spec0',
description: 'This string is the title of your `it` block',
fullName: 'This is the full title derived from nested `describe` and `it`s that you have created',
failedExpectations: [], // possibly has contents during `afterEach` / `afterAll`
passedExpectations: [], // possibly has contents during `afterEach` / `afterAll`
pendingReason: '',
testPath: '/path/to/the/spec/file/of/this/test.js'
} And now this will work: describe('My test', () => {
beforeEach(() => {
console.log(jasmine.currentTest.fullName);
// logs: 'My test has currentTest'
});
it('has currentTest', () => {
console.log(jasmine.currentTest.description);
// logs: 'has currentTest'
fail('Failure goes here');
});
afterEach(() => {
if (jasmine.currentTest.failedExpectations.length) {
console.log('This test failed:', jasmine.currentTest.description);
// logs: 'This test failed: My test has currentTest'
}
});
}); |
TLDR; Is there a way to get the currently executed test case (its description derived from
describe
/it
) in abeforeEach
block?What for?
Assuming I have a test runner that performs some sort of visual job on the screen (e.g. drawing SVG elements).
I provide each test case with a container to draw on and want the result to be inspectable by a user. In addition, I would like to add a caption to each of the tests, so that the user can easier keep track of which drawing result belongs to which test execution.
The text was updated successfully, but these errors were encountered: