Skip to content

Test implementation guidelines for Ignite UI for Angular

Nikolay Alipiev edited this page Jan 17, 2020 · 35 revisions
Version User Date Notes
0.1 Zdravko Kolev June 10, 2019 Initial version
0.2 Nikolay Alipiev January 17, 2020 Angular component unit testing
  • Radoslav Karaivanov | Date:
  • Konstantin Dinev | Date:

Test implementation guidelines

Following Angular tutorials for component unit testing, what they suggest is to directly instantiate the component instead of creating a test fixture. Here is an example of such an approach:

select = new IgxSelectComponent(null, mockCdr, mockSelection, null, mockInjector);

Note: In addition to all the unit tests, there is a single test that is responsible for testing if the bandings are properly called. Once this is tested, all other related tests can be unit tests using API.

  1. Use separate describes. When multiple tests are using the same testBed, it should be initialized in a beforeEach. Example:
describe('IgxGrid - Multi Cell selection', () => {
    configureTestSuite();
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                SelectionWithScrollsComponent,
                SelectionWithTransactionsComponent
            ],
            imports: [NoopAnimationsModule, IgxGridModule]
        }).compileComponents();
    }));
    describe('Base', () => {
        ...
        beforeEach(fakeAsync(/** height/width setter rAF */() => {
           fixture = TestBed.createComponent(TestComponentX);
           ...
        }));

        it('Should be able to select a range with mouse dragging', () => {
...
  1. The helper functions for the tests are in HelperUtils. Review and reuse them in tests instead of rewriting them. For example, verifyCheckbox(), clearOverlay() etc.

  2. Tests should be excluded with pending() function; Do not use x. Example:

it('my it block', () => {
   pending('my pending comment');
   ...
});
  1. When writing tests for a new control/functionality the method configureTestSuite() must be called.
  2. When adding tests for the Grids (igxGrid, igxTreeGrid, igxHieraticalGrid) the test beds from the files grid-base-components.spec, grid-samples.spec and tree-grid-components.spec.ts should be used or extended /Most probably one of the test components already defined in them would be suitable for your scenario/. When a new test component is necessary, add it to one of these files so it can be easily reused later.
  3. Avoid defining test components in the test files. Define them in a separate file instead (for example, grid-samples.spec.ts) so they can be easily reused in other test files.
  4. Implement different tests for each scenario, based on the Test plan.
  5. Common logic should be exposed in separate functions. Example:
// tests column and column group header rendering
function testColumnGroupHeaderRendering(column: DebugElement, width: number, height: number,
title: string, descendentColumnCssClass?: string, descendentColumnCount?: number) {}
  1. When keyboard or mouse events are needed, the functions from the UIInteractions (ui-interactions.spec) should be used. For example UIInteractions.triggerKeyDownEvtUponElem('tab', cell.nativeElement, true), UIInteractions.simulateClickAndSelectCellEvent(), UIInteractions. simulateTouchMoveEvent() etc. New event functions should also be added here.
  2. Define constants when using a class name as a selector to find an element for easier maintenance.
const ITEM_CLASS = 'igx-grid-summary__item';
const SUMMARY_ROW = 'igx-grid-summary-row';
const SUMMARY_CELL = 'igx-grid-summary-cell';
  1. Use fakeAsync when there are async operations (animations, rAF, timeouts). Most grid testbeds setups need to be fakeAsync (or async).
  2. Use native async (when fakeAsync is not an option) - Example.
  • When there are delays in the execution. For example, when testing Grid's scrolling or Resizing - this is because the scrolling is happening out of the zone.
  • When using await wait with fixture.detectChanges().
  1. Consider Jasmine async and callback when using promises - whenStable, rendering done, etc.
  2. Avoid using done() callback, with timeout() and fixture.whenStable when possible.
  3. Use NoopAnimationsModule in tests where animations are not the subject of tests.
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
  1. Use Spies to:
  • check for different calls. Example:
    it('should not trigger onRemove event when ..', () => {
        ...
        const firstChipComp = fix.componentInstance.chips.toArray()[0];
        spyOn(firstChipComp.onRemove, 'emit');
  • prevent a certain function from execution. For example:
    // Spy the saveBlobToFile method so the files are not really created
    spyOn(ExportUtilities as any, 'saveBlobToFile');
Clone this wiki locally