Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I dynamically create a test spec within a callback?

I want to retrieve a list of elements on a page, and for each one, create a test spec. My (pseudo) code is :-

fetchElements().then(element_list) {
   foreach element {
     it("should have some property", function() {
        expect("foo")
     })
   }
}

When I run this, I get "No specs found", which I guess makes sense since they are being defined off the main path.

What's the best way to achieve dynamically created specs?

like image 905
pinoyyid Avatar asked Jan 26 '16 09:01

pinoyyid


1 Answers

There are major problems preventing it to be easily achieved:

  • the specs you are creating are based on the result of asynchronous code - on the elements Protractor should first find
  • you can only have the Protractor/WebDriverJS specific code inside the it, beforeEach, beforeAll, afterEach, afterAll for it to work properly and have the promises put on the Control Flow etc.
  • you cannot have nested it blocks - jasmine would not execute them: Cannot perform a 'it' inside another 'it'

If it were not the elements you want to generate test cases from, but a static variable with a defined value, it would be as simple as:

describe("Check something", function () {
    var arr = [
        {name: "Status Reason", inclusion: true},
        {name: "Status Reason", inclusion: false}
    ];

    arr.map(function(item) {
        it("should look good with item " + item, function () {
            // test smth
        });
    });
});

But, if arr would be a promise, the test would fail at the very beginning since the code inside describe (which is not inside it) would be executed when the tests would be loaded by jasmine.

To conclude, have a single it() block and work inside it:

it("should have elements with a desired property", function() {
    fetchElements().then(element_list) {
        foreach element {
            expect("foo")
        })
    }
}

If you are worried about distinguishing test failures from an element to element, you can, for instance, provide readable error messages so that, if a test fails, you can easily say, which of the elements has not passed the test (did not have a specific property in your pseudo-test case). For example, you can provide custom messages to expect():

expect(1).toEqual(2, 'because of stuff') 
like image 82
alecxe Avatar answered Oct 09 '22 23:10

alecxe