diff --git a/adev-ja/src/content/guide/testing/component-harnesses-overview.en.md b/adev-ja/src/content/guide/testing/component-harnesses-overview.en.md new file mode 100644 index 0000000000..a1cc469c9d --- /dev/null +++ b/adev-ja/src/content/guide/testing/component-harnesses-overview.en.md @@ -0,0 +1,31 @@ +# Component harnesses overview + +A component harness is a class that allows tests to interact with components the way an end user does via a supported API. You can create test harnesses for any component, ranging from small reusable widgets to full pages. + +Harnesses offer several benefits: + +- They make tests less brittle by insulating themselves against implementation details of a component, such as its DOM structure +- They make tests become more readable and easier to maintain +- They can be used across multiple testing environments + + +// Example of test with a harness for a component called MyButtonComponent +it('should load button with exact text', async () => { + const button = await loader.getHarness(MyButtonComponentHarness); + expect(await button.getText()).toBe('Confirm'); +}); + + +Component harnesses are especially useful for shared UI widgets. Developers often write tests that depend on private implementation details of widgets, such as DOM structure and CSS classes. Those dependencies make tests brittle and hard to maintain. Harnesses offer an alternative— a supported API that interacts with the widget the same way an end-user does. Widget implementation changes now become less likely to break user tests. For example, [Angular Material](https://material.angular.dev/components/categories) provides a test harness for each component in the library. + +Component harnesses support multiple testing environments. You can use the same harness implementation in both unit and end-to-end tests. Test authors only need to learn one API and component authors don't have to maintain separate unit and end-to-end test implementations. + +Many developers can be categorized by one of the following developer type categories: test authors, component harness authors, and harness environment authors. Use the table below to find the most relevant section in this guide based on these categories: + +| Developer Type | Description | Relevant Section | +| :-------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------- | +| Test Authors | Developers that use component harnesses written by someone else to test their application. For example, this could be an app developer who uses a third-party menu component and needs to interact with the menu in a unit test. | [Using component harnesses in tests](guide/testing/using-component-harnesses) | +| Component harness authors | Developers who maintain some reusable Angular components and want to create a test harness for its users to use in their tests. For example, an author of a third party Angular component library or a developer who maintains a set of common components for a large Angular application. | [Creating component harnesses for your components](guide/testing/creating-component-harnesses) | +| Harness environment authors | Developers who want to add support for using component harnesses in additional testing environments. For information on supported testing environments out-of-the-box, see the [test harness environments and loaders](guide/testing/using-component-harnesses#test-harness-environments-and-loaders). | [Adding support for additional testing environments](guide/testing/component-harnesses-testing-environments) | + +For the full API reference, please see the [Angular CDK's component harness API reference page](/api#angular_cdk_testing). diff --git a/adev-ja/src/content/guide/testing/component-harnesses-overview.md b/adev-ja/src/content/guide/testing/component-harnesses-overview.md index a1cc469c9d..1ea8838c47 100644 --- a/adev-ja/src/content/guide/testing/component-harnesses-overview.md +++ b/adev-ja/src/content/guide/testing/component-harnesses-overview.md @@ -1,12 +1,12 @@ -# Component harnesses overview +# コンポーネントハーネスの概要 -A component harness is a class that allows tests to interact with components the way an end user does via a supported API. You can create test harnesses for any component, ranging from small reusable widgets to full pages. +コンポーネントハーネスは、テストがサポートされているAPIを介してエンドユーザーと同じ方法でコンポーネントと対話できるようにするクラスです。小さな再利用可能なウィジェットからフルページまで、あらゆるコンポーネントのテストハーネスを作成できます。 -Harnesses offer several benefits: +ハーネスにはいくつかの利点があります: -- They make tests less brittle by insulating themselves against implementation details of a component, such as its DOM structure -- They make tests become more readable and easier to maintain -- They can be used across multiple testing environments +- コンポーネントのDOM構造などの実装詳細から自身を隔離することで、テストの脆さを軽減します +- テストの可読性を高め、保守を容易にします +- 複数のテスト環境で使用できます // Example of test with a harness for a component called MyButtonComponent @@ -16,16 +16,16 @@ it('should load button with exact text', async () => { }); -Component harnesses are especially useful for shared UI widgets. Developers often write tests that depend on private implementation details of widgets, such as DOM structure and CSS classes. Those dependencies make tests brittle and hard to maintain. Harnesses offer an alternative— a supported API that interacts with the widget the same way an end-user does. Widget implementation changes now become less likely to break user tests. For example, [Angular Material](https://material.angular.dev/components/categories) provides a test harness for each component in the library. +コンポーネントハーネスは、共有UIウィジェットに特に役立ちます。開発者は、DOM構造やCSSクラスなど、ウィジェットのプライベートな実装詳細に依存するテストを記述することがよくあります。これらの依存関係はテストを脆くし、保守を困難にします。ハーネスは代替手段を提供します。それは、エンドユーザーと同じ方法でウィジェットと対話するサポートされたAPIです。ウィジェットの実装変更がユーザーテストを壊す可能性は低くなります。例えば、[Angular Material](https://material.angular.dev/components/categories)は、ライブラリ内の各コンポーネントにテストハーネスを提供しています。 -Component harnesses support multiple testing environments. You can use the same harness implementation in both unit and end-to-end tests. Test authors only need to learn one API and component authors don't have to maintain separate unit and end-to-end test implementations. +コンポーネントハーネスは複数のテスト環境をサポートしています。同じハーネス実装をユニットテストとエンドツーエンドテストの両方で使用できます。テスト作成者は1つのAPIを学ぶだけでよく、コンポーネント作成者は個別のユニットテストとエンドツーエンドテストの実装を保守する必要がありません。 -Many developers can be categorized by one of the following developer type categories: test authors, component harness authors, and harness environment authors. Use the table below to find the most relevant section in this guide based on these categories: +多くの開発者は、以下の開発者タイプカテゴリーのいずれかに分類できます: テスト作成者、コンポーネントハーネス作成者、ハーネス環境作成者。以下の表を使用して、これらのカテゴリーに基づいてこのガイドの最も関連性の高いセクションを見つけてください: -| Developer Type | Description | Relevant Section | -| :-------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------- | -| Test Authors | Developers that use component harnesses written by someone else to test their application. For example, this could be an app developer who uses a third-party menu component and needs to interact with the menu in a unit test. | [Using component harnesses in tests](guide/testing/using-component-harnesses) | -| Component harness authors | Developers who maintain some reusable Angular components and want to create a test harness for its users to use in their tests. For example, an author of a third party Angular component library or a developer who maintains a set of common components for a large Angular application. | [Creating component harnesses for your components](guide/testing/creating-component-harnesses) | -| Harness environment authors | Developers who want to add support for using component harnesses in additional testing environments. For information on supported testing environments out-of-the-box, see the [test harness environments and loaders](guide/testing/using-component-harnesses#test-harness-environments-and-loaders). | [Adding support for additional testing environments](guide/testing/component-harnesses-testing-environments) | +| 開発者タイプ | 説明 | 関連セクション | +| :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------- | +| テスト作成者 | 他の誰かが作成したコンポーネントハーネスを使用してアプリケーションをテストする開発者。例えば、サードパーティのメニューコンポーネントを使用し、ユニットテストでそのメニューと対話する必要があるアプリケーション開発者などがこれに該当します。 | [テストでのコンポーネントハーネスの使用](guide/testing/using-component-harnesses) | +| コンポーネントハーネス作成者 | 再利用可能なAngularコンポーネントを保守し、ユーザーがテストで使用するためのテストハーネスを作成したい開発者。例えば、サードパーティのAngularコンポーネントライブラリの作成者や、大規模なAngularアプリケーション向けに共通コンポーネントのセットを保守する開発者などがこれに該当します。 | [コンポーネントハーネスの作成](guide/testing/creating-component-harnesses) | +| ハーネス環境作成者 | 追加のテスト環境でコンポーネントハーネスを使用するためのサポートを追加したい開発者。すぐに利用できるサポートされているテスト環境については、[テストハーネス環境とローダー](guide/testing/using-component-harnesses#test-harness-environments-and-loaders)を参照してください。 | [テスト環境にハーネスサポートを追加する](guide/testing/component-harnesses-testing-environments) | -For the full API reference, please see the [Angular CDK's component harness API reference page](/api#angular_cdk_testing). +完全なAPIリファレンスについては、[Angular CDKのコンポーネントハーネスAPIリファレンスページ](/api#angular_cdk_testing)を参照してください。 diff --git a/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.en.md b/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.en.md new file mode 100644 index 0000000000..75fa6de3b0 --- /dev/null +++ b/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.en.md @@ -0,0 +1,62 @@ +# Adding harness support for additional testing environments + +## Before you start + +TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. + +### When does adding support for a test environment make sense? + +To use component harnesses in the following environments, you can use Angular CDK's two built-in environments: + +- Unit tests +- WebDriver end-to-end tests + +To use a supported testing environment, read the [Creating harnesses for your components guide](guide/testing/creating-component-harnesses). + +Otherwise, to add support for other environments, you need to define how to interact with a DOM element and how DOM interactions work in your environment. Continue reading to learn more. + +### CDK Installation + +The [Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: + + + ng add @angular/cdk + + +## Creating a `TestElement` implementation + +Every test environment must define a `TestElement` implementation. The `TestElement` interface serves as an environment-agnostic representation of a DOM element. It enables harnesses to interact with DOM elements regardless of the underlying environment. Because some environments don't support interacting with DOM elements synchronously (e.g. WebDriver), all `TestElement` methods are asynchronous, returning a `Promise` with the result of the operation. + +`TestElement` offers a number of methods to interact with the underlying DOM such as `blur()`, `click()`, `getAttribute()`, and more. See the [TestElement API reference page](/api/cdk/testing/TestElement) for the full list of methods. + +The `TestElement` interface consists largely of methods that resemble methods available on `HTMLElement`. Similar methods exist in most test environments, which makes implementing the methods fairly straightforward. However, one important difference to note when implementing the `sendKeys` method, is that the key codes in the `TestKey` enum likely differ from the key codes used in the test environment. Environment authors should maintain a mapping from `TestKey` codes to the codes used in the particular testing environment. + +The [UnitTestElement](/api/cdk/testing/testbed/UnitTestElement) and [SeleniumWebDriverElement](/api/cdk/testing/selenium-webdriver/SeleniumWebDriverElement) implementations in Angular CDK serve as good examples of implementations of this interface. + +## Creating a `HarnessEnvironment` implementation + +Test authors use `HarnessEnvironment` to create component harness instances for use in tests. `HarnessEnvironment` is an abstract class that must be extended to create a concrete subclass for the new environment. When supporting a new test environment, create a `HarnessEnvironment` subclass that adds concrete implementations for all abstract members. + +`HarnessEnvironment` has a generic type parameter: `HarnessEnvironment`. This parameter, `E`, represents the raw element type of the environment. For example, this parameter is Element for unit test environments. + +The following are the abstract methods that must be implemented: + +| Method | Description | +| :----------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `abstract getDocumentRoot(): E` | Gets the root element for the environment (e.g. `document.body`). | +| `abstract createTestElement(element: E): TestElement` | Creates a `TestElement` for the given raw element. | +| `abstract createEnvironment(element: E): HarnessEnvironment` | Creates a `HarnessEnvironment` rooted at the given raw element. | +| `abstract getAllRawElements(selector: string): Promise` | Gets all of the raw elements under the root element of the environment matching the given selector. | +| `abstract forceStabilize(): Promise` | Gets a `Promise` that resolves when the `NgZone` is stable. Additionally, if applicable, tells `NgZone` to stabilize (e.g. calling `flush()` in a `fakeAsync` test). | +| `abstract waitForTasksOutsideAngular(): Promise` | Gets a `Promise` that resolves when the parent zone of `NgZone` is stable. | + +In addition to implementing the missing methods, this class should provide a way for test authors to get `ComponentHarness` instances. You should define a protected constructor and provide a static method called `loader` that returns a `HarnessLoader` instance. This allows test authors to write code like: `SomeHarnessEnvironment.loader().getHarness(...)`. Depending on the needs of the particular environment, the class may provide several different static methods or require arguments to be passed. (e.g. the `loader` method on `TestbedHarnessEnvironment` takes a `ComponentFixture`, and the class provides additional static methods called `documentRootLoader` and `harnessForFixture`). + +The [`TestbedHarnessEnvironment`](/api/cdk/testing/testbed/TestbedHarnessEnvironment) and [SeleniumWebDriverHarnessEnvironment](/api/cdk/testing/selenium-webdriver/SeleniumWebDriverHarnessEnvironment) implementations in Angular CDK serve as good examples of implementations of this interface. + +## Handling auto change detection + +In order to support the `manualChangeDetection` and parallel APIs, your environment should install a handler for the auto change detection status. + +When your environment wants to start handling the auto change detection status it can call `handleAutoChangeDetectionStatus(handler)`. The handler function will receive a `AutoChangeDetectionStatus` which has two properties `isDisabled` and `onDetectChangesNow()`. See the [AutoChangeDetectionStatus API reference page](/api/cdk/testing/AutoChangeDetectionStatus) for more information. +If your environment wants to stop handling auto change detection status it can call `stopHandlingAutoChangeDetectionStatus()`. diff --git a/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md b/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md index 75fa6de3b0..92e39a3ff5 100644 --- a/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md +++ b/adev-ja/src/content/guide/testing/component-harnesses-testing-environments.md @@ -1,62 +1,62 @@ -# Adding harness support for additional testing environments +# テスト環境にハーネスサポートを追加する -## Before you start +## 始める前に {#before-you-start} -TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. +TIP: このガイドは、すでに[コンポーネントハーネスの概要ガイド](guide/testing/component-harnesses-overview)を読んでいることを前提としています。コンポーネントハーネスの使用が初めての場合は、まずそちらをお読みください。 -### When does adding support for a test environment make sense? +### テスト環境のサポートを追加するのはどのような場合ですか? {#when-does-adding-support-for-a-test-environment-make-sense} -To use component harnesses in the following environments, you can use Angular CDK's two built-in environments: +以下の環境でコンポーネントハーネスを使用するには、Angular CDKの2つの組み込み環境を使用できます。 -- Unit tests -- WebDriver end-to-end tests +- 単体テスト +- WebDriverエンドツーエンドテスト -To use a supported testing environment, read the [Creating harnesses for your components guide](guide/testing/creating-component-harnesses). +サポートされているテスト環境を使用するには、[コンポーネントのハーネスを作成するガイド](guide/testing/creating-component-harnesses)をお読みください。 -Otherwise, to add support for other environments, you need to define how to interact with a DOM element and how DOM interactions work in your environment. Continue reading to learn more. +それ以外の場合、他の環境のサポートを追加するには、DOM要素との対話方法と、その環境でDOMの対話がどのように機能するかを定義する必要があります。詳細については、引き続きお読みください。 -### CDK Installation +### CDKのインストール {#cdk-installation} -The [Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: +[Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories)は、コンポーネントを構築するための動作プリミティブのセットです。コンポーネントハーネスを使用するには、まずnpmから`@angular/cdk`をインストールします。これは、Angular CLIを使用してターミナルから実行できます。 ng add @angular/cdk -## Creating a `TestElement` implementation +TestElement実装の作成 {#creating-a-testelement-implementation} -Every test environment must define a `TestElement` implementation. The `TestElement` interface serves as an environment-agnostic representation of a DOM element. It enables harnesses to interact with DOM elements regardless of the underlying environment. Because some environments don't support interacting with DOM elements synchronously (e.g. WebDriver), all `TestElement` methods are asynchronous, returning a `Promise` with the result of the operation. +すべてのテスト環境は`TestElement`実装を定義する必要があります。`TestElement`インターフェースは、DOM要素の環境に依存しない表現の役割を果たします。これにより、ハーネスは基盤となる環境に関係なくDOM要素と対話できます。一部の環境ではDOM要素との同期的な対話がサポートされていないため(例: WebDriver)、すべての`TestElement`メソッドは非同期であり、操作の結果を`Promise`で返します。 -`TestElement` offers a number of methods to interact with the underlying DOM such as `blur()`, `click()`, `getAttribute()`, and more. See the [TestElement API reference page](/api/cdk/testing/TestElement) for the full list of methods. +`TestElement`は、`blur()`、`click()`、`getAttribute()`など、基盤であるDOMと対話するための多数のメソッドを提供します。メソッドの完全なリストについては、[TestElement APIリファレンスページ](/api/cdk/testing/TestElement)を参照してください。 -The `TestElement` interface consists largely of methods that resemble methods available on `HTMLElement`. Similar methods exist in most test environments, which makes implementing the methods fairly straightforward. However, one important difference to note when implementing the `sendKeys` method, is that the key codes in the `TestKey` enum likely differ from the key codes used in the test environment. Environment authors should maintain a mapping from `TestKey` codes to the codes used in the particular testing environment. +`TestElement`インターフェースは、主に`HTMLElement`で利用可能なメソッドに似たメソッドで構成されています。ほとんどのテスト環境には同様のメソッドが存在するため、それらのメソッドの実装は非常に簡単です。ただし、`sendKeys`メソッドを実装する際に注意すべき重要な違いは、`TestKey` enumのキーコードがテスト環境で使用されるキーコードと異なる可能性があることです。環境の作成者は、`TestKey`コードから特定のテスト環境で使用されるコードへのマッピングを維持する必要があります。 -The [UnitTestElement](/api/cdk/testing/testbed/UnitTestElement) and [SeleniumWebDriverElement](/api/cdk/testing/selenium-webdriver/SeleniumWebDriverElement) implementations in Angular CDK serve as good examples of implementations of this interface. +Angular CDKの[UnitTestElement](/api/cdk/testing/testbed/UnitTestElement)と[SeleniumWebDriverElement](/api/cdk/testing/selenium-webdriver/SeleniumWebDriverElement)の実装は、このインターフェースの実装の良い例として機能します。 -## Creating a `HarnessEnvironment` implementation +## `HarnessEnvironment`の実装を作成する {#creating-a-harnessenvironment-implementation} -Test authors use `HarnessEnvironment` to create component harness instances for use in tests. `HarnessEnvironment` is an abstract class that must be extended to create a concrete subclass for the new environment. When supporting a new test environment, create a `HarnessEnvironment` subclass that adds concrete implementations for all abstract members. +テスト作成者は、テストで使用するコンポーネントハーネスインスタンスを作成するために`HarnessEnvironment`を使用します。`HarnessEnvironment`は、新しい環境のための具象サブクラスを作成するために拡張されなければならない抽象クラスです。新しいテスト環境をサポートする場合、すべての抽象メンバーに具象実装を追加する`HarnessEnvironment`サブクラスを作成します。 -`HarnessEnvironment` has a generic type parameter: `HarnessEnvironment`. This parameter, `E`, represents the raw element type of the environment. For example, this parameter is Element for unit test environments. +`HarnessEnvironment`にはジェネリック型パラメータ`HarnessEnvironment`があります。このパラメータ`E`は、環境の生要素型を表します。例えば、このパラメータは単体テスト環境では`Element`です。 -The following are the abstract methods that must be implemented: +以下は、実装する必要がある抽象メソッドです。 | Method | Description | | :----------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `abstract getDocumentRoot(): E` | Gets the root element for the environment (e.g. `document.body`). | -| `abstract createTestElement(element: E): TestElement` | Creates a `TestElement` for the given raw element. | -| `abstract createEnvironment(element: E): HarnessEnvironment` | Creates a `HarnessEnvironment` rooted at the given raw element. | -| `abstract getAllRawElements(selector: string): Promise` | Gets all of the raw elements under the root element of the environment matching the given selector. | -| `abstract forceStabilize(): Promise` | Gets a `Promise` that resolves when the `NgZone` is stable. Additionally, if applicable, tells `NgZone` to stabilize (e.g. calling `flush()` in a `fakeAsync` test). | -| `abstract waitForTasksOutsideAngular(): Promise` | Gets a `Promise` that resolves when the parent zone of `NgZone` is stable. | +| `abstract getDocumentRoot(): E` | 環境のルート要素(例: `document.body`)を取得します。 | +| `abstract createTestElement(element: E): TestElement` | 指定された生要素の`TestElement`を作成します。 | +| `abstract createEnvironment(element: E): HarnessEnvironment` | 指定された生要素をルートとする`HarnessEnvironment`を作成します。 | +| `abstract getAllRawElements(selector: string): Promise` | 環境のルート要素の下にある、指定されたセレクターに一致するすべての生要素を取得します。 | +| `abstract forceStabilize(): Promise` | `NgZone`が安定したときに解決する`Promise`を取得します。さらに、該当する場合、`NgZone`に安定化を指示します(例: `fakeAsync`テストで`flush()`を呼び出す)。 | +| `abstract waitForTasksOutsideAngular(): Promise` | `NgZone`の親ゾーンが安定したときに解決する`Promise`を取得します。 | -In addition to implementing the missing methods, this class should provide a way for test authors to get `ComponentHarness` instances. You should define a protected constructor and provide a static method called `loader` that returns a `HarnessLoader` instance. This allows test authors to write code like: `SomeHarnessEnvironment.loader().getHarness(...)`. Depending on the needs of the particular environment, the class may provide several different static methods or require arguments to be passed. (e.g. the `loader` method on `TestbedHarnessEnvironment` takes a `ComponentFixture`, and the class provides additional static methods called `documentRootLoader` and `harnessForFixture`). +欠落しているメソッドを実装することに加えて、このクラスはテスト作成者が`ComponentHarness`インスタンスを取得する方法を提供する必要があります。保護されたコンストラクターを定義し、`HarnessLoader`インスタンスを返す`loader`という静的メソッドを提供する必要があります。これにより、テスト作成者は`SomeHarnessEnvironment.loader().getHarness(...)`のようなコードを記述できます。特定の環境のニーズに応じて、クラスはいくつかの異なる静的メソッドを提供したり、引数を渡すことを要求したりする場合があります。(例: `TestbedHarnessEnvironment`の`loader`メソッドは`ComponentFixture`を取り、クラスは`documentRootLoader`と`harnessForFixture`という追加の静的メソッドを提供します)。 -The [`TestbedHarnessEnvironment`](/api/cdk/testing/testbed/TestbedHarnessEnvironment) and [SeleniumWebDriverHarnessEnvironment](/api/cdk/testing/selenium-webdriver/SeleniumWebDriverHarnessEnvironment) implementations in Angular CDK serve as good examples of implementations of this interface. +Angular CDKの[`TestbedHarnessEnvironment`](/api/cdk/testing/testbed/TestbedHarnessEnvironment)と[SeleniumWebDriverHarnessEnvironment](/api/cdk/testing/selenium-webdriver/SeleniumWebDriverHarnessEnvironment)の実装は、このインターフェースの実装の良い例として役立ちます。 -## Handling auto change detection +## 自動での変更検知のハンドリング {#handling-auto-change-detection} -In order to support the `manualChangeDetection` and parallel APIs, your environment should install a handler for the auto change detection status. +`manualChangeDetection`と並列APIをサポートするために、お使いの環境は自動での変更検知ステータス用のハンドラーをインストールする必要があります。 -When your environment wants to start handling the auto change detection status it can call `handleAutoChangeDetectionStatus(handler)`. The handler function will receive a `AutoChangeDetectionStatus` which has two properties `isDisabled` and `onDetectChangesNow()`. See the [AutoChangeDetectionStatus API reference page](/api/cdk/testing/AutoChangeDetectionStatus) for more information. -If your environment wants to stop handling auto change detection status it can call `stopHandlingAutoChangeDetectionStatus()`. +お使いの環境が自動での変更検知ステータスのハンドリングを開始したい場合、`handleAutoChangeDetectionStatus(handler)`を呼び出すことができます。ハンドラー関数は、`isDisabled`と`onDetectChangesNow()`の2つのプロパティを持つ`AutoChangeDetectionStatus`を受け取ります。詳細については、[AutoChangeDetectionStatus APIリファレンスページ](/api/cdk/testing/AutoChangeDetectionStatus)を参照してください。 +お使いの環境が自動での変更検知ステータスのハンドリングを停止したい場合、`stopHandlingAutoChangeDetectionStatus()`を呼び出すことができます。 diff --git a/adev-ja/src/content/guide/testing/creating-component-harnesses.en.md b/adev-ja/src/content/guide/testing/creating-component-harnesses.en.md new file mode 100644 index 0000000000..622305abec --- /dev/null +++ b/adev-ja/src/content/guide/testing/creating-component-harnesses.en.md @@ -0,0 +1,277 @@ +# Creating harnesses for your components + +## Before you start + +TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. + +### When does creating a test harness make sense? + +The Angular team recommends creating component test harnesses for shared components that are used in many places and have some user interactivity. This most commonly applies to widget libraries and similar reusable components. Harnesses are valuable for these cases because they provide the consumers of these shared components a well- supported API for interacting with a component. Tests that use harnesses can avoid depending on unreliable implementation details of these shared components, such as DOM structure and specific event listeners. + +For components that appear in only one place, such as a page in an application, harnesses don't provide as much benefit. In these situations, a component's tests can reasonably depend on the implementation details of this component, as the tests and components are updated at the same time. However, harnesses still provide some value if you would use the harness in both unit and end-to-end tests. + +### CDK Installation + +The [Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: + + + ng add @angular/cdk + + +## Extending `ComponentHarness` + +The abstract `ComponentHarness` class is the base class for all component harnesses. To create a custom component harness, extend `ComponentHarness` and implement the static property `hostSelector`. + +The `hostSelector` property identifies elements in the DOM that match this harness subclass. In most cases, the `hostSelector` should be the same as the selector of the corresponding `Component` or `Directive`. For example, consider a simple popup component: + + +@Component({ + selector: 'my-popup', + template: ` + + @if (isOpen()) { +
+ } + ` +}) +class MyPopup { + triggerText = input(''); + + isOpen = signal(false); + + toggle() { + this.isOpen.update((value) => !value); + } +} +
+ +In this case, a minimal harness for the component would look like the following: + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; +} + + +While `ComponentHarness` subclasses require only the `hostSelector` property, most harnesses should also implement a static `with` method to generate `HarnessPredicate` instances. The [filtering harnesses section](guide/testing/using-component-harnesses#filtering-harnesses) covers this in more detail. + +## Finding elements in the component's DOM + +Each instance of a `ComponentHarness` subclass represents a particular instance of the corresponding component. You can access the component's host element via the `host() `method from the `ComponentHarness` base class. + +`ComponentHarness` also offers several methods for locating elements within the component's DOM. These methods are `locatorFor()`, `locatorForOptional()`, and `locatorForAll()`. These methods create functions that find elements, they do not directly find elements. This approach safeguards against caching references to out-of-date elements. For example, when an `@if` block hides and then shows an element, the result is a new DOM element; using functions ensures that tests always reference the current state of the DOM. + +See the [ComponentHarness API reference page](/api/cdk/testing/ComponentHarness) for the full list details of the different `locatorFor` methods. + +For example, the `MyPopupHarness` example discussed above could provide methods to get the trigger and content elements as follows: + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; + + // Gets the trigger element + getTriggerElement = this.locatorFor('button'); + + // Gets the content element. + getContentElement = this.locatorForOptional('.my-popup-content'); +} + + +## Working with `TestElement` instances + +`TestElement` is an abstraction designed to work across different test environments (Unit tests, WebDriver, etc). When using harnesses, you should perform all DOM interaction via this interface. Other means of accessing DOM elements, such as `document.querySelector()`, do not work in all test environments. + +`TestElement` has a number of methods to interact with the underlying DOM, such as `blur()`, `click()`, `getAttribute()`, and more. See the [TestElement API reference page](/api/cdk/testing/TestElement) for the full list of methods. + +Do not expose `TestElement` instances to harness users unless it's an element the component consumer defines directly, such as the component's host element. Exposing `TestElement` instances for internal elements leads users to depend on a component's internal DOM structure. + +Instead, provide more narrow-focused methods for specific actions the end-user may take or particular state they may observe. For example, `MyPopupHarness` from previous sections could provide methods like `toggle` and `isOpen`: + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; + + protected getTriggerElement = this.locatorFor('button'); + protected getContentElement = this.locatorForOptional('.my-popup-content'); + + /** Toggles the open state of the popup. */ + async toggle() { + const trigger = await this.getTriggerElement(); + return trigger.click(); + } + + /** Checks if the popup us open. */ + async isOpen() { + const content = await this.getContentElement(); + return !!content; + } +} + + +## Loading harnesses for subcomponents + +Larger components often compose sub-components. You can reflect this structure in a component's harness as well. Each of the `locatorFor` methods on `ComponentHarness` has an alternate signature that can be used for locating sub-harnesses rather than elements. + +See the [ComponentHarness API reference page](/api/cdk/testing/ComponentHarness) for the full list of the different locatorFor methods. + +For example, consider a menu build using the popup from above: + + +@Directive({ + selector: 'my-menu-item' +}) +class MyMenuItem {} + +@Component({ + selector: 'my-menu', + template: ` + + + + ` +}) +class MyMenu { + triggerText = input(''); + + @ContentChildren(MyMenuItem) items: QueryList; +} + + +The harness for `MyMenu` can then take advantage of other harnesses for `MyPopup` and `MyMenuItem`: + + +class MyMenuHarness extends ComponentHarness { + static hostSelector = 'my-menu'; + + protected getPopupHarness = this.locatorFor(MyPopupHarness); + + /** Gets the currently shown menu items (empty list if menu is closed). */ + getItems = this.locatorForAll(MyMenuItemHarness); + + /** Toggles open state of the menu. */ + async toggle() { + const popupHarness = await this.getPopupHarness(); + return popupHarness.toggle(); + } +} + +class MyMenuItemHarness extends ComponentHarness { + static hostSelector = 'my-menu-item'; +} + + +## Filtering harness instances with `HarnessPredicate` + +When a page contains multiple instances of a particular component, you may want to filter based on some property of the component to get a particular component instance. For example, you may want a button with some specific text, or a menu with a specific ID. The `HarnessPredicate` class can capture criteria like this for a `ComponentHarness` subclass. While the test author is able to construct `HarnessPredicate` instances manually, it's easier when the `ComponentHarness` subclass provides a helper method to construct predicates for common filters. + +You should create a static `with()` method on each `ComponentHarness` subclass that returns a `HarnessPredicate` for that class. This allows test authors to write easily understandable code, e.g. `loader.getHarness(MyMenuHarness.with({selector: '#menu1'}))`. In addition to the standard selector and ancestor options, the `with` method should add any other options that make sense for the particular subclass. + +Harnesses that need to add additional options should extend the `BaseHarnessFilters` interface and additional optional properties as needed. `HarnessPredicate` provides several convenience methods for adding options: `stringMatches()`, `addOption()`, and `add()`. See the [HarnessPredicate API page](/api/cdk/testing/HarnessPredicate) for the full description. + +For example, when working with a menu it is useful to filter based on trigger text and to filter menu items based on their text: + + +interface MyMenuHarnessFilters extends BaseHarnessFilters { + /** Filters based on the trigger text for the menu. */ + triggerText?: string | RegExp; +} + +interface MyMenuItemHarnessFilters extends BaseHarnessFilters { + /** Filters based on the text of the menu item. */ + text?: string | RegExp; +} + +class MyMenuHarness extends ComponentHarness { + static hostSelector = 'my-menu'; + + /** Creates a `HarnessPredicate` used to locate a particular `MyMenuHarness`. */ + static with(options: MyMenuHarnessFilters): HarnessPredicate { + return new HarnessPredicate(MyMenuHarness, options) + .addOption('trigger text', options.triggerText, + (harness, text) => HarnessPredicate.stringMatches(harness.getTriggerText(), text)); + } + + protected getPopupHarness = this.locatorFor(MyPopupHarness); + + /** Gets the text of the menu trigger. */ + async getTriggerText(): Promise { + const popupHarness = await this.getPopupHarness(); + return popupHarness.getTriggerText(); + } + ... +} + +class MyMenuItemHarness extends ComponentHarness { + static hostSelector = 'my-menu-item'; + + /** Creates a `HarnessPredicate` used to locate a particular `MyMenuItemHarness`. */ + static with(options: MyMenuItemHarnessFilters): HarnessPredicate { + return new HarnessPredicate(MyMenuItemHarness, options) + .addOption('text', options.text, + (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text)); + } + + /** Gets the text of the menu item. */ + async getText(): Promise { + const host = await this.host(); + return host.text(); + } +} + + +You can pass a `HarnessPredicate` instead of a `ComponentHarness` class to any of the APIs on `HarnessLoader`, `LocatorFactory`, or `ComponentHarness`. This allows test authors to easily target a particular component instance when creating a harness instance. It also allows the harness author to leverage the same `HarnessPredicate` to enable more powerful APIs on their harness class. For example, consider the `getItems` method on the `MyMenuHarness` shown above. Adding a filtering API allows users of the harness to search for particular menu items: + + +class MyMenuHarness extends ComponentHarness { + static hostSelector = 'my-menu'; + + /** Gets a list of items in the menu, optionally filtered based on the given criteria. */ + async getItems(filters: MyMenuItemHarnessFilters = {}): Promise { + const getFilteredItems = this.locatorForAll(MyMenuItemHarness.with(filters)); + return getFilteredItems(); + } + ... +} + + +## Creating `HarnessLoader` for elements that use content projection + +Some components project additional content into the component's template. See the [content projection guide](guide/components/content-projection) for more information. + +Add a `HarnessLoader` instance scoped to the element containing the `` when you create a harness for a component that uses content projection. This allows the user of the harness to load additional harnesses for whatever components were passed in as content. `ComponentHarness` has several methods that can be used to create HarnessLoader instances for cases like this: `harnessLoaderFor()`, `harnessLoaderForOptional()`, `harnessLoaderForAll()`. See the [HarnessLoader interface API reference page](/api/cdk/testing/HarnessLoader) for more details. + +For example, the `MyPopupHarness` example from above can extend `ContentContainerComponentHarness` to add support to load harnesses within the `` of the component. + + +class MyPopupHarness extends ContentContainerComponentHarness { + static hostSelector = 'my-popup'; +} + + +## Accessing elements outside of the component's host element + +There are times when a component harness might need to access elements outside of its corresponding component's host element. For example, code that displays a floating element or pop-up often attaches DOM elements directly to the document body, such as the `Overlay` service in Angular CDK. + +In this case, `ComponentHarness` provides a method that can be used to get a `LocatorFactory` for the root element of the document. The `LocatorFactory` supports most of the same APIs as the `ComponentHarness` base class, and can then be used to query relative to the document's root element. + +Consider if the `MyPopup` component above used the CDK overlay for the popup content, rather than an element in its own template. In this case, `MyPopupHarness` would have to access the content element via `documentRootLocatorFactory()` method that gets a locator factory rooted at the document root. + + +class MyPopupHarness extends ComponentHarness { + static hostSelector = 'my-popup'; + + /** Gets a `HarnessLoader` whose root element is the popup's content element. */ + async getHarnessLoaderForContent(): Promise { + const rootLocator = this.documentRootLocatorFactory(); + return rootLocator.harnessLoaderFor('my-popup-content'); + } +} + + +## Waiting for asynchronous tasks + +The methods on `TestElement` automatically trigger Angular's change detection and wait for tasks inside the `NgZone`. In most cases no special effort is required for harness authors to wait on asynchronous tasks. However, there are some edge cases where this may not be sufficient. + +Under some circumstances, Angular animations may require a second cycle of change detection and subsequent `NgZone` stabilization before animation events are fully flushed. In cases where this is needed, the `ComponentHarness` offers a `forceStabilize()` method that can be called to do the second round. + +You can use `NgZone.runOutsideAngular()` to schedule tasks outside of NgZone. Call the `waitForTasksOutsideAngular()` method on the corresponding harness if you need to explicitly wait for tasks outside `NgZone` since this does not happen automatically. diff --git a/adev-ja/src/content/guide/testing/creating-component-harnesses.md b/adev-ja/src/content/guide/testing/creating-component-harnesses.md index 622305abec..2d2e6ef91d 100644 --- a/adev-ja/src/content/guide/testing/creating-component-harnesses.md +++ b/adev-ja/src/content/guide/testing/creating-component-harnesses.md @@ -1,28 +1,28 @@ -# Creating harnesses for your components +# コンポーネントハーネスを作成する -## Before you start +## 始める前に {#before-you-start} -TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. +TIP: このガイドは、[コンポーネントハーネスの概要ガイド](guide/testing/component-harnesses-overview)をすでに読んでいることを前提としています。コンポーネントハーネスの使用が初めての場合は、まずそちらをお読みください。 -### When does creating a test harness make sense? +### テストハーネスの作成はどのような場合に意味がありますか? {#when-does-creating-a-test-harness-make-sense} -The Angular team recommends creating component test harnesses for shared components that are used in many places and have some user interactivity. This most commonly applies to widget libraries and similar reusable components. Harnesses are valuable for these cases because they provide the consumers of these shared components a well- supported API for interacting with a component. Tests that use harnesses can avoid depending on unreliable implementation details of these shared components, such as DOM structure and specific event listeners. +Angularチームは、多くの場所で使用され、ユーザーインタラクティビティを持つ共有コンポーネントに対して、コンポーネントテストハーネスを作成することを推奨しています。これはウィジェットライブラリや同様の再利用可能なコンポーネントに最も一般的に適用されます。ハーネスは、これらの共有コンポーネントの利用者に、コンポーネントと対話するための十分にサポートされたAPIを提供するため、これらのケースで価値があります。ハーネスを使用するテストは、DOM構造や特定のイベントリスナーなど、これらの共有コンポーネントの信頼性の低い実装詳細に依存することを避けることができます。 -For components that appear in only one place, such as a page in an application, harnesses don't provide as much benefit. In these situations, a component's tests can reasonably depend on the implementation details of this component, as the tests and components are updated at the same time. However, harnesses still provide some value if you would use the harness in both unit and end-to-end tests. +アプリケーション内のページなど、1か所にのみ出現するコンポーネントの場合、ハーネスはそれほど多くの利点を提供しません。このような状況では、テストとコンポーネントが同時に更新されるため、コンポーネントのテストは、そのコンポーネントの実装詳細に合理的に依存できます。ただし、ユニットテストとエンドツーエンドテストの両方でハーネスを使用する場合、ハーネスは依然としていくつかの価値を提供します。 -### CDK Installation +### CDKのインストール {#cdk-installation} -The [Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: +[Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories)は、コンポーネントを構築するための動作プリミティブのセットです。コンポーネントハーネスを使用するには、まずnpmから`@angular/cdk`をインストールします。これは、Angular CLIを使用してターミナルから実行できます。 ng add @angular/cdk -## Extending `ComponentHarness` +## ComponentHarnessの拡張 {#extending-componentharness} -The abstract `ComponentHarness` class is the base class for all component harnesses. To create a custom component harness, extend `ComponentHarness` and implement the static property `hostSelector`. +抽象クラス`ComponentHarness`は、すべてのコンポーネントハーネスの基底クラスです。カスタムコンポーネントハーネスを作成するには、`ComponentHarness`を拡張し、静的プロパティ`hostSelector`を実装します。 -The `hostSelector` property identifies elements in the DOM that match this harness subclass. In most cases, the `hostSelector` should be the same as the selector of the corresponding `Component` or `Directive`. For example, consider a simple popup component: +`hostSelector`プロパティは、このハーネスサブクラスに一致するDOM内の要素を識別します。ほとんどの場合、`hostSelector`は対応する`Component`または`Directive`のセレクターと同じである必要があります。例えば、シンプルなポップアップコンポーネントを考えてみましょう。 @Component({ @@ -45,7 +45,7 @@ class MyPopup { } -In this case, a minimal harness for the component would look like the following: +この場合、コンポーネントの最小限のハーネスは次のようになります。 class MyPopupHarness extends ComponentHarness { @@ -53,17 +53,17 @@ class MyPopupHarness extends ComponentHarness { } -While `ComponentHarness` subclasses require only the `hostSelector` property, most harnesses should also implement a static `with` method to generate `HarnessPredicate` instances. The [filtering harnesses section](guide/testing/using-component-harnesses#filtering-harnesses) covers this in more detail. +`ComponentHarness`のサブクラスは`hostSelector`プロパティのみを必要としますが、ほとんどのハーネスは`HarnessPredicate`インスタンスを生成するために静的な`with`メソッドも実装する必要があります。[ハーネスのフィルタリングセクション](guide/testing/using-component-harnesses#filtering-harnesses)で、これについて詳しく説明しています。 -## Finding elements in the component's DOM +## コンポーネントのDOM内の要素を見つける {#finding-elements-in-the-component's-dom} -Each instance of a `ComponentHarness` subclass represents a particular instance of the corresponding component. You can access the component's host element via the `host() `method from the `ComponentHarness` base class. +`ComponentHarness`サブクラスの各インスタンスは、対応するコンポーネントの特定のインスタンスを表します。`ComponentHarness`基底クラスの`host()`メソッドを介して、コンポーネントのホスト要素にアクセスできます。 -`ComponentHarness` also offers several methods for locating elements within the component's DOM. These methods are `locatorFor()`, `locatorForOptional()`, and `locatorForAll()`. These methods create functions that find elements, they do not directly find elements. This approach safeguards against caching references to out-of-date elements. For example, when an `@if` block hides and then shows an element, the result is a new DOM element; using functions ensures that tests always reference the current state of the DOM. +`ComponentHarness`は、コンポーネントのDOM内で要素を見つけるためのいくつかのメソッドも提供します。これらのメソッドは、`locatorFor()`、`locatorForOptional()`、および`locatorForAll()`です。これらのメソッドは要素を見つける関数を作成し、直接要素を見つけるわけではありません。このアプローチにより、古い要素への参照がキャッシュされるのを防ぎます。たとえば、`@if`ブロックが要素を非表示にしてから表示する場合、結果は新しいDOM要素になります。関数を使用することで、テストは常にDOMの現在の状態を参照するようになります。 -See the [ComponentHarness API reference page](/api/cdk/testing/ComponentHarness) for the full list details of the different `locatorFor` methods. +さまざまな`locatorFor`メソッドの完全な詳細については、[ComponentHarness APIリファレンスページ](/api/cdk/testing/ComponentHarness)を参照してください。 -For example, the `MyPopupHarness` example discussed above could provide methods to get the trigger and content elements as follows: +たとえば、上記の`MyPopupHarness`の例では、トリガー要素とコンテンツ要素を取得するメソッドを次のように提供できます。 class MyPopupHarness extends ComponentHarness { @@ -77,15 +77,15 @@ class MyPopupHarness extends ComponentHarness { } -## Working with `TestElement` instances +## TestElementインスタンスの操作 {#working-with-testelement-instances} -`TestElement` is an abstraction designed to work across different test environments (Unit tests, WebDriver, etc). When using harnesses, you should perform all DOM interaction via this interface. Other means of accessing DOM elements, such as `document.querySelector()`, do not work in all test environments. +`TestElement`は、さまざまなテスト環境(Unit tests, WebDriverなど)で動作するように設計された抽象化です。ハーネスを使用する場合、すべてのDOM操作はこのインターフェースを介して実行する必要があります。`document.querySelector()`のようなDOM要素にアクセスする他の手段は、すべてのテスト環境で機能するわけではありません。 -`TestElement` has a number of methods to interact with the underlying DOM, such as `blur()`, `click()`, `getAttribute()`, and more. See the [TestElement API reference page](/api/cdk/testing/TestElement) for the full list of methods. +`TestElement`には、`blur()`、`click()`、`getAttribute()`など、基になるDOMと対話するための多数のメソッドがあります。メソッドの完全なリストについては、[TestElement API reference page](/api/cdk/testing/TestElement)を参照してください。 -Do not expose `TestElement` instances to harness users unless it's an element the component consumer defines directly, such as the component's host element. Exposing `TestElement` instances for internal elements leads users to depend on a component's internal DOM structure. +`TestElement`インスタンスをハーネスユーザーに公開しないでください。ただし、コンポーネントのコンシューマーが直接定義する要素(コンポーネントのホスト要素など)である場合は除きます。内部要素に対して`TestElement`インスタンスを公開すると、ユーザーがコンポーネントの内部DOM構造に依存することになります。 -Instead, provide more narrow-focused methods for specific actions the end-user may take or particular state they may observe. For example, `MyPopupHarness` from previous sections could provide methods like `toggle` and `isOpen`: +代わりに、エンドユーザーが実行する可能性のある特定のアクションや、観察する可能性のある特定の状態に対して、より焦点を絞ったメソッドを提供してください。たとえば、以前のセクションの`MyPopupHarness`は、`toggle`や`isOpen`のようなメソッドを提供できます。 class MyPopupHarness extends ComponentHarness { @@ -108,13 +108,13 @@ class MyPopupHarness extends ComponentHarness { } -## Loading harnesses for subcomponents +## サブコンポーネントのハーネスのロード {#loading-harnesses-for-subcomponents} -Larger components often compose sub-components. You can reflect this structure in a component's harness as well. Each of the `locatorFor` methods on `ComponentHarness` has an alternate signature that can be used for locating sub-harnesses rather than elements. +より大きなコンポーネントは、しばしばサブコンポーネントで構成されます。この構造は、コンポーネントのハーネスにも反映できます。`ComponentHarness`の各`locatorFor`メソッドには、要素ではなくサブハーネスを特定するために使用できる代替シグネチャがあります。 -See the [ComponentHarness API reference page](/api/cdk/testing/ComponentHarness) for the full list of the different locatorFor methods. +異なるlocatorForメソッドの完全なリストについては、[ComponentHarness APIリファレンスページ](/api/cdk/testing/ComponentHarness)を参照してください。 -For example, consider a menu build using the popup from above: +例えば、上記ポップアップを使用して構築されたメニューを考えてみましょう。 @Directive({ @@ -137,7 +137,7 @@ class MyMenu { } -The harness for `MyMenu` can then take advantage of other harnesses for `MyPopup` and `MyMenuItem`: +これにより、`MyMenu`のハーネスは、`MyPopup`および`MyMenuItem`の他のハーネスを利用できます。 class MyMenuHarness extends ComponentHarness { @@ -160,15 +160,15 @@ class MyMenuItemHarness extends ComponentHarness { } -## Filtering harness instances with `HarnessPredicate` +## HarnessPredicateによるハーネスインスタンスのフィルタリング {#filtering-harness-instances-with-harnesspredicate} -When a page contains multiple instances of a particular component, you may want to filter based on some property of the component to get a particular component instance. For example, you may want a button with some specific text, or a menu with a specific ID. The `HarnessPredicate` class can capture criteria like this for a `ComponentHarness` subclass. While the test author is able to construct `HarnessPredicate` instances manually, it's easier when the `ComponentHarness` subclass provides a helper method to construct predicates for common filters. +ページに特定のコンポーネントの複数のインスタンスが含まれている場合、特定のコンポーネントインスタンスを取得するために、コンポーネントの何らかのプロパティに基づいてフィルタリングしたい場合があります。例えば、特定のテキストを持つボタンや、特定のIDを持つメニューが必要になるかもしれません。`HarnessPredicate`クラスは、`ComponentHarness`サブクラスに対してこのような条件を捕捉できます。テスト作成者が`HarnessPredicate`インスタンスを手動で構築できますが、`ComponentHarness`サブクラスが一般的なフィルター用の述語を構築するヘルパーメソッドを提供すると、より簡単になります。 -You should create a static `with()` method on each `ComponentHarness` subclass that returns a `HarnessPredicate` for that class. This allows test authors to write easily understandable code, e.g. `loader.getHarness(MyMenuHarness.with({selector: '#menu1'}))`. In addition to the standard selector and ancestor options, the `with` method should add any other options that make sense for the particular subclass. +各`ComponentHarness`サブクラスに、そのクラスの`HarnessPredicate`を返す静的`with()`メソッドを作成する必要があります。これにより、テスト作成者は`loader.getHarness(MyMenuHarness.with({selector: '#menu1'}))`のような、理解しやすいコードを書くことができます。標準セレクターと祖先オプションに加えて、`with`メソッドは、特定のサブクラスに意味のある他のオプションを追加する必要があります。 -Harnesses that need to add additional options should extend the `BaseHarnessFilters` interface and additional optional properties as needed. `HarnessPredicate` provides several convenience methods for adding options: `stringMatches()`, `addOption()`, and `add()`. See the [HarnessPredicate API page](/api/cdk/testing/HarnessPredicate) for the full description. +追加オプションを追加する必要があるハーネスは、`BaseHarnessFilters`インターフェースを拡張し、必要に応じて追加のオプションプロパティを追加する必要があります。`HarnessPredicate`は、オプションを追加するためのいくつかの便利なメソッドを提供します: `stringMatches()`、`addOption()`、および`add()`。詳細については、[HarnessPredicate APIページ](/api/cdk/testing/HarnessPredicate)を参照してください。 -For example, when working with a menu it is useful to filter based on trigger text and to filter menu items based on their text: +例えば、メニューを操作する場合、トリガーテキストに基づいてフィルタリングしたり、メニュー項目をそのテキストに基づいてフィルタリングしたりすると便利です。 interface MyMenuHarnessFilters extends BaseHarnessFilters { @@ -219,7 +219,7 @@ class MyMenuItemHarness extends ComponentHarness { } -You can pass a `HarnessPredicate` instead of a `ComponentHarness` class to any of the APIs on `HarnessLoader`, `LocatorFactory`, or `ComponentHarness`. This allows test authors to easily target a particular component instance when creating a harness instance. It also allows the harness author to leverage the same `HarnessPredicate` to enable more powerful APIs on their harness class. For example, consider the `getItems` method on the `MyMenuHarness` shown above. Adding a filtering API allows users of the harness to search for particular menu items: +`HarnessLoader`、`LocatorFactory`、または`ComponentHarness`のいずれかのAPIに、`ComponentHarness`クラスの代わりに`HarnessPredicate`を渡すことができます。これにより、テスト作成者はハーネスインスタンスを作成する際に、特定のコンポーネントインスタンスを簡単にターゲットにできます。また、ハーネス作成者は同じ`HarnessPredicate`を活用して、ハーネスクラスでより強力なAPIを有効にできます。例えば、上記の`MyMenuHarness`の`getItems`メソッドを考えてみましょう。フィルタリングAPIを追加することで、ハーネスのユーザーは特定のメニュー項目を検索できるようになります。 class MyMenuHarness extends ComponentHarness { @@ -234,13 +234,13 @@ class MyMenuHarness extends ComponentHarness { } -## Creating `HarnessLoader` for elements that use content projection +## コンテンツプロジェクションを使用する要素のための`HarnessLoader`の作成 {#creating-harnessloader-for-elements-that-use-content-projection} -Some components project additional content into the component's template. See the [content projection guide](guide/components/content-projection) for more information. +一部のコンポーネントは、追加のコンテンツをコンポーネントのテンプレートに投影します。詳細については、[コンテンツプロジェクションガイド](guide/components/content-projection)を参照してください。 -Add a `HarnessLoader` instance scoped to the element containing the `` when you create a harness for a component that uses content projection. This allows the user of the harness to load additional harnesses for whatever components were passed in as content. `ComponentHarness` has several methods that can be used to create HarnessLoader instances for cases like this: `harnessLoaderFor()`, `harnessLoaderForOptional()`, `harnessLoaderForAll()`. See the [HarnessLoader interface API reference page](/api/cdk/testing/HarnessLoader) for more details. +コンテンツプロジェクションを使用するコンポーネントのハーネスを作成する際には、``を含む要素にスコープされた`HarnessLoader`インスタンスを追加します。これにより、ハーネスのユーザーは、コンテンツとして渡されたコンポーネントのために追加のハーネスをロードできます。`ComponentHarness`には、このような場合に`HarnessLoader`インスタンスを作成するために使用できるいくつかのメソッドがあります:`harnessLoaderFor()`、`harnessLoaderForOptional()`、`harnessLoaderForAll()`。詳細については、[HarnessLoaderインターフェースAPIリファレンスページ](/api/cdk/testing/HarnessLoader)を参照してください。 -For example, the `MyPopupHarness` example from above can extend `ContentContainerComponentHarness` to add support to load harnesses within the `` of the component. +例えば、上記の`MyPopupHarness`の例は、コンポーネントの``内でハーネスをロードするサポートを追加するために、`ContentContainerComponentHarness`を拡張できます。 class MyPopupHarness extends ContentContainerComponentHarness { @@ -248,13 +248,13 @@ class MyPopupHarness extends ContentContainerComponentHarness { } -## Accessing elements outside of the component's host element +## コンポーネントのホスト要素外の要素へのアクセス {#accessing-elements-outside-of-the-component's-host-element} -There are times when a component harness might need to access elements outside of its corresponding component's host element. For example, code that displays a floating element or pop-up often attaches DOM elements directly to the document body, such as the `Overlay` service in Angular CDK. +コンポーネントハーネスが、対応するコンポーネントのホスト要素外の要素にアクセスする必要がある場合があります。たとえば、フローティング要素やポップアップを表示するコードは、Angular CDKの`Overlay`サービスのように、DOM要素をドキュメントボディに直接アタッチすることがよくあります。 -In this case, `ComponentHarness` provides a method that can be used to get a `LocatorFactory` for the root element of the document. The `LocatorFactory` supports most of the same APIs as the `ComponentHarness` base class, and can then be used to query relative to the document's root element. +この場合、`ComponentHarness`は、ドキュメントのルート要素の`LocatorFactory`を取得するために使用できるメソッドを提供します。`LocatorFactory`は、`ComponentHarness`基底クラスとほとんど同じAPIをサポートしており、ドキュメントのルート要素を基準にクエリするために使用できます。 -Consider if the `MyPopup` component above used the CDK overlay for the popup content, rather than an element in its own template. In this case, `MyPopupHarness` would have to access the content element via `documentRootLocatorFactory()` method that gets a locator factory rooted at the document root. +上記の`MyPopup`コンポーネントが、自身のテンプレート内の要素ではなく、ポップアップコンテンツにCDKオーバーレイを使用した場合を考えてみましょう。この場合、`MyPopupHarness`は、ドキュメントルートにルートを持つロケーターファクトリを取得する`documentRootLocatorFactory()`メソッドを介してコンテンツ要素にアクセスする必要があります。 class MyPopupHarness extends ComponentHarness { @@ -268,10 +268,10 @@ class MyPopupHarness extends ComponentHarness { } -## Waiting for asynchronous tasks +## 非同期タスクの待機 {#waiting-for-asynchronous-tasks} -The methods on `TestElement` automatically trigger Angular's change detection and wait for tasks inside the `NgZone`. In most cases no special effort is required for harness authors to wait on asynchronous tasks. However, there are some edge cases where this may not be sufficient. +`TestElement`のメソッドは、Angularの変更検知を自動的にトリガーし、`NgZone`内のタスクを待機します。ほとんどの場合、ハーネスの作成者が非同期タスクを待機するために特別な努力は必要ありません。しかし、これが十分でないエッジケースがいくつかあります。 -Under some circumstances, Angular animations may require a second cycle of change detection and subsequent `NgZone` stabilization before animation events are fully flushed. In cases where this is needed, the `ComponentHarness` offers a `forceStabilize()` method that can be called to do the second round. +特定の状況下では、Angularアニメーションは、アニメーションイベントが完全にフラッシュされる前に、変更検知の2回目のサイクルとそれに続く`NgZone`の安定化を必要とする場合があります。これが必要な場合、`ComponentHarness`は2回目の処理を行うために呼び出すことができる`forceStabilize()`メソッドを提供します。 -You can use `NgZone.runOutsideAngular()` to schedule tasks outside of NgZone. Call the `waitForTasksOutsideAngular()` method on the corresponding harness if you need to explicitly wait for tasks outside `NgZone` since this does not happen automatically. +`NgZone.runOutsideAngular()`を使用して、NgZone外でタスクをスケジュールできます。自動的に行われないため、`NgZone`外のタスクを明示的に待機する必要がある場合は、対応するハーネスで`waitForTasksOutsideAngular()`メソッドを呼び出してください。 diff --git a/adev-ja/src/content/guide/testing/using-component-harnesses.en.md b/adev-ja/src/content/guide/testing/using-component-harnesses.en.md new file mode 100644 index 0000000000..5873913d5f --- /dev/null +++ b/adev-ja/src/content/guide/testing/using-component-harnesses.en.md @@ -0,0 +1,214 @@ +# Using component harnesses in tests + +## Before you start + +TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. + +### CDK Installation + +The [Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: + + + ng add @angular/cdk + + +## Test harness environments and loaders + +You can use component test harnesses in different test environments. Angular CDK supports two built-in environments: + +- Unit tests with Angular's `TestBed` +- End-to-end tests with [WebDriver](https://developer.mozilla.org/en-US/docs/Web/WebDriver) + +Each environment provides a harness loader. The loader creates the harness instances you use throughout your tests. See below for more specific guidance on supported testing environments. + +Additional testing environments require custom bindings. See the [adding harness support for additional testing environments guide](guide/testing/component-harnesses-testing-environments) for more information. + +### Using the loader from `TestbedHarnessEnvironment` for unit tests + +For unit tests you can create a harness loader from [TestbedHarnessEnvironment](/api/cdk/testing/TestbedHarnessEnvironment). This environment uses a [component fixture](api/core/testing/ComponentFixture) created by Angular's `TestBed`. + +To create a harness loader rooted at the fixture's root element, use the `loader()` method: + + +const fixture = TestBed.createComponent(MyComponent); + +// Create a harness loader from the fixture +const loader = TestbedHarnessEnvironment.loader(fixture); +... + +// Use the loader to get harness instances +const myComponentHarness = await loader.getHarness(MyComponent); + + +To create a harness loader for harnesses for elements that fall outside the fixture, use the `documentRootLoader()` method. For example, code that displays a floating element or pop-up often attaches DOM elements directly to the document body, such as the `Overlay` service in Angular CDK. + +You can also create a harness loader directly with `harnessForFixture()` for a harness at that fixture's root element directly. + +### Using the loader from `SeleniumWebDriverHarnessEnvironment` for end-to-end tests + +For WebDriver-based end-to-end tests you can create a harness loader with `SeleniumWebDriverHarnessEnvironment`. + +Use the `loader()` method to get the harness loader instance for the current HTML document, rooted at the document's root element. This environment uses a WebDriver client. + + +let wd: webdriver.WebDriver = getMyWebDriverClient(); +const loader = SeleniumWebDriverHarnessEnvironment.loader(wd); +... +const myComponentHarness = await loader.getHarness(MyComponent); + + +## Using a harness loader + +Harness loader instances correspond to a specific DOM element and are used to create component harness instances for elements under that specific element. + +To get `ComponentHarness` for the first instance of the element, use the `getHarness()` method. To get all `ComponentHarness` instances, use the `getAllHarnesses()` method. + + +// Get harness for first instance of the element +const myComponentHarness = await loader.getHarness(MyComponent); + +// Get harnesses for all instances of the element +const myComponentHarnesses = await loader.getHarnesses(MyComponent); + + +As an example, consider a reusable dialog-button component that opens a dialog on click. It contains the following components, each with a corresponding harness: + +- `MyDialogButton` (composes the `MyButton` and `MyDialog` with a convenient API) +- `MyButton` (a standard button component) +- `MyDialog` (a dialog appended to `document.body` by `MyDialogButton` upon click) + +The following test loads harnesses for each of these components: + + +let fixture: ComponentFixture; +let loader: HarnessLoader; +let rootLoader: HarnessLoader; + +beforeEach(() => { + fixture = TestBed.createComponent(MyDialogButton); + loader = TestbedHarnessEnvironment.loader(fixture); + rootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture); +}); + +it('loads harnesses', async () => { + // Load a harness for the bootstrapped component with `harnessForFixture` + dialogButtonHarness = + await TestbedHarnessEnvironment.harnessForFixture(fixture, MyDialogButtonHarness); + + // The button element is inside the fixture's root element, so we use `loader`. + const buttonHarness = await loader.getHarness(MyButtonHarness); + + // Click the button to open the dialog + await buttonHarness.click(); + + // The dialog is appended to `document.body`, outside of the fixture's root element, + // so we use `rootLoader` in this case. + const dialogHarness = await rootLoader.getHarness(MyDialogHarness); + + // ... make some assertions +}); + + +### Harness behavior in different environments + +Harnesses may not behave exactly the same in all environments. Some differences are unavoidable between the real user interaction versus the simulated events generated in unit tests. Angular CDK makes a best effort to normalize the behavior to the extent possible. + +### Interacting with child elements + +To interact with elements below the root element of this harness loader, use the `HarnessLoader` instance of a child element. For the first instance of the child element, use the `getChildLoader()` method. For all instances of the child element, use the `getAllChildLoaders()` method. + + +const myComponentHarness = await loader.getHarness(MyComponent); + +// Get loader for first instance of child element with '.child' selector +const childLoader = await myComponentHarness.getLoader('.child'); + +// Get loaders for all instances of child elements with '.child' selector +const allChildLoaders = await myComponentHarness.getAllChildLoaders('.child'); + + +### Filtering harnesses + +When a page contains multiple instances of a particular component, you may want to filter based on some property of the component to get a particular component instance. You can use a harness predicate, a class used to associate a `ComponentHarness` class with predicates functions that can be used to filter component instances, to do so. + +When you ask a `HarnessLoader` for a harness, you're actually providing a HarnessQuery. A query can be one of two things: + +- A harness constructor. This just gets that harness +- A `HarnessPredicate`, which gets harnesses that are filtered based on one or more conditions + +`HarnessPredicate` does support some base filters (selector, ancestor) that work on anything that extends `ComponentHarness`. + + +// Example of loading a MyButtonComponentHarness with a harness predicate +const disabledButtonPredicate = new HarnessPredicate(MyButtonComponentHarness, {selector: '[disabled]'}); +const disabledButton = await loader.getHarness(disabledButtonPredicate); + + +However it's common for harnesses to implement a static `with()` method that accepts component-specific filtering options and returns a `HarnessPredicate`. + + +// Example of loading a MyButtonComponentHarness with a specific selector +const button = await loader.getHarness(MyButtonComponentHarness.with({selector: 'btn'})) + + +For more details refer to the specific harness documentation since additional filtering options are specific to each harness implementation. + +## Using test harness APIs + +While every harness defines an API specific to its corresponding component, they all share a common base class, [ComponentHarness](/api/cdk/testing/ComponentHarness). This base class defines a static property, `hostSelector`, that matches the harness class to instances of the component in the DOM. + +Beyond that, the API of any given harness is specific to its corresponding component; refer to the component's documentation to learn how to use a specific harness. + +As an example, the following is a test for a component that uses the [Angular Material slider component harness](https://material.angular.dev/components/slider/api#MatSliderHarness): + + +it('should get value of slider thumb', async () => { + const slider = await loader.getHarness(MatSliderHarness); + const thumb = await slider.getEndThumb(); + expect(await thumb.getValue()).toBe(50); +}); + + +## Interop with Angular change detection + +By default, test harnesses runs Angular's [change detection](https://angular.dev/best-practices/runtime-performance) before reading the state of a DOM element and after interacting with a DOM element. + +There may be times that you need finer-grained control over change detection in your tests. such as checking the state of a component while an async operation is pending. In these cases use the `manualChangeDetection` function to disable automatic handling of change detection for a block of code. + + +it('checks state while async action is in progress', async () => { + const buttonHarness = loader.getHarness(MyButtonHarness); + await manualChangeDetection(async () => { + await buttonHarness.click(); + fixture.detectChanges(); + // Check expectations while async click operation is in progress. + expect(isProgressSpinnerVisible()).toBe(true); + await fixture.whenStable(); + // Check expectations after async click operation complete. + expect(isProgressSpinnerVisible()).toBe(false); + }); +}); + + +Almost all harness methods are asynchronous and return a `Promise` to support the following: + +- Support for unit tests +- Support for end-to-end tests +- Insulate tests against changes in asynchronous behavior + +The Angular team recommends using [await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) to improve the test readability. Calling `await` blocks the execution of your test until the associated `Promise` resolves. + +Occasionally, you may want to perform multiple actions simultaneously and wait until they're all done rather than performing each action sequentially. For example, read multiple properties of a single component. In these situations use the `parallel` function to parallelize the operations. The parallel function works similarly to `Promise.all`, while also optimizing change detection checks. + + +it('reads properties in parallel', async () => { + const checkboxHarness = loader.getHarness(MyCheckboxHarness); + // Read the checked and intermediate properties simultaneously. + const [checked, indeterminate] = await parallel(() => [ + checkboxHarness.isChecked(), + checkboxHarness.isIndeterminate() + ]); + expect(checked).toBe(false); + expect(indeterminate).toBe(true); +}); + diff --git a/adev-ja/src/content/guide/testing/using-component-harnesses.md b/adev-ja/src/content/guide/testing/using-component-harnesses.md index 5873913d5f..ce620d47b7 100644 --- a/adev-ja/src/content/guide/testing/using-component-harnesses.md +++ b/adev-ja/src/content/guide/testing/using-component-harnesses.md @@ -1,33 +1,33 @@ -# Using component harnesses in tests +# テストでコンポーネントハーネスを使う -## Before you start +## 始める前に -TIP: This guide assumes you've already read the [component harnesses overview guide](guide/testing/component-harnesses-overview). Read that first if you're new to using component harnesses. +TIP: このガイドは、すでに[コンポーネントハーネスの概要ガイド](guide/testing/component-harnesses-overview)を読んでいることを前提としています。コンポーネントハーネスの利用が初めての場合は、まずそちらを読んでください。 -### CDK Installation +### CDKのインストール {#cdk-installation} -The [Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories) is a set of behavior primitives for building components. To use the component harnesses, first install `@angular/cdk` from npm. You can do this from your terminal using the Angular CLI: +[Component Dev Kit (CDK)](https://material.angular.dev/cdk/categories)は、コンポーネントを構築するための動作プリミティブのセットです。コンポーネントハーネスを使用するには、まずnpmから`@angular/cdk`をインストールします。これは、Angular CLIを使用してターミナルから実行できます。 ng add @angular/cdk -## Test harness environments and loaders +## テストハーネス環境とローダー -You can use component test harnesses in different test environments. Angular CDK supports two built-in environments: +コンポーネントテストハーネスはさまざまなテスト環境で使用できます。AngularCDKは2つの組み込み環境をサポートしています。 -- Unit tests with Angular's `TestBed` -- End-to-end tests with [WebDriver](https://developer.mozilla.org/en-US/docs/Web/WebDriver) +- Angularの`TestBed`を使用した単体テスト +- [WebDriver](https://developer.mozilla.org/en-US/docs/Web/WebDriver)を使用したエンドツーエンドテスト -Each environment provides a harness loader. The loader creates the harness instances you use throughout your tests. See below for more specific guidance on supported testing environments. +各環境はハーネスローダーを提供します。ローダーはテスト全体で使用するハーネスインスタンスを作成します。サポートされているテスト環境に関するより具体的なガイダンスについては、以下を参照してください。 -Additional testing environments require custom bindings. See the [adding harness support for additional testing environments guide](guide/testing/component-harnesses-testing-environments) for more information. +追加のテスト環境にはカスタムバインディングが必要です。詳細については、[追加のテスト環境へのハーネスサポートの追加ガイド](guide/testing/component-harnesses-testing-environments)を参照してください。 -### Using the loader from `TestbedHarnessEnvironment` for unit tests +### 単体テストでの`TestbedHarnessEnvironment`からのローダーの使用 {#using-the-loader-from-testbedharnessenvironment-for-unit-tests} -For unit tests you can create a harness loader from [TestbedHarnessEnvironment](/api/cdk/testing/TestbedHarnessEnvironment). This environment uses a [component fixture](api/core/testing/ComponentFixture) created by Angular's `TestBed`. +単体テストでは、[TestbedHarnessEnvironment](/api/cdk/testing/TestbedHarnessEnvironment)からハーネスローダーを作成できます。この環境は、Angularの`TestBed`によって作成された[コンポーネントフィクスチャ](api/core/testing/ComponentFixture)を使用します。 -To create a harness loader rooted at the fixture's root element, use the `loader()` method: +フィクスチャのルート要素にルートを持つハーネスローダーを作成するには、`loader()`メソッドを使用します。 const fixture = TestBed.createComponent(MyComponent); @@ -40,15 +40,15 @@ const loader = TestbedHarnessEnvironment.loader(fixture); const myComponentHarness = await loader.getHarness(MyComponent); -To create a harness loader for harnesses for elements that fall outside the fixture, use the `documentRootLoader()` method. For example, code that displays a floating element or pop-up often attaches DOM elements directly to the document body, such as the `Overlay` service in Angular CDK. +フィクスチャの外部にある要素のハーネス用のハーネスローダーを作成するには、`documentRootLoader()`メソッドを使用します。たとえば、フローティング要素やポップアップを表示するコードは、AngularCDKの`Overlay`サービスのように、DOM要素をドキュメントボディに直接アタッチすることがよくあります。 -You can also create a harness loader directly with `harnessForFixture()` for a harness at that fixture's root element directly. +また、そのフィクスチャのルート要素にあるハーネス用に、`harnessForFixture()`を使用してハーネスローダーを直接作成できます。 -### Using the loader from `SeleniumWebDriverHarnessEnvironment` for end-to-end tests +### エンドツーエンドテストでの`SeleniumWebDriverHarnessEnvironment`からのローダーの使用 {#using-the-loader-from-seleniumwebdriverharnessenvironment-for-end-to-end-tests} -For WebDriver-based end-to-end tests you can create a harness loader with `SeleniumWebDriverHarnessEnvironment`. +WebDriverベースのエンドツーエンドテストでは、`SeleniumWebDriverHarnessEnvironment`を使用してハーネスローダーを作成できます。 -Use the `loader()` method to get the harness loader instance for the current HTML document, rooted at the document's root element. This environment uses a WebDriver client. +現在のHTMLドキュメントのハーネスローダーインスタンスを、ドキュメントのルート要素にルートを持つ形で取得するには、`loader()`メソッドを使用します。この環境はWebDriverクライアントを使用します。 let wd: webdriver.WebDriver = getMyWebDriverClient(); @@ -57,11 +57,11 @@ const loader = SeleniumWebDriverHarnessEnvironment.loader(wd); const myComponentHarness = await loader.getHarness(MyComponent); -## Using a harness loader +## ハーネスローダーの使用 {#using-a-harness-loader} -Harness loader instances correspond to a specific DOM element and are used to create component harness instances for elements under that specific element. +ハーネスローダーインスタンスは特定のDOM要素に対応し、その特定の要素配下の要素に対してコンポーネントハーネスインスタンスを作成するために使用されます。 -To get `ComponentHarness` for the first instance of the element, use the `getHarness()` method. To get all `ComponentHarness` instances, use the `getAllHarnesses()` method. +要素の最初のインスタンスの`ComponentHarness`を取得するには、`getHarness()`メソッドを使用します。すべての`ComponentHarness`インスタンスを取得するには、`getAllHarnesses()`メソッドを使用します。 // Get harness for first instance of the element @@ -71,13 +71,13 @@ const myComponentHarness = await loader.getHarness(MyComponent); const myComponentHarnesses = await loader.getHarnesses(MyComponent); -As an example, consider a reusable dialog-button component that opens a dialog on click. It contains the following components, each with a corresponding harness: +例として、クリック時にダイアログを開く再利用可能なダイアログボタンコンポーネントを考えます。これには、それぞれに対応するハーネスを持つ以下のコンポーネントが含まれています。 -- `MyDialogButton` (composes the `MyButton` and `MyDialog` with a convenient API) -- `MyButton` (a standard button component) -- `MyDialog` (a dialog appended to `document.body` by `MyDialogButton` upon click) +- `MyDialogButton` (`MyButton`と`MyDialog`を便利なAPIで構成) +- `MyButton` (標準のボタンコンポーネント) +- `MyDialog` (`MyDialogButton`によってクリック時に`document.body`に追加されるダイアログ) -The following test loads harnesses for each of these components: +以下のテストは、これらの各コンポーネントのハーネスをロードします。 let fixture: ComponentFixture; @@ -109,13 +109,13 @@ it('loads harnesses', async () => { }); -### Harness behavior in different environments +### 異なる環境でのハーネスの動作 {#harness-behavior-in-different-environments} -Harnesses may not behave exactly the same in all environments. Some differences are unavoidable between the real user interaction versus the simulated events generated in unit tests. Angular CDK makes a best effort to normalize the behavior to the extent possible. +ハーネスは、すべての環境でまったく同じように動作するとは限りません。実際のユーザーインタラクションと単体テストで生成されるシミュレートされたイベントの間には、避けられない違いがあります。Angular CDKは、可能な限り動作を正規化するために最善を尽くします。 -### Interacting with child elements +### 子要素とのインタラクション {#interacting-with-child-elements} -To interact with elements below the root element of this harness loader, use the `HarnessLoader` instance of a child element. For the first instance of the child element, use the `getChildLoader()` method. For all instances of the child element, use the `getAllChildLoaders()` method. +このハーネスローダーのルート要素より下位の要素とインタラクトするには、子要素の`HarnessLoader`インスタンスを使用します。子要素の最初のインスタンスには`getChildLoader()`メソッドを、すべての子要素のインスタンスには`getAllChildLoaders()`メソッドを使用します。 const myComponentHarness = await loader.getHarness(MyComponent); @@ -127,16 +127,16 @@ const childLoader = await myComponentHarness.getLoader('.child'); const allChildLoaders = await myComponentHarness.getAllChildLoaders('.child'); -### Filtering harnesses +### ハーネスのフィルタリング {#filtering-harnesses} -When a page contains multiple instances of a particular component, you may want to filter based on some property of the component to get a particular component instance. You can use a harness predicate, a class used to associate a `ComponentHarness` class with predicates functions that can be used to filter component instances, to do so. +ページに特定のコンポーネントの複数のインスタンスが含まれている場合、特定のコンポーネントインスタンスを取得するために、コンポーネントの何らかのプロパティに基づいてフィルタリングしたい場合があります。これを行うには、ハーネス述語を使用できます。これは、`ComponentHarness`クラスを、コンポーネントインスタンスをフィルタリングするために使用できる述語関数と関連付けるために使用されるクラスです。 -When you ask a `HarnessLoader` for a harness, you're actually providing a HarnessQuery. A query can be one of two things: +`HarnessLoader`にハーネスを要求するとき、実際にはHarnessQueryを提供しています。クエリは次の2つのいずれかです。 -- A harness constructor. This just gets that harness -- A `HarnessPredicate`, which gets harnesses that are filtered based on one or more conditions +- ハーネスコンストラクター。これは単にそのハーネスを取得します +- `HarnessPredicate`。これは1つ以上の条件に基づいてフィルタリングされたハーネスを取得します -`HarnessPredicate` does support some base filters (selector, ancestor) that work on anything that extends `ComponentHarness`. +`HarnessPredicate`は、`ComponentHarness`を拡張するあらゆるものに機能するいくつかの基本フィルター(selector、ancestor)をサポートしています。 // Example of loading a MyButtonComponentHarness with a harness predicate @@ -144,22 +144,22 @@ const disabledButtonPredicate = new HarnessPredicate(MyButtonComponentHarness, { const disabledButton = await loader.getHarness(disabledButtonPredicate); -However it's common for harnesses to implement a static `with()` method that accepts component-specific filtering options and returns a `HarnessPredicate`. +ただし、ハーネスがコンポーネント固有のフィルタリングオプションを受け入れ、`HarnessPredicate`を返す静的`with()`メソッドを実装することは一般的です。 // Example of loading a MyButtonComponentHarness with a specific selector const button = await loader.getHarness(MyButtonComponentHarness.with({selector: 'btn'})) -For more details refer to the specific harness documentation since additional filtering options are specific to each harness implementation. +追加のフィルタリングオプションは各ハーネスの実装に固有であるため、詳細については特定のハーネスのドキュメントを参照してください。 -## Using test harness APIs +## テストハーネスAPIの使用 {#using-test-harness-apis} -While every harness defines an API specific to its corresponding component, they all share a common base class, [ComponentHarness](/api/cdk/testing/ComponentHarness). This base class defines a static property, `hostSelector`, that matches the harness class to instances of the component in the DOM. +各ハーネスは対応するコンポーネントに固有のAPIを定義していますが、それらはすべて共通の基底クラスである[ComponentHarness](/api/cdk/testing/ComponentHarness)を共有しています。この基底クラスは、ハーネスクラスをDOM内のコンポーネントインスタンスに一致させる静的プロパティ`hostSelector`を定義します。 -Beyond that, the API of any given harness is specific to its corresponding component; refer to the component's documentation to learn how to use a specific harness. +それ以外に、特定のハーネスのAPIは対応するコンポーネントに固有です。特定のハーネスの使用方法については、コンポーネントのドキュメントを参照してください。 -As an example, the following is a test for a component that uses the [Angular Material slider component harness](https://material.angular.dev/components/slider/api#MatSliderHarness): +例として、[Angular Materialスライダーコンポーネントハーネス](https://material.angular.dev/components/slider/api#MatSliderHarness)を使用するコンポーネントのテストを以下に示します。 it('should get value of slider thumb', async () => { @@ -169,11 +169,11 @@ it('should get value of slider thumb', async () => { }); -## Interop with Angular change detection +## Angularの変更検知との連携 {#interop-with-angular-change-detection} -By default, test harnesses runs Angular's [change detection](https://angular.dev/best-practices/runtime-performance) before reading the state of a DOM element and after interacting with a DOM element. +デフォルトでは、テストハーネスはAngularの[変更検知](https://angular.dev/best-practices/runtime-performance)をDOM要素の状態を読み取る前と、DOM要素と対話した後に実行します。 -There may be times that you need finer-grained control over change detection in your tests. such as checking the state of a component while an async operation is pending. In these cases use the `manualChangeDetection` function to disable automatic handling of change detection for a block of code. +テストで変更検知をより細かく制御する必要がある場合があります。例えば、非同期操作が保留中の間にコンポーネントの状態を確認する場合などです。このような場合は、`manualChangeDetection`関数を使用して、コードブロックの変更検知の自動処理を無効にします。 it('checks state while async action is in progress', async () => { @@ -190,15 +190,15 @@ it('checks state while async action is in progress', async () => { }); -Almost all harness methods are asynchronous and return a `Promise` to support the following: +ほとんどすべてのハーネスメソッドは非同期であり、以下をサポートするために`Promise`を返します。 -- Support for unit tests -- Support for end-to-end tests -- Insulate tests against changes in asynchronous behavior +- 単体テストのサポート +- エンドツーエンドテストのサポート +- 非同期動作の変更からテストを保護 -The Angular team recommends using [await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) to improve the test readability. Calling `await` blocks the execution of your test until the associated `Promise` resolves. +Angularチームは、テストの可読性を向上させるために[await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)の使用を推奨しています。`await`を呼び出すと、関連する`Promise`が解決されるまでテストの実行がブロックされます。 -Occasionally, you may want to perform multiple actions simultaneously and wait until they're all done rather than performing each action sequentially. For example, read multiple properties of a single component. In these situations use the `parallel` function to parallelize the operations. The parallel function works similarly to `Promise.all`, while also optimizing change detection checks. +場合によっては、複数のアクションを同時に実行し、それぞれのアクションを順次実行するのではなく、すべてが完了するまで待機したい場合があります。例えば、単一コンポーネントの複数のプロパティを読み取る場合などです。このような状況では、`parallel`関数を使用して操作を並列化します。`parallel`関数は`Promise.all`と同様に機能し、変更検知チェックも最適化します。 it('reads properties in parallel', async () => {