How to get jasmine tests to load data and execute

2019-05-09 22:15发布

问题:

I'm using Jasmine (2.3.2) and Protractor (2.5.1) for my UI tests. I need to load in data and generate tests for each item from that array. I have a function (checkItem) that creates a new describe function for each item and checks certain properties on that object. This is a very simplified version of my code and there are other tests that run before these.

If I call checkItem in a describe statement, itemsArr isn't defined yet. So I'm not sure how to get the data loaded and create dynamic tests from that data.

var data = require('get-data'); //custom module here

describe('Test', function() {
  var itemsArr;
  beforeAll(function(done) { 
    data.get(function(err, result) {
      itemsArr = result; //load data from module
      done();
    });
  })

  //error: Cannot read property 'forEach' of undefined
  describe('check each item', function() {
    itemsArr.forEach(function(item) {
      checkItem(item);
    });
  });

  function checkItem (item) {
    var itemName = item.name;
    describe(itemName, function() {
      console.log('describe');
      //this doesn't fire when 'should check item' is called
      it('should work', function() {
        console.log('it');
        expect(false).toBeTruthy();
      });
    });
  }

});

UPDATE: When I change my code like this it's the same issue, so maybe there's another way to load data instead of using beforeAll/beforeEach

beforeAll(function() {
  itemsArr = [
    {
      name: 'apple'
    },
    {
      name: 'orange'
    },
    {
      name: 'banana'
    }
  ]
});

回答1:

You are getting an undefined itemsArr cause the code in the inner describe executes very early in the process and before the beforeAll finishes getting the data. Having it in place of describe would let it wait for beforeAll to finish.

The problem with it now is that you cannot have nested its - jasmine would not execute the inner its, see this relevant issue.

If you would not create inner its dynamically, but just make your expectations in the parent it - this is going to work. Working sample:

describe('Test', function() {
    var itemsArr;
    beforeAll(function(done) {
        itemsArr = [
            {
                name: 'apple'
            },
            {
                name: 'orange'
            },
            {
                name: 'banana'
            }
        ];
        done();
    });

    it('should check each item', function() {
        itemsArr.forEach(function(item) {
            expect(false).toBeTruthy();
        });
    });

});

It produces 3 Expected false to be truthy failures.


I still think that if we would try using Protractor's Control Flow, we might have a better solution.