Skip to content

feat(tests): manage asynchronous tests using zones#7735

Closed
juliemr wants to merge 1 commit intoangular:masterfrom
juliemr:zone-spec-b
Closed

feat(tests): manage asynchronous tests using zones#7735
juliemr wants to merge 1 commit intoangular:masterfrom
juliemr:zone-spec-b

Conversation

@juliemr
Copy link
Copy Markdown
Member

@juliemr juliemr commented Mar 23, 2016

Instead of returning a promise, use the async function to wrap
tests. This will run the test inside a zone which does not complete
the test until all asynchronous tasks have been completed.

async may be used with the inject function, or separately.

BREAKING CHANGE:

injectAsync is now deprecated. Instead, use the async function
to wrap any asynchronous tests.

Before:

it('should wait for returned promises', injectAsync([FancyService], (service) => {
  return service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
}));

it('should wait for returned promises', injectAsync([], () => {
  return somePromise.then(() => { expect(true).toEqual(true); });
}));

After:

it('should wait for returned promises', async(inject([FancyService], (service) => {
  service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
})));

// Note that if there is no injection, we no longer need `inject` OR `injectAsync`.
it('should wait for returned promises', async(() => {
  somePromise.then() => { expect(true).toEqual(true); });
}));

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Mar 23, 2016

This is blocked until zone.js treats XHRs as a macrotask.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use this opportunity to remove FunctionWithParamTokens from regular paths(and handle it temporarily in till injectAsync is completely removed) since we no longer have a sync and async variations of it.

So the new inject() would just be something like

function inject(tokens, fn): Function {
  return () => {
     var params = tokens.map(t => injector.get(t));
     return FunctionWrapper.apply(fn, params);  
  } 
}

This way inject can be a generic mechanism to execute a function with injected parameters and not return the special FunctionWithParams type.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that we necessarily need to get rid of FunctionWithParamTokens - it's useful to store information about what we want to test and it's not tied to Jasmine.

In particular, we need to store information about additional providers somewhere so that we can do:

it('only uses these providers once', withProviders([MyService]).inject([MyService], (service) => {
 ...
});

We could pass the providers around everywhere, but I think it's clearer to store them on an object.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Agreed.

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 5, 2016

This is now using the latest zones release, and no longer blocked!

@juliemr juliemr added action: review The PR is still awaiting reviews from at least one requested reviewer and removed state: blocked labels Apr 5, 2016
@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 5, 2016

cc @mhevery @IgorMinar if you want to review!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need a return type?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@vikerman
Copy link
Copy Markdown
Contributor

vikerman commented Apr 5, 2016

LGTM

@juliemr juliemr force-pushed the zone-spec-b branch 2 times, most recently from 1ee351a to c515ec3 Compare April 5, 2016 23:32
@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 6, 2016

Looks like new zones may be causing an issue with the http code - I'm seeing errors in http://localhost:8001/playground/src/http/. Investigating...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeouts -> tasks (timeout is just one kind of task, but it's well representative of the whole class)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@IgorMinar
Copy link
Copy Markdown
Contributor

LGTM once the test failure is resolved. Good job Julie!

@mhevery
Copy link
Copy Markdown
Contributor

mhevery commented Apr 6, 2016

LGTM

@IgorMinar IgorMinar added pr_state: LGTM action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews labels Apr 6, 2016
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we clean up all the return values?

they are harmless but people will keep on copy&pasting existing tests and it will take forever to remove them. We could have a team-wide fixit after tobias' change lands.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done from this file.

@IgorMinar
Copy link
Copy Markdown
Contributor

one more thing, do we really have only this few async injected tests? I'd expect hundreds of them. Isn't that surprising?

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 6, 2016

Most of our tests are still using testing_internal, which uses the old AsyncTestCompleter. I have an issue to remove that when possible: #5443

@IgorMinar
Copy link
Copy Markdown
Contributor

@juliemr I see. that explains it. thanks!

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 7, 2016

The Travis error is a real problem with my changes in zone.js. I'm going to do a new zone release, then clean this up.

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 8, 2016

Done.

@mhevery mhevery removed the action: merge The PR is ready for merge by the caretaker label Apr 8, 2016
@mhevery
Copy link
Copy Markdown
Contributor

mhevery commented Apr 8, 2016

Hi @juliemr I have removed the merge label, because it seems to be passing tests which should be failing. can we discuss?

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 8, 2016

We are blocking this because zones doesn't handle this properly on node.js yes, so some tests run with gulp test.unit.cjs can't fail!

Pending a fix in zone.js...

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 14, 2016

With the new zone release, this is unblocked! Working on rebasing now.

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 14, 2016

OK! This is rebased and ready to go again. @mhevery or @IgorMinar can I get another ok?

Note that the example from https://github.com/mhevery/angular/tree/async-not-working still won't work without modification because it is importing from angular2/testing_internal instead of angular2/testing.

@juliemr juliemr removed their assignment Apr 14, 2016
@juliemr juliemr mentioned this pull request Apr 14, 2016
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a doc string for this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Instead of using injectAsync and returning a promise, use the `async` function
to wrap tests. This will run the test inside a zone which does not complete
the test until all asynchronous tasks have been completed.

`async` may be used with the `inject` function, or separately.

BREAKING CHANGE:

`injectAsync` is now deprecated. Instead, use the `async` function
to wrap any asynchronous tests.

Before:
```
it('should wait for returned promises', injectAsync([FancyService], (service) => {
  return service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
}));

it('should wait for returned promises', injectAsync([], () => {
  return somePromise.then(() => { expect(true).toEqual(true); });
}));
```

After:
```
it('should wait for returned promises', async(inject([FancyService], (service) => {
  service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
})));

// Note that if there is no injection, we no longer need `inject` OR `injectAsync`.
it('should wait for returned promises', async(() => {
  somePromise.then() => { expect(true).toEqual(true); });
}));
```
@mhevery mhevery added the action: merge The PR is ready for merge by the caretaker label Apr 14, 2016
@IgorMinar
Copy link
Copy Markdown
Contributor

IgorMinar commented Apr 15, 2016

@juliemr should we deprecate testing_internal? it seems that it's dangerous to use it now if you don't return the promise or call the async completer. no?

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 18, 2016

@IgorMinar I would like to, but we need to figure out what the ts2dart plan is.

@nschipperbrainsmith
Copy link
Copy Markdown

@juliemr I wanted to make a quick note as it is not mentioned within the changelog.md
That its important to include the 'node_modules/zone.js/dist/async-test.js', within your karma config / tests. Else you will experience a lot of red errors in your tests like i had.

8490921#diff-c4667ceccd7e91092048e752850fab9cR23

@juliemr
Copy link
Copy Markdown
Member Author

juliemr commented Apr 26, 2016

@schippie see #8253

@angular-automatic-lock-bot
Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker cla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants