Skip to content

Conversation

@atscott
Copy link
Contributor

@atscott atscott commented Jul 15, 2024

The behavior of ComponentFixture for zoneless tests was decided somewhat through guesswork, trial, and error. In addition, working on the zoneless fixture revealed oddities in the behavior of the zone-based fixture, or behaviors that we felt were counterintuitive. The most consequential difference is how change detection works: detectChanges goes through ApplicationRef.tick in zoneless while it is changeDetectorRef.detectChanges in the zone fixture.

We felt that running change detection through ApplicationRef.tick was important for several reasons:

  • Aligning application behavior more closely with the test behavior (almost all views are attached to application ref in reality)
  • Ensuring that afterRender* hooks are executed when calling fixture.detectChanges
  • Ensuring that the change detection runs again if render hooks update state

This change, however, has some noticeable consequences that will break some tests, mostly around how errors are handled. ApplicationRef.tick catches errors that happen during change detection and reports them to the ErrorHandler from DI. The default error handler only logs the error to the console. This will break tests which have expect(() => fixture.detectChanges()).toThrow(). In addition, it allows tests to pass when there are real errors encountered during change detection.

This change ensures that errors from ApplicationRef.tick are rethrown and will fail the test. We should also do a follow-up investigation to determine whether we can/should also do this for the zone-based ComponentFixture.

fixes #56977

@atscott atscott added the target: patch This PR is targeted for the next patch release label Jul 15, 2024
@angular-robot angular-robot bot added the area: core Issues related to the framework runtime label Jul 15, 2024
@ngbot ngbot bot added this to the Backlog milestone Jul 15, 2024
@atscott atscott force-pushed the zonelesstesterrorhandler branch 2 times, most recently from 094a528 to 7724bc9 Compare July 15, 2024 21:55
…oneless tests

The behavior of `ComponentFixture` for zoneless tests was decided somewhat through guesswork, trial, and error. In addition, working on the zoneless fixture revealed oddities in the behavior of the zone-based fixture, or behaviors that we felt were counterintuitive. The most consequential difference is how change detection works: `detectChanges` goes through ApplicationRef.tick in zoneless while it is `changeDetectorRef.detectChanges` in the zone fixture.

We felt that running change detection through `ApplicationRef.tick` was important for several reasons:
* Aligning application behavior more closely with the test behavior (almost all views are attached to application ref in reality)
* Ensuring that afterRender* hooks are executed when calling `fixture.detectChanges`
* Ensuring that the change detection runs again if render hooks update state

This change, however, has some noticeable consequences that will break some tests, mostly around how errors are handled. `ApplicationRef.tick` catches errors that happen during change detection and reports them to the ErrorHandler from DI. The default error handler only logs the error to the console. This will break tests which have `expect(() => fixture.detectChanges()).toThrow()`. In addition, it allows tests to pass when there are real errors encountered during change detection.

This change ensures that errors from `ApplicationRef.tick` are rethrown
and will fail the test. We should also do a follow-up investigation to
determine whether we can/should also do this for the zone-based
`ComponentFixture`.

fixes angular#56977
@atscott atscott force-pushed the zonelesstesterrorhandler branch from 7724bc9 to 6ba156e Compare July 16, 2024 14:42
@atscott atscott marked this pull request as ready for review July 18, 2024 22:28
@atscott
Copy link
Contributor Author

atscott commented Jul 18, 2024

TGP=https://fusion2.corp.google.com/presubmit/652583354/OCL:652583354:BASE:653720239:1721331698886:53f00f28;groups=/targets

I also tested this change for zone-based fixtures as well. There are ~200 failures in TGP that truly have errors that just result in console.logs at the moment rather than failing the test (as they probably should)

@atscott atscott added the action: merge The PR is ready for merge by the caretaker label Jul 26, 2024
@dylhunn
Copy link
Contributor

dylhunn commented Jul 29, 2024

This PR was merged into the repository by commit 3a63c9e.

The changes were merged into the following branches: main, 18.1.x

dylhunn pushed a commit that referenced this pull request Jul 29, 2024
…oneless tests (#56993)

The behavior of `ComponentFixture` for zoneless tests was decided somewhat through guesswork, trial, and error. In addition, working on the zoneless fixture revealed oddities in the behavior of the zone-based fixture, or behaviors that we felt were counterintuitive. The most consequential difference is how change detection works: `detectChanges` goes through ApplicationRef.tick in zoneless while it is `changeDetectorRef.detectChanges` in the zone fixture.

We felt that running change detection through `ApplicationRef.tick` was important for several reasons:
* Aligning application behavior more closely with the test behavior (almost all views are attached to application ref in reality)
* Ensuring that afterRender* hooks are executed when calling `fixture.detectChanges`
* Ensuring that the change detection runs again if render hooks update state

This change, however, has some noticeable consequences that will break some tests, mostly around how errors are handled. `ApplicationRef.tick` catches errors that happen during change detection and reports them to the ErrorHandler from DI. The default error handler only logs the error to the console. This will break tests which have `expect(() => fixture.detectChanges()).toThrow()`. In addition, it allows tests to pass when there are real errors encountered during change detection.

This change ensures that errors from `ApplicationRef.tick` are rethrown
and will fail the test. We should also do a follow-up investigation to
determine whether we can/should also do this for the zone-based
`ComponentFixture`.

fixes #56977

PR Close #56993
@dylhunn dylhunn closed this in 3a63c9e Jul 29, 2024
@angular-automatic-lock-bot
Copy link

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 Aug 29, 2024
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 area: core Issues related to the framework runtime target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zoneless tests with unset required inputs succeeds unexpectedly

3 participants