DevUI is a team with both design and engineering perspectives, serving huawei DevCloud platform and huawei internal background systems, as well as designers and front-end engineers. Add devui Helper (Devui-Official) DevUIHelper plugin: Devuihelper-lsp (welcome Star)

The introduction

As a mature Web front end engineer, we all know that writing unit test cases does not benefit the front end very much. There is still a lot of business code to write. What test cases to write?

So why do I cover unit test case writing?

Finding product quality issues on the development side is the lowest-cost way for development to ensure the quality of on-line products.

Writing test cases at development time is one of many strategies for finding problems on the development side.

When writing unit test cases for the DevUI component library, consider two things:

  1. First, the open source library already has the component implementation, the test-driven development scenario is weak;
  2. If we are developing based on an open source component library, we only care if some of our own common functions can be guaranteed.

This article will take the Button component in the component library as an example to expand the DevUI open source component library unit test case writing introduction.

1 preparation before writing unit test cases

Clone the ng-devui source code

First, clone the source code of the NG-devui component library. After installing the dependency packages, ensure that NPM start can start the project:

Step 2: Find the command to start unit tests

After the project is started, go to the package.json file and you can see that there are two test commands:

Some of you may be confused at this point, but which of these two commands should I run?

View angular.json to see which commands should be run. If you pull to the bottom of the angular.json file, you can see that devui is run by default. There are three projects in the project: devui, devui-e2e, and devui-lib.

The root path of devui is SRC, the root path of devui-lib is devui, and all components of the Devui component library are under devui:

Based on the above judgment, the project for the DevUI component library should be devui-lib.

So we should run the test:lib command in package.json:

npm run test:lib
Copy the code

Step 3: Run unit tests

After running the NPM run test:lib command, you can see that the DevUI component library contains 666 unit test cases, of which 5 are skipped, 661 succeed, and 0 fail.

Start writing unit test cases for Button components

Step 1: Find the unit test file for the Button component

Open the button component source directory, click button. Spec. ts test file, change the first describe encountered to fdescribe, run NPM run test:lib again, only 15 successful use cases will be found. A search for IT in the button.spec.ts file reveals 15 IT fields.

In fact, an IT is a unit test case, and FDESCRIBE states that only the IT unit test cases contained in the entire FDESCRIBE are run at runtime.

Step 2: Plan tests and prepare data

In order to ensure that the article is not so redundant, this paper only introduces some elements and only carries out unit tests on some functions of Button. After understanding the basic way of unit test case operation, we can start to write unit test cases.

Delete the contents of the existing button.spec.ts file before writing so that we can write the unit test case from 0.

When writing test cases, the button component is introduced, where beforeEach represents the action that is performed beforeEach it unit test case is executed.

@Component({ template: ` <d-button></d-button> ` }) class TestButtonAutoFocusComponent {} fdescribe('Button', () => { let fixture: ComponentFixture<any>; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ButtonModule], declarations: [TestButtonComponent, TestButtonAutoFocusComponent] }).compileComponents(); })); . });Copy the code

Here we will test the basic style of the button, the common style, the button click function, and the disabled state. Therefore, we will add style, disable, and click functions to the button in the TestButtonComponent test component.

@Component({ template: ` <d-button [bsStyle]="style" (btnClick)="isClick()" [disabled]="disabled"></d-button> ` }) class TestButtonComponent { style = 'primary'; disabled = false; hasClick = false; isClick() { this.hasClick = true; }}Copy the code

To test button-related functionality, we need to create an instance of TestButtonComponent and then be able to retrieve the button element used in the instance. Typically, four variables are used for testing.

let fixture: ComponentFixture<any>;
let testComponent: TestButtonComponent;
let buttonDebug: DebugElement;
let buttonNative: HTMLElement;

beforeEach((() => {
  fixture = TestBed.createComponent(TestButtonComponent);
  testComponent = fixture.debugElement.componentInstance;
  buttonDebug = fixture.debugElement.query(By.css('d-button'));
  buttonNative = buttonDebug.nativeElement;
  fixture.detectChanges();
}));
Copy the code

Step 3: Test Button component instance creation

In order to ensure that the Button component does not have fatal syntax class errors, the first step is to ensure that the component instance is created successfully.

it('Button demo has created successfully', () => {
  expect(testComponent).toBeTruthy();
});
Copy the code

Step 4: Test the Button style

To style a Button component, you need to know that the component is properly applied to the style class.

A) It can be seen from the button.component. HTML file that two classes devui-bTN and devui-btn-primary are correctly applied to indicate that button can be correctly applied to the style class. This way, as long as the style class in the style file is correct, the style is correct.

B) The correct application of devui-bTN and devui-btn-common indicates that the button style of common type is correct.

it('Button should apply css classes', () => {
  let buttonHtml = buttonDebug.query(By.css('button'));
  expect(buttonInsideNativeElement.classList.contains('devui-btn')).toBeTruthy();
  expect(buttonInsideNativeElement.classList.contains('devui-btn-primary')).toBeTruthy();
  
  testComponent.style = 'common';
  fixture.detectChanges();
  buttonHtml = buttonDebug.query(By.css('button'));
  
  expect(buttonInsideNativeElement.classList.contains('devui-btn')).toBeTruthy();
  expect(buttonInsideNativeElement.classList.contains('devui-btn-common')).toBeTruthy();
});
Copy the code

Step 5: Test the Button click function

If the isClick event is triggered, hasClick will change from false to true. If the isClick event is triggered successfully, hasClick will change from false to true.

A) First, we should determine whether the initial assignment of hasClick is correct;

B) Next, simulate the click event bound to clicking button.

it('Button click', () => {
  expect(testComponent.hasClick).toBeFalsy();
  
  let buttonHtml = buttonDebug.query(By.css('button'));
  buttonHtml.nativeElement.click();
  fixture.detectChanges();
  expect(testComponent.hasClick).toBeTruthy();
});
Copy the code

Step 6: Test the disable function

In the disabled state, invalid clicking isa major feature of its function, and the button in the disabled state has the disabled attribute, so our unit test is also divided into two parts:

A) Click failure

B) The button element has the disabled attribute

it('Button disabled should have disabled attribute', () => { testComponent.disabled = true; fixture.detectChanges(); // Expect (testComponent.hasclick).tobefalsy (); let buttonHtml = buttonDebug.query(By.css('button')); buttonHtml.nativeElement.click(); fixture.detectChanges(); expect(testComponent.hasClick).toBeFalsy(); / / are disabled expect form (buttonHtml. NativeElement. HasAttribute (" disabled ")). ToBeTruthy (); });Copy the code

3. Respect for quality

(1) As front-end development, I believe that most of the development is in the business development, if you encounter a high quality requirements of the business, any major accident may affect many customers, reduce the efficiency of customers, causing losses to customers. In this case, how can you ensure the quality of your code?

(2) Another situation is that any small component you develop, such as a small button, may be used in dozens or hundreds of businesses. Any mistake you make is like a stone falling into the lake, causing ripples on the whole lake.

In both cases, if a developer doesn’t test enough and goes live, it can cause a lot of damage.

Stability: The first requirement for both development scenarios.

Hopefully, the writing of the unit test cases above has been enlightening, but of course, our ultimate goal is still to solve more problems at the least cost!

Join us

We are DevUI team, welcome to come here and build elegant and efficient human-computer design/research and development system with us. Email: [email protected].

DevUI is monet’s disciple of closing doors

Previous articles are recommended

Start writing Tests for Your Angular App now, Part 2

Start writing Tests for Your Angular App now, Part 1

“How to build a grayscale Publishing environment”