Heim  >  Artikel  >  Web-Frontend  >  Lassen Sie uns über Unit-Tests in Angular sprechen

Lassen Sie uns über Unit-Tests in Angular sprechen

青灯夜游
青灯夜游nach vorne
2021-07-26 10:36:362354Durchsuche

In diesem Artikel erfahren Sie mehr über Unit-Tests in Angular und stellen anhand von Beispielen die Verwendung von Unit-Test-Tools (Karma + Jasmine) vor.

Lassen Sie uns über Unit-Tests in Angular sprechen

Ich mache seit vielen Jahren Angular-Frontend-Entwicklung, aber ich hatte nie den Mut, das Frontend einem Unit-Test zu unterziehen. Der erste Grund ist, dass das Frontend mit Benutzern zu tun hat und nicht einfach ist Test Der zweite Grund ist, dass der Zeitdruck des Projekts es mir nicht erlaubt, Unit-Tests durchzuführen. Dies führt auch dazu, dass während der Front-End-Entwicklung menschliche Tests erforderlich sind, sobald sich das Unternehmen ändert. Es ist zeitaufwändig und hat keinen technischen Inhalt, was mich direkt an meinem Leben zweifeln lässt.

Vor kurzem hatte ich etwas Freizeit, also habe ich einfach Angulars Unit-Tests studiert. Angular verfügt tatsächlich über eigene Unit-Test-Tools: Karma + Jasmine:

  • Karma: Karma ist ein automatisiertes Testmanagement-Tool zum Testen von JavaScript-Code. Es kann Dateiänderungen überwachen und Tests automatisch ausführen.
  • Jasmine: Ein Framework zum Schreiben von Javascript-Tests.

【Verwandte Tutorial-Empfehlung: „Angular-Tutorial“】

Erster Testfall

Nach dem Erstellen der Angular-Anwendung wurden die Abhängigkeiten von Karma und Jasmine zur package.json-Datei hinzugefügt:

"karma": "~1.7.1",  
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.0",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",

Diese Wer Backend-Tests durchgeführt hat, kennt wahrscheinlich bereits die Arbeitsteilung zwischen diesen Komponenten:

  • karma: Karma-Kernkomponente
  • karma-chrome-launcher: Chrome-Launcher, der Test wird auf Chrome ausgeführt
  • karma-coverage-istanbul - Reporter: Berichterstattungsbericht
  • karma-jasmine: Jasmine-Kernkomponente
  • karma-jasmine-html-reporter: HTML-Testbericht

Im src-Verzeichnis sehen Sie die Namen: karma.conf.js, test.ts Zwei Dateien .

karma.conf.js: Karmas Konfigurationsdatei, die Konfigurationen, auf die man sich konzentrieren muss, sind:

  • frameworks: das verwendete Testframework, hier wird Jasmine verwendet

  • port: der zum Testen verwendete Port

  • autoWatch: Ob Änderungen im Testcode automatisch erkannt und der Test automatisch ausgeführt werden sollen.

  • Plugins: Die im Test verwendeten Plug-Ins, konsistent mit der Datei package.json Führen Sie den Test aus und verwenden Sie Chrome hier. Wenn Sie andere Browser verwenden müssen, müssen Sie den Browser-Launcher über npm installieren und ihn in Plugins und hier einrichten, z. B. mit Safari:

    npm install karma-safari-launcher --save-dev
    
    plugins: [
        require('karma-safari-launcher')
    ]
    browsers: ['Safari'],
  • test.ts: Testeintragsdatei, die die Testumgebung initialisiert und alle Testdateien angibt

  • Im App-Verzeichnis finden Sie auch eine Datei mit dem Namen app.component.spec.ts. Der Inhalt lautet wie folgt:
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
//测试入口,参数为测试名、方法
describe('AppComponent', () => {
  //每个测试用的Setup
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent  
      ],
    }).compileComponents();
  }));

  //测试用例
  it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));

  it(`should have as title 'test-demo'`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    //断言,期望值是否满足要求
    expect(app.title).toEqual('test-demo');
  }));

  it('should render title in a h1 tag', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    //通过querySelector获取页面元素
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to test-demo!');
  }));

  //每个测试用例的TearDown
  afterEach(function() {
    //清除测试数据
  });
});

Der obige Code verwendet die Jasmine-Syntax. Eine ausführlichere Einführung in Jasmine finden Sie unter „JavaScript-Unit-Test-Framework: Ein erster Blick auf Jasmine“. Ich werde hier nicht auf Details eingehen.

Ausführen: ng test, Sie sehen den Testbericht der obigen Datei:

Darüber hinaus können Sie im Testbericht auch auf einen Test klicken, um ihn separat auszuführen. Der Bericht lautet wie folgt:

Lassen Sie uns über Unit-Tests in Angular sprechen

Füllen Sie die Lücken aus

Lassen Sie uns über Unit-Tests in Angular sprechenInformationen zum Testen von Pipe, Service, Router und anderen Komponenten finden Sie in der Angular-Dokumentation. Hier konzentrieren wir uns auf die verschiedenen Fallstricke, die beim Testen auftreten.

Kein Anbieter ***

Wenn die getestete Komponente während des Tests andere Komponenten, Dienste oder Pipes von Drittanbietern erfordert und nicht eingeführt wird, wird „Kein Anbieter“ angezeigt Fehler, die Lösung ist sehr einfach, verwenden Sie einfach Imports oder Provider in beforeEach, um es einzuführen:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        //这里声明
      ],
      imports: [
        //这里引入
      ],
      providers: [
        //这里引入
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
    })
      .compileComponents();
  }));
Request Timeout

Während der Entwicklung kommt es bei asynchronen Anfragen häufig zu TimeOut-Fehlern aus Netzwerkgründen. Die übliche Lösung ist Set the Obergrenze der TimeOut-Zeit und Bereitstellung humanisierter Eingabeaufforderungen für TimeOut-Fehler. Beim Testen treten auch TimeOut-Fehler auf:

Die Lösung besteht darin, die TimeOut-Zeit in einem Testfall festzulegen:

it('#loadBalance for BCT should return real value', async () => {
  jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000000;
  ...
})

oder die TimeOut-Zeit einheitlich in BeforeEach festzulegen:

describe("my async specs", function() {
    var originalTimeout;
    beforeEach(function() {
      originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
      jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000000;
    });

    ...

    afterEach(function() {
      jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });
  });
Lassen Sie uns über Unit-Tests in Angular sprechen

Definieren Sie die Testumgebung

Angular bietet standardmäßig unterschiedliche Umgebungen für Entwicklung und Produkt. Zum Testen können wir auch Umgebungen festlegen. Erstellen Sie „environment.test.ts“ unter src/environment und ändern Sie den Inhalt von „angular.json“:

"architect":{
    "test":{
        ...
        "configurations": {
            "test": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.test.ts"
                }
              ]
            }
          }
    }
}
Ändern Sie die package.json-Datei:

"scripts": {
  "test": "ng test --configuration=test",
}

Führen Sie den folgenden Befehl wie folgt aus:

npm test
//或者
ng test --configuration=test

Beim Ausführen des Tests ist die Umgebung Verwendet wird der in der Datei test.ts konfigurierte Inhalt.

Daten-Rollback testen

做过Grails开发的伙计应该知道,单元测试、集成测试后,数据库中的测试数据会通过配置文件清除掉。在前端测试中,测试数据需要自行调用清除代码,对于使用LocalStorage、SessionStorage保持的数据亦是如此,方法很简单,在afterEach添加清除代码:

describe("my async specs", function() {
  
  afterEach(function() {
    //在这里清除测试数据
  });
});

与StoryBook的配合

先前我发布了一篇题为《StoryBook实战》的文章,StoryBook也是用来测试组件的,它与Karma+Jasmine有什么区别呢?

二者都能测试的:

  • Pipe

  • Servcie

  • Component

StoryBook不能测、Karma + Jasmine可测试的:

  • Router

  • Component的界面元素属性、Input、Output

Karma + Jasmine不能做的,StoryBook能做的:

  • Component交互测试

  • 组件管理

  • 编写组件文档

从上面可以看出,Storybook进行的是黑盒测试,Karma + Jasmine则注重白盒测试,二者侧重点不同,没有谁强谁弱之分,只有扬长避短,利用好各自的优点,方可让前端测试更完美,将前端bug扼杀在开发阶段。

一些前端测试感悟

虽然前端开发的工作比较繁琐,也是客户Challenge最多的地方,但是不代表前端只有页面,没有架构。以前之所以觉得Angular的单元测试难做,就是觉得都是页面的东西怎么测?其实,终其原因,还是没有架构,所有的代码都集中在Component中,为了赶进度,通过拷贝、粘贴,怎么快怎么来。结果,悲剧了,后期代码维护困难,一点改动就需要人肉测试。

费时不说,开发人员也没有成长。接触Angular前端测试后,我的脑海里又出现了“测试驱动开发”。一段好代码,前提是要易于测试,不管这段代码是用于前端还是后端。 前端开发人员不仅仅要关注页面的易用性、美观性,同样需要关注前端的架构,一个易于测试的架构才是最好的“武器”。

更多编程相关知识,请访问:编程入门!!

Das obige ist der detaillierte Inhalt vonLassen Sie uns über Unit-Tests in Angular sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:掘金--胡伟红. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen