メインコンテンツへスキップ
バージョン: v8

テスト

Ionic CLIを使用して@ionic/angularアプリケーションを生成すると、アプリケーションの単体テストとエンドツーエンドテスト用に自動的にセットアップされます。これは、Angular CLIで使用されているのと同じセットアップです。Angularアプリケーションのテストに関する詳細については、Angular Testing Guideを参照してください。

テストの原則

アプリケーションをテストする場合、テストはシステムに欠陥が存在するかどうかを示すことができるということを念頭に置いておくのが最善です。ただし、非自明なシステムに欠陥が完全にないことを証明することは不可能です。このため、テストの目標はコードが正しいことを検証することではなく、コード内の問題を見つけることです。これは微妙ですが重要な区別です。

コードが正しいことを証明しようとすると、コードのハッピーパスに固執する可能性が高くなります。問題を見つけようとすると、コードをより完全に実行し、そこに潜んでいるバグを見つける可能性が高くなります。

また、アプリケーションのテストは最初から始めるのが最善です。これにより、修正が簡単なプロセスの早い段階で欠陥を見つけることができます。これにより、システムに新しい機能が追加される際に、自信を持ってコードをリファクタリングすることもできます。

単体テスト

単体テストは、システム全体から分離されたコードの単一ユニット(コンポーネント、ページ、サービス、パイプなど)を実行します。分離は、コードの依存関係の代わりにモックオブジェクトを注入することによって実現されます。モックオブジェクトにより、テストは依存関係の出力を細かく制御できます。モックを使用すると、テストでどの依存関係が呼び出されたか、およびそれらに何が渡されたかを判断することもできます。

適切に記述された単体テストは、コードのユニットとそれに含まれる機能がdescribe()コールバックを介して記述されるように構造化されています。コードのユニットとその機能の要件は、it()コールバックを介してテストされます。describe()およびit()コールバックの説明を読むと、フレーズとして意味をなします。ネストされたdescribe()と最後のit()の説明を連結すると、テストケースを完全に記述する文が形成されます。

単体テストは分離されたコードを実行するため、高速で堅牢であり、高いコードカバレッジが可能です。

モックの使用

単体テストは、分離されたコードモジュールを実行します。これを容易にするために、Jasmine(https://jasmine.dokyumento.jp/)を使用することをお勧めします。Jasmineは、テスト中に依存関係の代わりとなるモックオブジェクト(Jasmineでは「スパイ」と呼ばれます)を作成します。モックオブジェクトを使用すると、テストは依存関係への呼び出しによって返される値を制御できるため、現在のテストは依存関係に加えられた変更に依存しません。これにより、テストのセットアップも簡単になり、テスト対象のモジュール内のコードのみに関心を持つことができます。

モックを使用すると、テストでtoHaveBeenCalled*関数セットを介して、モックが呼び出されたかどうか、およびどのように呼び出されたかをクエリすることもできます。テストは、これらの関数を使用して可能な限り具体的にする必要があり、メソッドが呼び出されたことをテストする場合は、toHaveBeenCalledへの呼び出しよりもtoHaveBeenCalledTimesへの呼び出しを優先する必要があります。つまり、expect(mock.foo).toHaveBeenCalledTimes(1)expect(mock.foo).toHaveBeenCalled()よりも優れています。何かが呼び出されていないことをテストする場合は、逆のアドバイスに従う必要があります(expect(mock.foo).not.toHaveBeenCalled())。

Jasmineでモックオブジェクトを作成するには、2つの一般的な方法があります。モックオブジェクトは、jasmine.createSpyおよびjasmine.createSpyObjを使用してゼロから構築するか、spyOn()およびspyOnProperty()を使用して既存のオブジェクトにスパイをインストールすることができます。

jasmine.createSpyjasmine.createSpyObjの使用

jasmine.createSpyObjは、作成時に定義されたモックメソッドのセットを使用して、ゼロから完全なモックオブジェクトを作成します。これは非常に簡単であるという点で便利です。何も構築したり、テストに注入したりする必要はありません。この関数を使用するデメリットは、実際のオブジェクトと一致しない可能性のあるオブジェクトの作成が可能になることです。

jasmine.createSpyも似ていますが、スタンドアロンのモック関数を作成します。

spyOn()spyOnProperty()の使用

spyOn()は、既存のオブジェクトにスパイをインストールします。この手法を使用する利点は、オブジェクトに存在しないメソッドをスパイしようとすると、例外が発生することです。これにより、存在しないメソッドをモックするテストを防ぐことができます。欠点は、テストを開始するために完全に形成されたオブジェクトが必要になるため、必要なテストセットアップの量が増える可能性があることです。

spyOnProperty()も同様ですが、メソッドではなくプロパティをスパイするという違いがあります。

一般的なテスト構造

単体テストは、エンティティ(コンポーネント、ページ、サービス、パイプなど)ごとに1つのspecファイルを含むspecファイルに格納されます。specファイルは、テスト対象のソースと並んで存在し、その後に名前が付けられます。たとえば、プロジェクトにWeatherServiceというサービスがある場合、そのコードはweather.service.tsという名前のファイルにあり、テストはweather.service.spec.tsという名前のファイルにあります。これらの両方のファイルは同じフォルダーにあります。

specファイル自体には、全体的なテストを定義する単一のdescribe呼び出しが含まれています。その中にネストされているのは、主要な機能領域を定義する他のdescribe呼び出しです。各describe呼び出しには、セットアップおよびティアダウンコード(通常はbeforeEachおよびafterEach呼び出しによって処理)、機能の階層的な内訳を形成するその他のdescribe呼び出し、および個々のテストケースを定義するit呼び出しを含めることができます。

describeおよびit呼び出しには、説明テキストラベルも含まれています。適切に形成されたテストでは、describeおよびit呼び出しはラベルと組み合わされて適切なフレーズを実行し、describeおよびitラベルを組み合わせて形成された各テストケースの完全なラベルは、完全な文を作成します。

例:

describe('Calculation', () => {
describe('divide', () => {
it('calculates 4 / 2 properly' () => {});
it('cowardly refuses to divide by zero' () => {});
...
});

describe('multiply', () => {
...
});
});

外側の describe 呼び出しは、Calculation サービスがテストされていることを示し、内側の describe 呼び出しは、どの機能がテストされているかを正確に示し、it 呼び出しは、テストケースが何であるかを示します。実行すると、各テストケースの完全なラベルは、(Calculation divide cowardly refuses to divide by zero)のような意味のある文になります。

ページとコンポーネント

ページは単なるAngularコンポーネントです。したがって、ページとコンポーネントはどちらも、Angularのコンポーネントテストガイドラインを使用してテストされます。

ページとコンポーネントにはTypeScriptコードとHTMLテンプレートマークアップの両方が含まれているため、コンポーネントクラスのテストとコンポーネントDOMのテストの両方を実行できます。ページが作成されると、生成されるテンプレートテストは次のようになります。

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TabsPage } from './tabs.page';

describe('TabsPage', () => {
let component: TabsPage;
let fixture: ComponentFixture<TabsPage>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [TabsPage],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}).compileComponents();

fixture = TestBed.createComponent(TabsPage);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

コンポーネントクラスのテストを行う場合、コンポーネントオブジェクトは、component = fixture.componentInstance; を介して定義されたコンポーネントオブジェクトを使用してアクセスされます。これはコンポーネントクラスのインスタンスです。DOMテストを行う場合、fixture.nativeElement プロパティが使用されます。これはコンポーネントの実際の HTMLElement であり、テストで HTMLElement.querySelector などの標準HTML APIメソッドを使用してDOMを調べることができます。

サービス

サービスは、多くの場合、計算やその他の操作を実行するユーティリティサービスと、主にHTTP操作とデータ操作を実行するデータサービスの2つの広範なカテゴリに分類されます。

基本的なサービステスト

ほとんどのサービスをテストする推奨される方法は、サービスをインスタンス化し、サービスが持つ依存関係に対してモックを手動で注入することです。このようにして、コードを隔離してテストできます。

タイムカードの配列を受け取り、純給与を計算するメソッドを持つサービスがあるとします。また、税計算は現在のサービスが依存する別のサービスを介して処理されると仮定します。この給与サービスは、次のようにテストできます。

import { PayrollService } from './payroll.service';

describe('PayrollService', () => {
let service: PayrollService;
let taxServiceSpy;

beforeEach(() => {
taxServiceSpy = jasmine.createSpyObj('TaxService', {
federalIncomeTax: 0,
stateIncomeTax: 0,
socialSecurity: 0,
medicare: 0
});
service = new PayrollService(taxServiceSpy);
});

describe('net pay calculations', () => {
...
});
});

これにより、テストは taxServiceSpy.federalIncomeTax.and.returnValue(73.24) などのモック設定を介して、さまざまな税計算によって返される値を制御できます。これにより、「純給与」テストは、税計算ロジックから独立できます。税コードが変更されると、税サービス関連のコードとテストのみを変更する必要があります。純給与のテストは、税の計算方法に関係なく、値が適切に適用されるかどうかだけを気にするため、そのまま動作し続けることができます。

ionic g service name を介してサービスが生成されるときに使用される足場は、Angularのテストユーティリティを使用し、テストモジュールを設定します。そうすることは厳密には必須ではありません。ただし、そのコードは残しておくことができ、サービスを手動で構築したり、次のように注入したりできます。

import { TestBed, inject } from '@angular/core/testing';

import { PayrollService } from './payroll.service';
import { TaxService } from './tax.service';

describe('PayrolService', () => {
let taxServiceSpy;

beforeEach(() => {
taxServiceSpy = jasmine.createSpyObj('TaxService', {
federalIncomeTax: 0,
stateIncomeTax: 0,
socialSecurity: 0,
medicare: 0,
});
TestBed.configureTestingModule({
providers: [PayrollService, { provide: TaxService, useValue: taxServiceSpy }],
});
});

it('does some test where it is injected', inject([PayrollService], (service: PayrollService) => {
expect(service).toBeTruthy();
}));

it('does some test where it is manually built', () => {
const service = new PayrollService(taxServiceSpy);
expect(service).toBeTruthy();
});
});

HTTPデータサービスのテスト

HTTP操作を実行するほとんどのサービスは、それらの操作を実行するためにAngularのHttpClientサービスを使用します。このようなテストでは、Angularの HttpClientTestingModule を使用することをお勧めします。このモジュールの詳細なドキュメントについては、AngularのAngularのHTTPリクエストのテストガイドを参照してください。

このようなテストの基本的なセットアップは次のようになります。

import { HttpBackend, HttpClient } from '@angular/common/http';
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
import { TestBed, inject } from '@angular/core/testing';

import { IssTrackingDataService } from './iss-tracking-data.service';

describe('IssTrackingDataService', () => {
let httpClient: HttpClient;
let httpTestingController: HttpTestingController;
let issTrackingDataService: IssTrackingDataService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [IssTrackingDataService],
});

httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
issTrackingDataService = new IssTrackingDataService(httpClient);
});

it('exists', inject([IssTrackingDataService], (service: IssTrackingDataService) => {
expect(service).toBeTruthy();
}));

describe('location', () => {
it('gets the location of the ISS now', () => {
issTrackingDataService.location().subscribe((x) => {
expect(x).toEqual({ longitude: -138.1719, latitude: 44.4423 });
});
const req = httpTestingController.expectOne('http://api.open-notify.org/iss-now.json');
expect(req.request.method).toEqual('GET');
req.flush({
iss_position: { longitude: '-138.1719', latitude: '44.4423' },
timestamp: 1525950644,
message: 'success',
});
httpTestingController.verify();
});
});
});

パイプ

パイプは、特に定義されたインターフェースを持つサービスのようなものです。これは、1つのパブリックメソッド transform を含むクラスであり、入力値(およびその他のオプションの引数)を操作して、ページにレンダリングされる出力を作成します。パイプをテストするには、パイプをインスタンス化し、transformメソッドを呼び出し、結果を検証します。

簡単な例として、Person オブジェクトを受け取り、名前をフォーマットするパイプを見てみましょう。簡単にするために、PersonidfirstNamelastName、および middleInitial で構成されているとしましょう。パイプの要件は、名、姓、ミドルイニシャルが存在しない状況を処理して、名前を「姓, 名 M.」として出力することです。このようなテストは次のようになる可能性があります。

import { NamePipe } from './name.pipe';

import { Person } from '../../models/person';

describe('NamePipe', () => {
let pipe: NamePipe;
let testPerson: Person;

beforeEach(() => {
pipe = new NamePipe();
testPerson = {
id: 42,
firstName: 'Douglas',
lastName: 'Adams',
middleInitial: 'N',
};
});

it('exists', () => {
expect(pipe).toBeTruthy();
});

it('formats a full name properly', () => {
expect(pipe.transform(testPerson)).toBeEqual('Adams, Douglas N.');
});

it('handles having no middle initial', () => {
delete testPerson.middleInitial;
expect(pipe.transform(testPerson)).toBeEqual('Adams, Douglas');
});

it('handles having no first name', () => {
delete testPerson.firstName;
expect(pipe.transform(testPerson)).toBeEqual('Adams N.');
});

it('handles having no last name', () => {
delete testPerson.lastName;
expect(pipe.transform(testPerson)).toBeEqual('Douglas N.');
});
});

パイプを使用するコンポーネントおよびページでDOMテストを介してパイプを実行することも有益です。

エンドツーエンドテスト

エンドツーエンドテストは、アプリケーション全体が動作することを検証するために使用され、多くの場合、ライブデータへの接続が含まれます。ユニットテストは、分離されたコードユニットに焦点を当て、アプリケーションロジックの低レベルテストを可能にするのに対し、エンドツーエンドテストはさまざまなユーザーストーリーまたは使用シナリオに焦点を当て、アプリケーションを介したデータフローの全体的な高レベルテストを提供します。ユニットテストはアプリケーションのロジックの問題を発見しようとするのに対し、エンドツーエンドテストは、これらの個々のユニットが一緒に使用されたときに発生する問題を検出しようとします。エンドツーエンドテストは、アプリケーションの全体的なアーキテクチャの問題を発見します。

エンドツーエンドテストは、ユーザーストーリーを実行し、個々のコードモジュールではなくアプリケーション全体をカバーするため、エンドツーエンドテストは、メインアプリケーション自体のコードとは別に、プロジェクト内の独自のアプリケーションに存在します。ほとんどのエンドツーエンドテストは、アプリケーションとの一般的なユーザーインタラクションを自動化し、DOMを調べてそれらのインタラクションの結果を判断することで動作します。

テスト構造

@ionic/angular アプリケーションが生成されると、デフォルトのエンドツーエンドテストアプリケーションが e2e フォルダーに生成されます。このアプリケーションは、ブラウザを制御するためにProtractorを使用し、テストを構造化および実行するためにJasmineを使用します。アプリケーションは、最初は4つのファイルで構成されています。

  • protractor.conf.js - Protractor構成ファイル
  • tsconfig.e2e.json - テストアプリケーションに固有のTypeScript構成
  • src/app.po.ts - アプリケーションをナビゲートし、DOM内の要素をクエリし、ページ上の要素を操作するメソッドを含むページオブジェクト
  • src/app.e2e-spec.ts - テストスクリプト

ページオブジェクト

エンドツーエンドテストは、アプリケーションとの一般的なユーザーインタラクションを自動化し、アプリケーションが応答するのを待ってから、DOMを調べてインタラクションの結果を判断することで動作します。これには、多くのDOM操作と調査が含まれます。これらすべてが手動で行われた場合、テストは非常に壊れやすく、読んだり保守したりするのが困難になります。

ページオブジェクトは、単一ページのHTMLをTypeScriptクラスにカプセル化し、テストスクリプトがアプリケーションと対話するために使用するAPIを提供します。ページオブジェクトでのDOM操作ロジックのカプセル化により、テストがより読みやすく、推論がはるかに容易になり、テストの保守コストが削減されます。適切に作成されたページオブジェクトを作成することが、高品質で保守可能なエンドツーエンドテストを作成するための鍵となります。

ベースページオブジェクト

多くのテストは、ページの表示を待ったり、テキストをインプットに入力したり、ボタンをクリックしたりするなどのアクションに依存しています。これを行うために使用されるメソッドは、適切なDOM要素を取得するために使用されるCSSセレクターのみが変更され、一貫性が保たれています。したがって、このロジックを他のページオブジェクトで使用できるベースクラスに抽象化することは理にかなっています。

これは、すべてのページオブジェクトがサポートする必要があるいくつかの基本的なメソッドを実装する例です。

import { browser, by, element, ExpectedConditions } from 'protractor';

export class PageObjectBase {
private path: string;
protected tag: string;

constructor(tag: string, path: string) {
this.tag = tag;
this.path = path;
}

load() {
return browser.get(this.path);
}

rootElement() {
return element(by.css(this.tag));
}

waitUntilInvisible() {
browser.wait(ExpectedConditions.invisibilityOf(this.rootElement()), 3000);
}

waitUntilPresent() {
browser.wait(ExpectedConditions.presenceOf(this.rootElement()), 3000);
}

waitUntilNotPresent() {
browser.wait(ExpectedConditions.not(ExpectedConditions.presenceOf(this.rootElement())), 3000);
}

waitUntilVisible() {
browser.wait(ExpectedConditions.visibilityOf(this.rootElement()), 3000);
}

getTitle() {
return element(by.css(`${this.tag} ion-title`)).getText();
}

protected enterInputText(sel: string, text: string) {
const el = element(by.css(`${this.tag} ${sel}`));
const inp = el.element(by.css('input'));
inp.sendKeys(text);
}

protected enterTextareaText(sel: string, text: string) {
const el = element(by.css(`${this.tag} ${sel}`));
const inp = el.element(by.css('textarea'));
inp.sendKeys(text);
}

protected clickButton(sel: string) {
const el = element(by.css(`${this.tag} ${sel}`));
browser.wait(ExpectedConditions.elementToBeClickable(el));
el.click();
}
}
ページごとの抽象化

アプリケーション内の各ページには、そのページの要素を抽象化する独自のページオブジェクトクラスがあります。ベースページオブジェクトクラスが使用されている場合、ページオブジェクトの作成には、そのページに固有の要素に対するカスタムメソッドを作成することがほとんど含まれます。多くの場合、これらのカスタム要素は、必要な作業を実行するために、ベースクラスのメソッドを利用します。

これは、シンプルだが典型的なログインページのページオブジェクトの例です。enterEMail() など、多くのメソッドが、作業の大部分を実行するベースクラスのメソッドを呼び出していることに注意してください。

import { browser, by, element, ExpectedConditions } from 'protractor';
import { PageObjectBase } from './base.po';

export class LoginPage extends PageObjectBase {
constructor() {
super('app-login', '/login');
}

waitForError() {
browser.wait(ExpectedConditions.presenceOf(element(by.css('.error'))), 3000);
}

getErrorMessage() {
return element(by.css('.error')).getText();
}

enterEMail(email: string) {
this.enterInputText('#email-input', email);
}

enterPassword(password: string) {
this.enterInputText('#password-input', password);
}

clickSignIn() {
this.clickButton('#signin-button');
}
}

テストスクリプト

ユニットテストと同様に、エンドツーエンドテストスクリプトは、ネストされた describe() および it() 関数で構成されます。エンドツーエンドテストの場合、describe() 関数は通常、特定のシナリオを示し、it() 関数は、そのシナリオ内でアクションが実行されたときにアプリケーションが示す必要がある特定の動作を示します。

また、ユニットテストと同様に、describe() および it() 関数で使用されるラベルは、「describe」または「it」の両方で意味を成し、結合して完全なテストケースを形成する必要があります。

これは、いくつかの典型的なログインシナリオを実行するサンプルエンドツーエンドテストスクリプトです。

import { AppPage } from '../page-objects/pages/app.po';
import { AboutPage } from '../page-objects/pages/about.po';
import { CustomersPage } from '../page-objects/pages/customers.po';
import { LoginPage } from '../page-objects/pages/login.po';
import { MenuPage } from '../page-objects/pages/menu.po';
import { TasksPage } from '../page-objects/pages/tasks.po';

describe('Login', () => {
const about = new AboutPage();
const app = new AppPage();
const customers = new CustomersPage();
const login = new LoginPage();
const menu = new MenuPage();
const tasks = new TasksPage();

beforeEach(() => {
app.load();
});

describe('before logged in', () => {
it('displays the login screen', () => {
expect(login.rootElement().isDisplayed()).toEqual(true);
});

it('allows in-app navigation to about', () => {
menu.clickAbout();
about.waitUntilVisible();
login.waitUntilInvisible();
});

it('does not allow in-app navigation to tasks', () => {
menu.clickTasks();
app.waitForPageNavigation();
expect(login.rootElement().isDisplayed()).toEqual(true);
});

it('does not allow in-app navigation to customers', () => {
menu.clickCustomers();
app.waitForPageNavigation();
expect(login.rootElement().isDisplayed()).toEqual(true);
});

it('displays an error message if the login fails', () => {
login.enterEMail('test@test.com');
login.enterPassword('bogus');
login.clickSignIn();
login.waitForError();
expect(login.getErrorMessage()).toEqual('The password is invalid or the user does not have a password.');
});

it('navigates to the tasks page if the login succeeds', () => {
login.enterEMail('test@test.com');
login.enterPassword('testtest');
login.clickSignIn();
tasks.waitUntilVisible();
});
});

describe('once logged in', () => {
beforeEach(() => {
tasks.waitUntilVisible();
});

it('allows navigation to the customers page', () => {
menu.clickCustomers();
customers.waitUntilVisible();
tasks.waitUntilInvisible();
});

it('allows navigation to the about page', () => {
menu.clickAbout();
about.waitUntilVisible();
tasks.waitUntilInvisible();
});

it('allows navigation back to the tasks page', () => {
menu.clickAbout();
tasks.waitUntilInvisible();
menu.clickTasks();
tasks.waitUntilVisible();
});
});
});

構成

デフォルトの構成では、開発に使用されるのと同じ environment.ts ファイルが使用されます。エンドツーエンドテストで使用されるデータをより適切に制御するために、多くの場合、テスト専用の環境を作成し、その環境をテストに使用することが役立ちます。このセクションでは、この構成を作成する1つの可能な方法を示します。

テスト環境

テスト環境のセットアップには、専用のテストバックエンドを使用する新しい環境ファイルの作成、その環境を使用するように angular.json ファイルの更新、および package.jsone2e スクリプトを test 環境を指定するように変更することが含まれます。

environment.e2e.ts ファイルの作成

Angular の environment.ts および environment.prod.ts ファイルは、アプリケーションのバックエンドデータサービスのベース URL などの情報を格納するためによく使用されます。開発または本番のバックエンドサービスではなく、テスト専用のバックエンドサービスにのみ接続する、同じ情報を提供する environment.e2e.ts を作成します。以下に例を示します。

export const environment = {
production: false,
databaseURL: 'https://e2e-test-api.my-great-app.com',
projectId: 'my-great-app-e2e',
};
angular.json ファイルの変更

このファイルを使用するように angular.json ファイルを変更する必要があります。これは段階的なプロセスです。下記にリストされている XPath に従って、必要な構成を追加してください。

ファイル置換を行う test という構成を /projects/app/architect/build/configurations に追加します。

"test": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.e2e.ts"
}
]
}

上記の定義した test ビルド構成をブラウザターゲットとする test という構成を /projects/app/architect/serve/configurations に追加します。

"test": {
"browserTarget": "app:build:test"
}

上記の定義した test サービス構成を開発サーバーターゲットとする test という構成を /projects/app-e2e/architect/e2e/configurations に追加します。

"test": {
"devServerTarget": "app:serve:test"
}
package.json ファイルの変更

npm run e2etest 構成を使用するように、package.json ファイルを変更します。

"scripts": {
"e2e": "ng e2e --configuration=test",
"lint": "ng lint",
"ng": "ng",
"start": "ng serve",
"test": "ng test",
"test:dev": "ng test --browsers=ChromeHeadlessCI",
"test:ci": "ng test --no-watch --browsers=ChromeHeadlessCI"
},

テストのクリーンアップ

エンドツーエンドテストが何らかの方法でデータを変更する場合、テスト完了後にデータを既知の状態にリセットすると役立ちます。そのための1つの方法は次のとおりです。

  1. クリーンアップを実行するエンドポイントを作成します。
  2. protractor.conf.js ファイルによってエクスポートされる config オブジェクトに onCleanUp() 関数を追加します。

以下に例を示します。

onCleanUp() {
const axios = require('axios');
return axios
.post(
'https://e2e-test-api.my-great-app.com/purgeDatabase',
{}
)
.then(res => {
console.log(res.data);
})
.catch(err => console.log(err));
}