question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Code does not appear when async/await is used with test

See original GitHub issue

When using async/await in tests, the code for the test appears as just ; (both JSON and HTML report). Switching the same test logic back to a normal function (non async) things start working again:

function longPromise() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({})
    }, 1000);
  });
}

describe('Async tests', () => {
  // Works as expected
  it('should return code when returning a promise', () => {
    return longPromise().then(result => {
      expect(result).to.exist;
    });
  });

  // Works as expected
  it('should return code when using done', (done) => {
    longPromise().then(result => {
      expect(result).to.exist;
      done();
    });
  });

  // DOES NOT WORK - code is ";"
  it('should return code when using async/await', async () => {
    const result = await longPromise();
    expect(result).to.exist;
  });
});

Running the above example yields JSON results that look like so:

      {
        "uuid": "e265b085-5692-4801-b2f8-a8f7a87e0c72",
        "title": "Async tests",
        "fullFile": "<- file path ->",
        "file": "<- file path ->",
        "beforeHooks": [],
        "afterHooks": [],
        "tests": [
          {
            "title": "should return code when returning a promise",
            "fullTitle": "Async tests should return code when returning a promise",
            "timedOut": false,
            "duration": 2007,
            "state": "passed",
            "speed": "slow",
            "pass": true,
            "fail": false,
            "pending": false,
            "code": "return longPromise().then(function (result) {\n  expect(result).to.exist;\n});",
            "err": {},
            "isRoot": false,
            "uuid": "41825a27-cd6f-4b65-b261-c7e606e17581",
            "isHook": false,
            "skipped": false
          },
          {
            "title": "should return code when using done",
            "fullTitle": "Async tests should return code when using done",
            "timedOut": false,
            "duration": 2003,
            "state": "passed",
            "speed": "slow",
            "pass": true,
            "fail": false,
            "pending": false,
            "code": "longPromise().then(function (result) {\n  expect(result).to.exist;\n  done();\n});",
            "err": {},
            "isRoot": false,
            "uuid": "0c6854b6-ca36-4bdd-b7a2-3882232f5234",
            "isHook": false,
            "skipped": false
          },
          {
            "title": "should return code when using async/await",
            "fullTitle": "Async tests should return code when using async/await",
            "timedOut": false,
            "duration": 2004,
            "state": "passed",
            "speed": "slow",
            "pass": true,
            "fail": false,
            "pending": false,
            "code": ";",
            "err": {},
            "isRoot": false,
            "uuid": "e268da13-766c-45a8-8d58-08ca2b3dd261",
            "isHook": false,
            "skipped": false
          }
        ],
        "suites": [],
        "passes": [
          "41825a27-cd6f-4b65-b261-c7e606e17581",
          "0c6854b6-ca36-4bdd-b7a2-3882232f5234",
          "e268da13-766c-45a8-8d58-08ca2b3dd261"
        ],
        "failures": [],
        "pending": [],
        "skipped": [],
        "duration": 6014,
        "root": false,
        "rootEmpty": false,
        "_timeout": 300000
      },

It is expected that the code would also show for the third test even though it uses async/await.

My guess it that it might have something to do with how the parsing of the babelified code is happening. I am using babel, so I believe the async/await code will be converted to generators, but not sure where the code drop is happening. Transpilation can be disabled, but not sure that would solve anything.

Let me know if more info would be helpful.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
adamgrubercommented, Jul 25, 2018

Should work now in 3.0.3

1reaction
adamgrubercommented, Jul 12, 2018

@prescottprue Thanks for the sample code. Its a HUGE help.

Here’s what’s going on. To display your test code in the report, mochawesome attempts to clean it by stripping off the leading function () {. It does this via a RegExp. In the case where you’re only seeing ; as the output, this it the input:

function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }

The problem is that the RegExp expects a new line after the opening bracket but the input code is all one line so the RegExp is matching the entire line and replacing it with an empty string. I should be able to update the RegExp to handle this case, though it may take some time to ensure I don’t introduce any regressions. It’s a gnarly RegExp that tries to handle every possible function type. I’ve been considering rewriting the clean code utility to use an AST instead.

EDIT: I’m wrong about the new line expectation. It’s something else in the line of code that is causing the RegExp to fail. AST is really the way to go here to cover all cases. The RegExp is only going to get more complex and brittle.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unit tests not showing code coverage with async/await
Are you asking why your unit test code isn't shown as covered or why your actual logic code isn't shown as covered? If...
Read more >
Testing-library: avoid these mistakes in async tests
If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise. In our test,...
Read more >
Async Methods - Testing Library
Several utilities are provided for dealing with asynchronous code. These can be useful to wait for an element to appear or disappear in ......
Read more >
Async/Await - Best Practices in Asynchronous Programming
Async all the way, Don't mix blocking and async code, Console main method. Configure context, Use ConfigureAwait(false) when you can, Methods that require ......
Read more >
Unit testing Swift code that uses async/await
Let's take a look at how to call async APIs within our unit tests, and also how async/await can be a great testing...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found