2

Is there a way to capture expect failures in Jasmine?

This doesn't work, the exception is not captured.

try {
  expect(1).toBe(3)
} catch (e) {

}

I am looking for something like this TestNG equivalent:

SoftAssert a= new SoftAssert();

a.assertTrue(1==2, "safasfhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
a.assertTrue(1==2, "sad");
a.assertTrue(1==2, "test");
a.assertTrue(1==2, "3");

try {

    a.assertAll();

} catch (Throwable  e) {

    Logger logger = Logger.getLogger("");
    logger.log(Level.WARNING, e.toString());

}
10
  • 1
    Could you expand on "doesn't work"? What was the expected behaviour, and what happens instead?
    – jonrsharpe
    Commented May 21, 2020 at 7:08
  • It doesn't capture the error , i want to do something like in sqa.stackexchange.com/a/44631/40022
    – PDHide
    Commented May 21, 2020 at 7:14
  • So that it can report multiple failing assertions, rather than throwing an exception, Jasmine's assertions register a failure for later reporting.
    – jonrsharpe
    Commented May 21, 2020 at 7:26
  • 1
    Again, to what end? In that TestNG you get to see the output from multiple assertions, but that already happens in Jasmine. Please provide the context, what's the problem you're trying to solve with this?
    – jonrsharpe
    Commented May 21, 2020 at 7:37
  • 1
    Yes, that's how it's designed to work. The alternative is "I want the test to pass even though the expectations failed" and doesn't really make sense; in that case maybe you shouldn't be using expectations (in this case just if (1 !== 3) { console.log("Maths works") }). Again, please provide the context behind this request; do a five whys and give the last one rather than the first.
    – jonrsharpe
    Commented May 21, 2020 at 7:44

3 Answers 3

1

Rather than use a string:

assertExpectation("expect(1).toBe(3)");

why not pass a callback, shadowing the global expect with the env's:

assertExpectation(function (expect) {
  expect(1).toBe(3);
};

This means you can have IDE support on the JS code, rather than at runtime when the eval fails, and allows you to have multiple soft expectations (and other code) in one callback. You could implement this like:

function assertExpectation(callback) {
  const env = new jasmine.Env();
  const spec = env.it("", async function () {
    await callback(env.expect);
  });
  return new Promise(function (resolve) {
    spec.resultCallback = function (result) {
      const messages = result.failedExpectations.map(function (e) {
        return e.message;
      });
      resolve(messages);
    }
    env.execute();
  });
}

Note:

  1. The env.describe was redundant for a single spec;
  2. spec.result seemed to be populated asynchronously in my testing (using Jasmine 3.5.0), so I've added handling for async code throughout;
  3. It now handles multiple messages, rather than just the first; and
  4. Your code is a good example of how not to use comments, they're either redundant repetition of what the code itself does (e.g. create a variable spec) or out of date with the actual implementation (...along with the stack).

Given the following in a discovered test file with the above implementation:

it("works how I want", async () => {
  const messages = await assertExpectation(function (expect) {
    expect(1).toBe(3);
  });
  console.log(messages);
  expect(1).toBe(1);
});

I get the output

$ npm t

> [email protected] test path/to/soft-expect
> jasmine

Randomized with seed 82972
Started
[ 'Expected 1 to be 3.' ]
.


1 spec, 0 failures
Finished in 0.011 seconds
Randomized with seed 82972 (jasmine --random=true --seed=82972)
1
  • Wow that's smart thinking, thanks for this
    – PDHide
    Commented May 23, 2020 at 5:38
1

Found a workaround for the above issue:

Here I created a separate Jasmine object and calls the expect inside the new Jasmine object and retrieves the error message.

Now I can just pass the Jasmine expectation to assertExpectation as a string and get the message:

 assertExpectation=function (expression) {

  //create a variable spec
  let spec;
  //create a jasmine object
  let env = new jasmine.Env()
  //create describe and spec
  env.describe('desc', function () {
    //assign the spec to the spec variable
    spec = env.it('spec', function (done) {
      //`${env.expect(12).toBe(2)}`
      eval("env." + expression)
    })
  })
  // execute the spec
  env.execute()
  //access the spec and print out the message as error along with the stack to know where exactly this error thrown
  // in our actual spec.
  if (spec.result.failedExpectations[0] !== undefined) {
    return (spec.result.failedExpectations[0].message);
  }
}



describe('Validate expectations', function () {

  it('test', async function () {
    await browser.get("https://www.npmjs.com");    
    console.log(assertExpectation("expect('This sentence ').toContain('nothing')"));    
    await browser.get("https://www.protractortest.org/#/jasmine-upgrade")
  });

});

Output:

enter image description here

2
  • 2
    That's an interesting approach. Wouldn't it be better to pass in the env's expect to a callback, so you write e.g. softAssertion((expect) => expect(1).toBe(3));? That way you don't have to eval anything and your expectation can actually be e.g. intellisense'd and syntax checked before runtime. Also you could return an array of all failure messages.
    – jonrsharpe
    Commented May 22, 2020 at 21:37
  • This looks interesting , could you explain how this work where to provide this . If I use expect outside spec then it throws exception saying expect not used with anyspec
    – PDHide
    Commented May 22, 2020 at 21:40
0

If you are trying to find a way so that test continues after assertion fails then it is important to know that the jasmine expectations are kind of "soft" by default.

It means that the test continues to execute even after a failure.

6
  • Thanks Vishal , i don't want to fail the test
    – PDHide
    Commented Jun 10, 2020 at 6:49
  • It will not fail the test but the assertion , that's the whole point. :) Commented Jun 10, 2020 at 19:30
  • it fails the test at the end ,
    – PDHide
    Commented Jun 10, 2020 at 19:31
  • I am not sure , why one would not to fail the assertion as well ... except for the fake testing..! Commented Jun 10, 2020 at 19:33
  • This is against the basic principle of testing so it does not make any sense!! Commented Jun 10, 2020 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.