-
Notifications
You must be signed in to change notification settings - Fork 92
Description
First of all, happy new year and my best wishes to you! πΊπ
TLDR: I want to modernize Angular Testing Library (ATL)
History
ATL is created to test angular components with the following requisites:
- for developers: make testing easier and maintainable
- for users: provide a good experience with accessibility in mind
The more your tests resemble the way your software is used, the more confidence they can give you.
To achieve this ATL is as a wrapper around DOM Testing library, which allows you to interact with components and verify its behavior.
The main concepts for testing Angular components are the TestBed and the Angular change detection, these two are handled automatically by ATL. This means you (almost) don't have to fire change cycle manually (detectChanges()) because it's fired by the event.xyz(), findBy, and waitFor utility functions.
From the start the core API is almost unchanged, with some additions along the way to provide the functionality for new Angular API's.
The Problem
Angular has changed over the past year by providing us signals and a zoneless environment.
This also impacts the way we test components. Because it makes all(?) of the change detection cycles obsolete. I also don't want the test environment to trigger them, instead, I want a experience close to a "real production" experience.
The proposed solution
We can make this behavior configurable, but I want to take this opportunity to also remove deprecated features and less used features. Because many application rely on "older" Angular, I want to create a new subpackage where the automatic change detection will be removed and where many options and functionality will also be removed. This way the test suites for older applications or components are left untouched. In the future the new subpackage can become the default.
This means:
- No invocations of
detectChanges(), this is handled by Angular - Less custom code/behavior, use new Angular testing utilities
- Further
TestBedcustomizations can be handled within theconfigureTestBedcallback
In code this translates to the following minimal API with only the core functions:
export interface RenderResult<ComponentType> {
container: HTMLElement;
debug: (
element?: Element | Document | (Element | Document)[],
maxLength?: number,
options?: PrettyDOMOptions,
) => void;
fixture: ComponentFixture<WrapperType>;
}
export interface RenderOptions<Q extends Queries = typeof queries> {
configureTestBed?: (testbed: TestBed) => void;
bindings?: Binding[];
providers?: (Provider | EnvironmentProviders)[];
queries?: Q;
}Impact on you
As I mentioned earlier, this will not impact you in the short future.
But, if you want to test your new components that are zoneless you can make use of the new subpackage.
The end result should be a thinner layer around the Angular API.
For the new subpackage the requisites (mentioned at the top) are still answered.
// π Import from subpackage
import {render, screen} from '@testing-library/angular/zoneless';
test('interacts with the component', async () => {
// π We can just re-use the render method
await render(FixtureComponent);
// π Inputs and outputs can be set using the bindings API
await render(FixtureComponent, {
bindings: [...]
});
const incrementControl = screen.getByRole('button', { name: '+' });
const decrementControl = screen.getByRole('button', { name: '-' });
const valueControl = screen.getByTestId('value');
// π Use findBy instead of getBy so the component/signal can the value
expect(await screen.findByText('5')).toBeInTheDocument();
incrementControl.click();
incrementControl.click();
// π we can just use vi.waitFor instead of ATL's waitFor
await vi.waitFor(() => expect(valueControl).toHaveTextContent('7'));
})The functionality that I want to remove:
- Remove
declarations,imports,componentProperties,componentInputs,inputs,componentOutputs,onin favor of thebindingsAPI - Remove
routerfunctionality, this can be implemented on the user-side usingconfigureTestBed - Remove
deferBlockfunctionality, this can be implemented on the user-side usingconfigureTestBed
With these changes we can still provide a good testing experience. By using the latest Angular testing utilities we remove some clutter.
Call to action
If you want to get involved feel free to add a comment (or send me a DM) with the following questions in mind:
- Is there a better way to migrate existing test suites from "old" Angular to Modern Angular?
- I want to hear from you what features should be migrated over to this new package.