Angular4(包括Angular2)的单元测试【Angular单元测试基础与组件简易测试部分】

Angular4(Angular2〜)的单元测试【Angular单元测试基础和组件简单测试编写】

由于我正在学习Angular的单元测试,所以我打算分几次写成文章。
本次文章主要参考了以下官方文档的四个部分:
介绍Angular的测试
第一个karma测试
测试一个组件
测试一个带有外部模板的组件

本次文章的主题是关于Angular测试的大致流程和简单的组件测试。

使用测试工具

在Angular的测试中,需要使用一些JavaScript领域的测试工具。如果不了解这些工具,可能会导致挫败,因此,在进行Angular自身的测试之前,需要先学习这些工具。以下内容可以作为参考,便于理解。

茉莉花

JavaScript的测试框架

茉莉花公式
https://jasmine.github.io/2.0/introduction.html
Jasmine的易懂文章
Jasmine使用方法备忘录 – Qiita
Jasmine规范记忆 – Qiita

因果报应

用于在浏览器中运行单元测试的测试运行器

逐步开始学习Karma的易懂文章- 掘金
Karma官方网站
Karma- 令人惊叹的JavaScript测试运行器

测试组件

import {Component} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'テストだよ';

  /**
   * h1の文章を変更する
   */
  changeH1Element() {
    this.title = 'クリックされたぜ!';
  }
}
<h1>
  {{title}}
</h1>

<p class="button" (click)="changeH1Element()">ここをクリックして</p>

如果标题上有一个“点击这里”的地方,当你点击它时,标题会改变。
此外,本次的目的是为了学习 Angular 的单元测试,不会进行任何 CSS 或其他的装饰。

考试班级

import {ComponentFixture, TestBed, async, ComponentFixtureAutoDetect,} from '@angular/core/testing';
import {By}              from '@angular/platform-browser';
import {DebugElement}    from '@angular/core';
import {AppComponent} from './app.component';


// describeでテストSuiteを作成
describe('AppComponentのテスト', () => {
  // テストの中のAppComponent
  let comp: AppComponent;
  // ComponentFixtureは、 componentのインスタンスそのものとcomponentのDOM elementのハンドルであるDebugElementへのアクセスを提供する。
  let fixture: ComponentFixture<AppComponent>;
  // ComponentのDOM elementのhandle
  let de: DebugElement;
  let el: HTMLElement;


  // 各Spec(個々のテスト)が開始される前に行う処理を設定する。
  // 非同期処理
  // Componentのインスタンスを生成する前に、Angular template compilerが外部ファイルを読み込む
  beforeEach(async(() => {
    // テストしたいクラスのためのモジュール環境をconfigureTestingModuleメソッドで設定する。
    // メタデータの登録
    TestBed.configureTestingModule({
      // テストされるComponentを登録
      declarations: [
        AppComponent
      ],
      providers: [
        {provide: ComponentFixtureAutoDetect, useValue: true}
      ]
    }).compileComponents(); // 外部ファイルをコンパイル

  }));

  // 同期処理
  // Componentのインスタンスを生成
  beforeEach(() => {
    // ComponentFixtureは、 componentのインスタンスそのものとcomponentのDOM elementのハンドルであるDebugElementへのアクセスを提供する。
    fixture = TestBed.createComponent(AppComponent);

    // テストされるComponentのインスタンス
    comp = fixture.componentInstance;

    // queryは、fixtureのDOM全体の中から、引数で与えたelementを満たす最初のDom elementとマッチしたDebugElementを返す
    // Byでは、cssのselectorを生成している。
    de = fixture.debugElement.query(By.css('h1'));

    el = de.nativeElement;
  });


// itでSpecを作成
  it('AppComponentのインスタンスが生成できているかどうか', async(() => {
    // trueかどうかs
    expect(comp).toBeTruthy();
  }));
  it('何もしない場合のタイトルがAppComponentのtitleと同じかどうか', async(() => {
    expect(el.textContent).toContain(comp.title);
  }));
  it('何もしない場合のタイトルがAppComponentのtitleと同じかどうか(上のテストと同じことをしている)', async(() => {
    expect(el.textContent).toContain('テストだよ');
  }));

  it('detectChangesが1回起きた時、h1の値が変更されるかどうか', async(() => {
    comp.title = 'クリックされたぜ!';
    fixture.detectChanges();
    expect(el.textContent).toContain(comp.title);
  }));

  it('changeH1Elementが呼び出されたら、titleが変更されるかどうか', async(()=> {
    comp.changeH1Element();
    expect(comp.title).toBe('クリックされたぜ!');
  }));
});

在每个处理中所做的事情已经以代码中的注释形式记录下来。

Angular测试的整体架构

基本上,似乎遵循jasmine的結構。
1. 在beforeEach中,描述在每個測試Spec執行之前要執行的代碼。(有時候也可以在afterEach中,描述在每個測試Spec執行之後要執行的代碼。)
2. 使用descibe創建Suite(一組測試的塊),並在其中使用it來描述多個Spec(單獨的測試方法)。在這個it中,進行各種測試。

在Angular的测试中使用的类和方法-使用Angular进行测试的类和方法

测试平台

Angular官方文档的公式API参考,可以在此链接中找到:https://angular.io/docs/ts/latest/api/core/testing/index/TestBed-class.html

为单元测试配置和初始化环境,并提供在单元测试中创建组件和服务的方法。

创建用于配置和初始化单元测试环境的设置。
此外,创建用于在单元测试内生成组件和服务的方法。

它创建了一个Angular测试模块-一个@NgModule类,您可以通过configureTestingModule方法进行配置,以为要测试的类生成模块环境。

TestBed用于生成Angular的测试模块(@NgModule类)。
@NgModule类在configureTestingModule方法中设置为要测试的类的模块环境。

进行测试环境的初始化和设置。

测试床配置TestingModule

设置用于要测试的类的模块环境。
进行元数据的注册。类似于@NgModule的测试版本。

beforeEach(jasmine的方法)之前

在每个特定测试开始前进行配置处理。

TestBed.createComponent()是用于在Angular测试中创建组件实例的函数。ComponentFixture是一个包含了组件实例及其相关属性和功能的辅助工具类。

TestBed.createComponent是Angular框架中的公共API引用,具体信息请参阅https://angular.io/docs/js/latest/api/core/testing/index/TestBed-class.html。

ComponentFixture是Angular框架中的公共API引用,具体信息请参阅https://angular.io/docs/ts/latest/api/core/testing/index/ComponentFixture-class.html。

createComponent方法返回一个ComponentFixture,在创建的组件周围提供了一个测试环境的句柄。Fixture提供了对组件实例本身和DebugElement的访问权限,DebugElement是对组件的DOM元素的句柄。

createComponent(TestBed.createComponent)函数会返回一个ComponentFixture类,该类是用于测试生成的组件的环境句柄。ComponentFixture类提供了对组件实例本身以及组件DOM元素的句柄DebugElement的访问权限。

ComponentFixture提供了对想要测试的组件实例和该组件的DebugElement的访问。此功能使得可以操作测试目标组件的实例和DOM元素。

据我的理解,似乎是在使用createComponent后,不应该再使用TestBed的配置方法,因为它会关闭TestBed实例的设置。

调试元素查询

公式API参考资料
https://angular.io/docs/ts/latest/api/core/index/DebugElement-class.html

在给定的DOM元素集合中,通过参数指定的元素,查询并返回与之匹配的第一个DebugElement。fixture.debugElement.query的DebugElement和返回的DebugElement是不同的。

对于查询全部的情况,它会返回一个数组,其中包含满足给定元素参数的所有Dom元素。

请参考以下链接获取更多信息:
https://angular.io/docs/ts/latest/guide/testing.html#!%23component-fixture
https://angular.io/docs/js/latest/api/core/index/DebugElement-class.html#!%23query-anchor

使用下面的文字原生地用中文表达,只需要一个选项:

通过

在Angular的Utility中,生成predicates(谓词)的功能。

公式API参考
https://angular.io/docs/ts/latest/api/platform-browser/index/By-class.html

监测变化

进行组件的变更检测周期。

中文本土化后的版本为:

Angular 2变更检测解释- Qiita对于detectChanges非常易懂的解释如下链接:
https://angular.io/docs/ts/latest/api/core/testing/index/ComponentFixture-class.html#!%23detectChanges-anchor

借用以下文章中的词汇,可自然地用中文进行改述:

如果引用以下文章的词汇,可以用中文进行一种自然的改述:

变更检测是指检测模型的变化并将其反映在用户界面上。

引用来源 大致意思是:Angular 2 变更检测解释 – Qiita

通过调用fixture.detectChanges()来告知Angular从测试中进行变化检测。

使用Angular读取外部的模板。

在使用外部的模板和CSS文件时,似乎需要进行一些简单的处理。

但是Angular模板编译器在创建组件实例之前必须从文件系统中读取外部文件。这是一个异步的活动。

在Angular中,在创建组件实例之前,Angular模板编译器需要加载外部文件,这是一个异步操作。

换句话说,在生成 Component 实例之前,Angular 模板编译器需要在 beforeEach 中执行能够读取外部文件的处理。

测试床编译组件

公式API参考文档

首先,在测试模块中以异步方式编译设定的组件。
一旦完成上述的compileComponents,外部文件和CSS文件将被内联,
而TestBed.createComponent将可以同步地生成组件实例。

请参考:https://angular.io/docs/ts/latest/guide/testing.html#!%23component-fixture

在将template和css转移到外部文件时,务必在“生成组件实例”之前正确地使用异步和同步来“加载外部文件”。(代码的编写顺序可以不按照这个顺序)

考试执行界面

当您在命令行上输入以下命令时,将会启动Karma测试执行器并打开浏览器,测试结果将显示在浏览器上。

ng test
ng-karma.png

我参考了这个网站。

公式
https://angular.io/docs/ts/latest/guide/testing.html#!#组件-夹具

jasmine公式
https://jasmine.github.io/2.0/introduction.html
Jasmine官方文档
Jasmine使い方メモ – Qiita
Jasmine使用方法笔记 – Qiita
Jasmine spec覚え書き – Qiita
Jasmine规范备忘录 – Qiita

用中文将以下内容进行改述,只需要提供一种选择:

易于理解的Karma文章
逐步开始使用Karma – Qiita
Karma官方网站
Karma – 令人惊叹的JavaScript测试运行器

公式API参考资料
https://angular.io/docs/ts/latest/api/core/testing/index/TestBed-class.html
https://angular.io/docs/js/latest/api/core/testing/index/TestBed-class.html
https://angular.io/docs/ts/latest/api/core/testing/index/ComponentFixture-class.html
https://angular.io/docs/ts/latest/api/core/index/DebugElement-class.html
https://angular.io/docs/ts/latest/api/platform-browser/index/By-class.html
https://angular.io/docs/ts/latest/api/core/testing/index/ComponentFixture-class.html#!%23detectChanges-anchor

关于detectChanges的说明:
Angular 2变更检测解释 – Qiita


※在博客上也发布了同一篇文章。

Angular4(Angular2 〜)的单元测试【Angular单元测试的基础和组件简单测试部分】。

广告
将在 10 秒后关闭
bannerAds