I have a code some thing like this
describe("Main test", function(){
var temp = [];
it("actual test1", function(){
...
});
describe("sub main test1", function(){
it("test", function(){
temp.push(1);
});
});
describe("sub main test2", function(){
for(var i=0;i<temp;i++){
it("test" + temp, function(){
...
});
}
});
});
When the test starts, the for loop is executing, at that time the temp is empty. In this case the it block inside the for loop is not executing. How to execute for loop after the sub main test1 describe block. In this way temp has some data.
You should do initialization stuff in the beforeEach or beforeAll blocks (see reference).
Therefore, the following code should do the trick.
describe('Main test', function () {
var temp;
beforeEach(function () {
temp = [];
temp.push(1);
});
...
});
Note:
Based on your comment, what you are trying to achieve is a bit wrong, as the it blocks should not perform any initialization for further it blocks.
Every it block should be able to run individually.
Related
I have seen lots of questions about this but all of the fixes simply does not work with my code.
What am I doing wrong? My beforeEach doesnt get executed.
This is the unit test code:
var assert = require('assert');
var environmentConfiguration;
var fs = require('fs');
var expect = require('chai').expect;
describe('environmentConfiguration', function() {
beforeEach('some description', function() {
console.log("hello")
});
describe('#configFile null configFile', function() {
var result = environmentConfiguration.load(null)
var expectedConfiguration = JSON.parse(fs.readFileSync('./ISPRemotingService.config.json'));
it('should return current ISP environment configuration', function() {
assert(result, expectedConfiguration);
});
});
});
I have also applied simpler versions from Mocha's documentation and beforeEach doesn't gets executed.
Another exception was blocking the unit tests to even reach there. My bad
I am writing some BDD unit tests for the first time and I'd like to eliminate some repeated code for one of my test suites. The following async unit test code works fine, but I'd like to set up the Promise in the beforeEach() block somehow, since I will be writing many more it() tests, and each one will need to run the db.find(...) call. Thanks
describe('DB retrieve row', function() {
beforeEach(function () {
// i'd like to set up the promise in this block
});
it("returns a least one result", function () {
function success(orderData) {
// keep the following line in this it() block
expect(orderData.length).to.be.ok;
}
function fail(error) {
new Error(error);
}
return db.find('P9GV8CIL').then(success).catch(fail);
});
});
Simply something like this would work
describe('DB retrieve row', function() {
var promise;
beforeEach(function () {
promise = db.find('P9GV8CIL')
});
it("returns a least one result", function () {
function success(orderData) {
// keep the following line in this it() block
expect(orderData.length).to.be.ok;
}
function fail(error) {
new Error(error);
}
return promise.then(success).catch(fail);
});
});
Here are 2 samples of the same test. The only difference is that first one uses a promise in beforeAll block to assign a value to the variable while the second one assigns the value directly.
I raised a similar question Running spec after promise has been resolved with one of the comments pointing to this issue https://github.com/jasmine/jasmine/issues/412 which says that this is not supported in Jasmine. Has somebody figured out any workaround?
This fails with TypeError: Cannot read property 'forEach' of undefined
describe('Async car test', function () {
var cars;
beforeAll(function (done) {
// getCars() is a promise which resolves to ['audi', 'bmw']
getCars().then(function (data) {
cars = data;
console.log(cars) // ['audi', 'bmw']
done();
});
});
cars.forEach(function (car) {
it('car ' + car, function () {
expect(car).toBe(car);
});
});
});
This works fine
describe('Car test', function () {
var cars = ['audi', 'bmw'];
cars.forEach(function (car) {
it('car ' + car, function () {
expect(car).toBe(car);
});
});
});
Posting it as an answer, because I can't see things properly in comments.
I'm actually generating tests in my spec as well, and I'm using https://www.npmjs.com/package/jasmine-data-provider , I think you probably cannot generate it directly from resolved promise. And wrapping in another it doesn't work for you. This should work:
var using = require('jasmine-data-provider');
using(cars.forEach, function (car) {
it(car + ' should be' + car, function () {
expect(car).toBe(car);
});
});
This is not an issue with jasmine, it is an issue with your code.
beforeAll does not block subsequent code below the statement. it blocks code that is defined in it('should ...', (done)=>{...});
it('should have cars', (done) => {
cars.forEach(function (car) {
expect(car).toBe(car);
});
});
Since Jasmine does not support adding tests at runtime, the trick is to request the asynchronous data before starting Jasmine, and then using the retrieved data during runtime instead. This can be achieved with a singleton and programmatically starting Jasmine.
See here for a working example.
// car-collection.js
class CarCollection {
static load() {
return this.request()
then((data) => this.cars = data);
}
static request() {
// in practice this function would do something cooler
return Promise.resolve(['audi', 'bmw']);
}
}
modules.export = CarCollection;
Since CarCollection has methods that are static they will be shared across imports and this.cars will persist.
// launcher.js
const Jasmine = require('jasmine');
const CarCollection = require('./car-collection');
CarCollection.load()
.then(() => {
console.log(`car count is ${CarCollection.cars.length}`); // prints: car count is 2
const jasmine = new Jasmine();
jasmine.loadConfigFile(...); // path to jasmine.json
jasmine.execute();
});
An important step here is configure jasmine to know where to look for the test files. Either by loading a config or passing specifics into the execute function.
// car.spec.js
const CarCollection = require('./car-collection');
describe('test', function () {
CarCollection.cars.forEach((car) => {
it('test' + car, () => {
expect(car).toBe(car);
});
});
});
Now run node ./launcher.js and the tests should run.
Can I create a nested it in Protractor/Jasmine.
it("outer it", function () {
it("inner it", function () {
expect(1).toBe(1);
});
});
I am trying to execute it test cases inside a loop, and in every iteration I want to run a test, for example:
it("outer it", function () {
for(var i=0;i<10;i++){
it("inner it", function () {
expect(1).toBe(1);
});
}
});
The reason I want to do it is that I want to initialize an array and then in a dynamically way to loop trough all the element and run a number of "it", for example:
describe ("[Components]", function() {
var grid = new Grid();
it("Initialize the grid for the history window", function () {
grid.init();
});
for(var i=0;i<grid.length;i++){
it("test 1", function () {
expect(1).toBe(1);
});
}
});
The grid.length is equal to 0 when the for loop execute, I want the for loop execute after the initialize "it".
Answering to your question, no you cannot nest it's one inside other. Though Jasmine framework doesn't throw any error, the code inside a nested it doesn't execute. Also, I don't see any use of nesting it's as they are specs or functions that run on their own to complete a particular test step. It also gives an overview of the function that is being executed currently. If you are trying to run something in a loop, you can create another function and then call it inside the for loop, something like this -
it("outer it", function () {
var newFunction = function(){
expect(1).toBe(1);
};
for(var i=0;i<10;i++){
newFunction();
};
});
Hope this helps. More on it's can be found here - Jasmine Framework - it's
As mentioned earlier - no, you can not place it inside of another it block, BUT you could place a whole describe block inside another one
You also have an ability to run it blocks inside of for loops, OR for example make it block conditional.
You can find a real example of a code below (I've added for loop just for demonstration purposes)
describe("E2E: Environment configuration test", function () {
beforeAll(function () {
logIn();
});
afterAll(function () {
logOut();
});
describe("Members page configuration test", function() {
for (let i=0; i<3; i++) {
it("Members page - columns", function () {
//code that verifies that all columns of the page are presented
});
}
it( "Members page - filters", function() {
//code that verifies that all filters of the UI are presented as expected
});
it( "Members page - eligibility feature", function() {
//code that verifies that if the feature is set to true then additional column must be displayed
});
});
describe("Providers page configuration test", function() {
// use of conditional it blocks
// if feature is turned on run one set it blocks
// otherwise execute another set of it blocks
if (envConfig.providerFeature) {
it( "Organizations tab configuration test", function() {
//code that verifies that all elements of the current tab are displayed according to configurations of all features of the application
});
it( "Practitioners tab configuration test", function() {});
//code that verifies that all elements of the current tab are displayed according to configurations of all features of the application
} else {
it( "Providers page - verification of the page being disabled", function() {
//code that verifies that both tabs are not present in the UI
console.log('Providers feature is set to FALSE for the environment by default configuration, the test case will be skipped');
});
}
});
it( "Users page configuration test", function() {
//code that verifies that all elements of the current page are displayed according to configurations of all features of the application
});
it( "Reports page configuration test", function() {
if (!envConfig.disabledReportsFeature) {
//code that verifies that all elements of the current page are displayed according to configurations of all features of the application
} else {
console.log('Reports DISABLED_REPORTS_FEATURE is set to TRUE for the environment by default configuration, the test case will be skipped');
}
});
});
The console output in this case will look well organized
P.S. Additionally I will attach an image of clean console
Is there a way to NOT execute beforeEach function only for certain tests ('it' blocks). Lets say I have 10 it blocks, I do not want beforeEach to be executed for two of the blocks. Is it possible?
You can group specs which you want to run with beforeEach into a separate describe:
it('should 1...', function () {});
it('should 2...', function () {});
describe('group', function () {
beforeEach(function () {
// ...
});
it('should 3...', function () {});
it('should 4...', function () {});
// ...
});
I currently managed this with a work around as follows:
var executeBeforeEach = true;
function beforeEach() {
if(!executeBeforeEach) return;
//your before each code here.
}
describe('some test case 1', function(){
it('Start', function(){
//this is a dummy block to disable beforeeach for next test
})
it('The test that does not need beforeEach', function(){
//this test does not need before each.
})
it('Start', function(){
//this is a dummy block to enable beforeeach for next test
})
})
But, I am wondering if there is a more elegant way!?!