diff --git a/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/index.mdx b/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/index.mdx new file mode 100644 index 0000000000..fd92456cab --- /dev/null +++ b/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/index.mdx @@ -0,0 +1,201 @@ +--- +title: モデル・アプリケーションの基本設定 +sidebar: + order: 30 +i18nReady: true +--- + +{/* TODO: REVISE COPY TO V2 */} + +import { Image } from 'astro:assets'; +import HelloTauriWebdriver from '@assets/develop/Tests/hello-tauri-webdriver.png'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +この章の「モデル・アプリケーション」事例では、既存のプロジェクトに WebDriver テストを追加することだけに焦点を当てています。 +続く二章でテストするプロジェクトを用意するために、そのテストで使用するための極最小限の Tauri アプリケーションを構成します。 +ここでは、Tauri CLI や、フロントエンドの依存関係、ビルド手順は使用せず、また、後からアプリケーションをバンドルすることもありません。 +ここでの作業は、既存のアプリケーションに WebDriver テストを追加する方法を示し、最小の構成設定を紹介するためのものです。 + +この「モデル・アプリケーション」作成ガイドで紹介されている内容に基づいた完成版のプロジェクト事例だけを見たい場合には、https://github.com/chippers/hello_tauri を参照してください。 + +## Cargo プロジェクトの初期化 + +この「モデル・アプリケーション」を格納するための新しいバイナリ Cargo プロジェクトを作成します。 +これは、コマンドラインから `cargo new hello-tauri-webdriver --bin` を使用すれば簡単に行なえ、これにより最小限のバイナリ Cargo プロジェクトが準備されます。 +このディレクトリは、この先、この作成ガイドの作業ディレクトリとして機能するため、実行するコマンドがこの新しい `hello-tauri-webdriver/` ディレクトリ内にあることを確認してください。 + +## 最小構成のフロントエンドの作成 + +「モデル・アプリケーション」のフロントエンドとなる最小限の HTML ファイルを作成します。 +後ほど、WebDriver テスト中にこのフロントエンドのいくつかの項目を用いることになります。 + +最初に、「モデル・アプリケーション」の Tauri 部分を構築する際に必要になる Tauri `distDir` を作成しましょう。 +コマンド `mkdir dist` で `dist/` という新しいディレクトリを作成し、そこに次の `index.html` ファイルを配置します。 + +`dist/index.html`: + +```html + + + + + Hello Tauri! + + + +

Hello, Tauri!

+ + +``` + +## タウリを Cargo プロジェクトに追加 + +次に、上記の Cargo プロジェクトを Tauri プロジェクトに変換するために必要な項目を追加します。まず、Cargo マニフェスト・ファイル(`Cargo.toml`)に依存関係を追加し、Cargo がビルド時に依存関係を読み込むようにします。 + + + +**Cargo.toml** 以下の Cargo.toml ファイルは一部内容が古い可能性があります。たとえば 2025.02.20 現在の Rust エディションは "2024"、最新バージョンは "1.85" です。バージョン "1.56" は 2021.10.21 リリース、tauri 1.0 のリリースが 2022.06.19 なので、その頃に作成された事例と思われます。適宜読み替えてください。 + + + +`Cargo.toml`: + +```toml +[package] +name = "hello-tauri-webdriver" +version = "0.1.0" +edition = "2021" +rust-version = "1.56" + +# ビルド時に Tauri 用にいくつかの設定が必要 +[build-dependencies] +tauri-build = "1" + +# 実際の Tauri 依存関係と、ページを表示(serve)するための `custom-protocol` +[dependencies] +tauri = { version = "1", features = ["custom-protocol"] } + +# --release で、小さく(opt-level = "s")かつ高速(lto = true)なバイナリをビルドします +# この設定は完全にオプションですが、一般的なリリース設定にできるだけ近い状態でアプリケーションをテストすることが可能であることを示しています +# 注意: これによりコンパイル速度が低下します +[profile.release] +incremental = false +codegen-units = 1 +panic = "abort" +opt-level = "s" +lto = true +``` + +お気づきかもしれませんが、`[build-dependency]`(ビルド依存関係)が追加されています。この `[build-dependency]` を利用するには、これをビルド・スクリプトから使用する必要があります。 +そこで `build.rs` で作成します。 + +`build.rs`: + +```rust +fn main() { + // 再コンパイルでは `dist/` ディレクトリのみを監視し、別のプロジェクトのサブディレクトリのファイルを変更したときに不要な変更が加えられるのを防ぎます + println!("cargo:rerun-if-changed=dist"); + + // Tauri build-time helpers を実行します + tauri_build::build() +} +``` + +これで、Cargo プロジェクトは Tauri の依存関係とその設定を読み込み、ビルドできるようになりました。実際のプロジェクト・コードに Tauri を設定して、この最小限の Tauri モデル・アプリケーションを完成させましょう。この Tauri 機能を追加するために、`src/main.rs` ファイルを編集します。 + +`src/main.rs`: + +```rust +fn main() { + tauri::Builder::default() + .run(tauri::generate_context!()) + .expect("unable to run Tauri application"); +} +``` + +どう? とても簡単でしょう? + +## Tauri の設定 + +このモデル・アプリケーションを正常にビルドするには、二つのものが必要です。一つ目は、「アイコン・ファイル」です。この作業にはどのような PNG データでも構いません。それを `icon.png` にコピーします。 +通常は、このデータは、プロジェクトの作成に Tauri CLI を使用すると、その準備処理の一部として提供されます。 +デフォルトの Tauri アイコンを取得するには、コマンド `curl -L "https://github.com/chippers/hello_tauri/raw/main/icon.png" --output icon.png` を使用して、「Hello Tauri サンプル・リポジトリ」で使用されているアイコンをダウンロードします。 + +二つ目は、Tauri 用の重要な設定値を設定するための「`tauri.conf.json`」ファイルです。 +このファイルも、通常はスキャフォルディング・コマンドの `tauri init` で生成されますが、ここでも独自の最小限の構成を作成します。 + + + +**スキャフォルディング・コマンド** scaffolding command: "scaffold" は「工事現場の足場」「足場を組む」という意味ですが、本稿では主に「準備」という訳語を当てています。「スキャフォルディング・コマンド」とはアプリケーション作成開始時に必要なファイル類を自動作成/準備してくれる(作業用の足場を組んでくれる)コマンドのこと。 + + + +`tauri.conf.json`: + +```json +{ + "build": { + "distDir": "dist" + }, + "tauri": { + "bundle": { + "identifier": "studio.tauri.hello_tauri_webdriver", + "icon": ["icon.png"] + }, + "allowlist": { + "all": false + }, + "windows": [ + { + "width": 800, + "height": 600, + "resizable": true, + "fullscreen": false + } + ] + } +} +``` + +いくつかの項目の内容を見ていきましょう。 +先ほど作成した `dist/` ディレクトリが `distDir` プロパティに指定されているのがわかります。 +ビルドされたアプリケーションが一意の ID を持つようにバンドル識別子(ID)を設定し、アイコンには `icon.png` のみを指定しています。Tauri の API や機能は使用しないため、`allowlist` で `"all": false` を設定して無効化しています。 +ウィンドウ値には、適切なデフォルト値を使用して作成される単一のウィンドウを設定するだけです。 + +これで、実行時に簡単な挨拶を表示する基礎的な「Hello World」アプリケーションが完成しました。 + +## モデル・アプリケーションの実行 + +正しく設定が行なわれているかを確認するために、このアプリケーションをビルドしてみましょう。WebDriver テストもリリース版用設定プロファイルで実行するので、このアプリケーションを `--release` 版として実行します。 +`cargo run --release` を実行すると、コンパイル後に次のアプリケーションがポップアップ表示されるはずです。 + +
+ Hello Tauri Webdriver +
+ +_注記: アプリケーションを修正して Devtools を使用したい場合は、`--release` 指定なしで実行すれば、右クリック・メニューで「Inspect Element/要素の検査」が表示され、利用できるはずです。_ + +これで、このモデル・アプリケーションを利用して、「WebDriver フレームワーク」を使用したテストを開始する準備が整いました。 +次章から、[Selenium を利用する](/ja/develop/tests/webdriver/example/selenium/) と [WebdriverIO を利用する](/ja/develop/tests/webdriver/example/webdriverio/) の両方について、この順序で説明します。 + +[完成版モデル・アプリケーション]: https://github.com/chippers/hello_tauri + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/selenium.mdx b/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/selenium.mdx new file mode 100644 index 0000000000..d420553cb8 --- /dev/null +++ b/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/selenium.mdx @@ -0,0 +1,216 @@ +--- +title: Selenium を利用する +sidebar: + order: 31 +i18nReady: true +--- + +{/* TODO: REVISE COPY TO V2 */} + +import CommandTabs from '@components/CommandTabs.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +:::note[モデル・アプリケーション] + +この「[Selenium](セレニウム)」設定ガイドでは、手順を追って読み進めるために、前章の「[モデル・アプリケーションの基本設定]」に目を通していることを前提としています。それとは別に、一般的な情報としても役に立つでしょう。 + +::: + +この章の WebDriver テストの事例では、[Selenium] と人気のある Node.js のテスト・スイートを使用しますので、 +`npm` または `yarn` とともに Node.js をインストールしていることが前提となります([完成版モデル・アプリケーション] では `yarn` が使用されていますが)。 + +## テスト用ディレクトリの作成 + +プロジェクト内にテストを記述するための場所を作成しましょう。 +このプロジェクト事例では「ネスト化された」ディレクトリを使用しますが、これは後ほど他のフレームワークについても詳しく調べるためで、通常は「一つのフレームワーク」だけが必要です。 +`mkdir -p webdriver/selenium` で、使用するディレクトリを作成します。以下、この設定ガイドでは、`webdriver/selenium` ディレクトリ内にいると仮定します。 + +## Selenium プロジェクトの初期化 + +既存の `package.json` を使用して、このテスト・スイートをブートストラップ(起動)します。というのも、使用する具体的な依存関係はすでに選定済であり、シンプルで実用的なソリューションを紹介したいためです。 +この項の最後の「**> ここをクリック・・・**」の部分に、白紙の状態から設定する手順についての設定ガイドが折り畳まれています。 + +`package.json`: + +```json +{ + "name": "selenium", + "version": "1.0.0", + "private": true, + "scripts": { + "test": "mocha" + }, + "dependencies": { + "chai": "^4.3.4", + "mocha": "^9.0.3", + "selenium-webdriver": "^4.0.0-beta.4" + } +} +``` + +テスト・フレームワークとして [Mocha](モカ)を実行するスクリプトがあり、これは `test` コマンドとして利用可能です。 +また、テストの実行に使用するさまざまな依存関係もあります。 +すなわち、テスト・フレームワークとしての [Mocha]、アサーション・ライブラリとしての [Chai](チャイ)、それに [`selenium-webdriver`] で、これは Node.js の [Selenium] パッケージです。 + + + +**アサーション・ライブラリ** assertion library: テスト時に検証結果が想定された内容かどうかを判定するためのツール。 + + + +
+ ここをクリック(プロジェクトを白紙の状態から設定する場合) + +依存関係を白紙の状態からインストールする場合は、次のコマンドを実行します。 + + + +また、`package.json` の `"scripts"` キーに `"test": "mocha"` 項目を追加することをお勧めします。これにより、Mocha の実行が以下のコマンドから簡単に呼び出せるようになります。 + + + +
+ +## テスト + +[WebdriverIO のテスト・スイート](/ja/develop/tests/webdriver/example/webdriverio/#設定) とは異なり、Selenium にはテスト・スイートが付属しておらず、テスト・スイートの構築は開発者に任されています。 +ここでは [Mocha] を選択しました。Mocha は WebDrivers とは関係のない、比較的中立的なライブラリなので、スクリプトのすべてを正しい順序で設定するには少しばかり作業が必要になります。 +[Mocha] はデフォルトで `test/test.js` にテスト・ファイルを用意する必要があります。では、早速作成してみましょう。 + +`test/test.js`: + +```javascript +const os = require('os'); +const path = require('path'); +const { expect } = require('chai'); +const { spawn, spawnSync } = require('child_process'); +const { Builder, By, Capabilities } = require('selenium-webdriver'); + +// 求められるアプリケーション・バイナリへのパスを作成 +const application = path.resolve( + __dirname, + '..', + '..', + '..', + 'target', + 'release', + 'hello-tauri-webdriver' +); + +// 作成した WebDriver インスタンスを追跡 +let driver; + +// 開始する tauri-driver プロセスを追跡 +let tauriDriver; + +before(async function () { + // 必要に応じてプログラムをビルドできるように、タイムアウトを2分に設定 + this.timeout(120000); + + // プログラムがビルドされたことを確認 + spawnSync('cargo', ['build', '--release']); + + // tauri-driver を起動 + tauriDriver = spawn( + path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'), + [], + { stdio: [null, process.stdout, process.stderr] } + ); + + const capabilities = new Capabilities(); + capabilities.set('tauri:options', { application }); + capabilities.setBrowserName('wry'); + + // Webdriver クライアントを起動 + driver = await new Builder() + .withCapabilities(capabilities) + .usingServer('http://127.0.0.1:4444/') + .build(); +}); + +after(async function () { + // Webdriver セッションを停止 + await driver.quit(); + + // tauri-driver プロセスを強制終了 + tauriDriver.kill(); +}); + +describe('Hello Tauri', () => { + it('should be cordial', async () => { + const text = await driver.findElement(By.css('body > h1')).getText(); + expect(text).to.match(/^[hH]ello/); + }); + + it('should be excited', async () => { + const text = await driver.findElement(By.css('body > h1')).getText(); + expect(text).to.match(/!$/); + }); + + it('should be easy on the eyes', async () => { + // Selenium は色の CSS 値を rgb(r, g, b) として返します + const text = await driver + .findElement(By.css('body')) + .getCssValue('background-color'); + + const rgb = text.match(/^rgb\((?\d+), (?\d+), (?\d+)\)$/).groups; + expect(rgb).to.have.all.keys('r', 'g', 'b'); + + const luma = 0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b; + expect(luma).to.be.lessThan(100); + }); +}); +``` + +もし「JS テスト・フレームワーク」に慣れ親しんでいる方であれば、`describe`、`it`、`expect` などは見覚えがあるはずです。また、mocha の設定(セットアップ)と解除(ティアダウン)を行なうための、やや複雑な`before()`と`after()`コールバックも用意されています。 +テスト本体ではない行には、セットアップ・コードとティアダウン・コードを説明するコメントの記載があります。 +[WebdriverIO のテスト仕様](/ja/develop/tests/webdriver/example/webdriverio/#テスト仕様)の「Spec ファイル」に慣れている場合は、WebDriver 関連の項目をさらにいくつか設定する必要があるため、テスト以外のコードがより多くなっていることに気付くでしょう。 + +## テスト・スイートの実行 + +依存関係とテスト・スクリプトの設定がすべて完了しましたので、実行してみましょう。 + + + +次のような出力が表示されるはずです: + +```text +➜ selenium git:(main) ✗ yarn test +yarn run v1.22.11 +$ Mocha + + + Hello Tauri + ✔ should be cordial (120ms) + ✔ should be excited + ✔ should be easy on the eyes + + + 3 passing (588ms) + +Done in 0.93s. +``` + +上記の `test/test.js` の `describe` で生成した `Hello Tauri` テスト・スイートでは、`it` に記載した三つのテスト項目がすべて合格していることがわかります。 + +[Selenium] とともに、テスト・スイートに「フックアップ」する(別処理を挟み込む)処理により、Tauri アプリケーションをまったく修正せずに「e2e テスト」を実行することができました! + + + +**e2e テスト** end-to-end test の略記。システム全体を「先端から終端まで」(つまり最初から最後まで)動作検証するテスト手法。自動システム全検証。システム毎にテスト・コードを準備すると工数・費用が増大するため、テスト自動化ツールが利用されています。 + + + +[モデル・アプリケーションの基本設定]: /ja/develop/tests/webdriver/example/ +[selenium]: https://selenium.dev/ja/ +[完成版モデル・プロジェクト]: https://github.com/chippers/hello_tauri +[mocha]: https://mochajs.org/ +[chai]: https://www.chaijs.com/ +[`selenium-webdriver`]: https://www.npmjs.com/package/selenium-webdriver + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/webdriverio.mdx b/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/webdriverio.mdx new file mode 100644 index 0000000000..b4403ddf61 --- /dev/null +++ b/src/content/docs/ja/develop/Debug/tests/WebDriver/Example/webdriverio.mdx @@ -0,0 +1,224 @@ +--- +title: WebdriverIO を利用する +sidebar: + order: 31 +i18nReady: true +--- + +{/* TODO: REVISE COPY TO V2 */} + +import CommandTabs from '@components/CommandTabs.astro'; +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +:::note[モデル・アプリケーション] + +この「[WebdriverIO]」(ウェブドライバ IO)設定ガイドでは、手順を追って読み進めるために、前々章の「[モデル・アプリケーションの基本設定]」に目を通していることを前提としています。それとは別に、一般的な情報としても役に立つでしょう。 + +::: + +この章の WebDriver テストの事例では、[WebdriverIO] とそのテスト・スイートを使用しますので、 +`npm` または `yarn` とともに Node.js がすでにインストールされていることが前提となります([完成版モデル・アプリケーション] では `yarn` が使用されていますが)。 + +## テスト用ディレクトリの作成 + +プロジェクト内にテストを記述するための場所を作成しましょう。 +このプロジェクト事例では「ネスト化された」ディレクトリを使用しますが、これは後ほど他のフレームワークについても詳しく調べるためで、通常は「一つのフレームワーク」だけが必要です。 +`mkdir -p webdriver/webdriverio` で、使用するディレクトリを作成します。以下、この設定ガイドでは、`webdriver/webdriverio` ディレクトリ内にいると仮定します。 + +## WebdriverIO プロジェクトの初期化 + +既存の `package.json` を使用して、このテスト・スイートをブートストラップ(起動)します。というのも、既に具体的な [WebdriverIO] 設定オプションを選定済であり、シンプルで実用的なソリューションを紹介したいためです。 +この項の最後の「**> ここをクリック・・・**」の部分に、白紙の状態から設定する手順についての設定ガイドが折り畳まれています。 + +`package.json`: + +```json +{ + "name": "webdriverio", + "version": "1.0.0", + "private": true, + "scripts": { + "test": "wdio run wdio.conf.js" + }, + "dependencies": { + "@wdio/cli": "^7.9.1" + }, + "devDependencies": { + "@wdio/local-runner": "^7.9.1", + "@wdio/mocha-framework": "^7.9.1", + "@wdio/spec-reporter": "^7.9.0" + } +} +``` + +テスト・スイートとして [WebdriverIO] 設定を実行するスクリプトがあり、これは `test` コマンドとして利用可能です。 +また、最初にセットアップするときに `@wdio/cli` コマンドによって追加される依存関係もあります。 +手短に言えば、こうした依存関係は、ローカル WebDriver ランナー、テスト・フレームワークとしての [Mocha]、および単純な Spec Reporter を使用した最も単純なセットアップのためのものです。 + +
+ ここをクリック(プロジェクトを白紙の状態から設定する場合) + +CLI は対話型であり、自分で操作するツールを選択できます。 +ただし、設定ガイドの記述とは相違する場合があり、相違部分は自分で設定する必要があることに注意してください。 + +この npm プロジェクトに [WebdriverIO] CLIを追加しましょう。 + + + +次に、対話型 config コマンドを実行して [WebdriverIO] テスト・スイートを設定するには、次のコマンドを実行します: + + + +
+ +## 設定 + +`package.json` 内の `test` スクリプトに `wdio.conf.js` ファイルが記載されていることに気付いたかもしれません。 +これは、[WebdriverIO] 設定ファイルで、テスト・スイートのほとんどの側面を制御するものです。 + +`wdio.conf.js`: + +```javascript +const os = require('os'); +const path = require('path'); +const { spawn, spawnSync } = require('child_process'); + +// `tauri-driver` 子プロセスを追跡 +let tauriDriver; + +exports.config = { + specs: ['./develop/tests/specs/**/*.js'], + maxInstances: 1, + capabilities: [ + { + maxInstances: 1, + 'tauri:options': { + application: '../../target/release/hello-tauri-webdriver', + }, + }, + ], + reporters: ['spec'], + framework: 'mocha', + mochaOpts: { + ui: 'bdd', + timeout: 60000, + }, + + // Webdriver セッション用に必要な Rust プロジェクトがビルドされていることを確認 + onPrepare: () => spawnSync('cargo', ['build', '--release']), + + // Webdriver 要求をプロキシできるように、セッション開始前に `tauri-driver` が実行されていることを確認 + beforeSession: () => + (tauriDriver = spawn( + path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'), + [], + { stdio: [null, process.stdout, process.stderr] } + )), + + // セッションの開始時に生成した「tauri-driver」プロセスをクリーンアップ + afterSession: () => tauriDriver.kill(), +}; +``` + +`exports.config` オブジェクトのプロパティに興味がある場合は、[webdriver ドキュメント] を参照してください。 +webdriverIO 固有ではない項目については、`onPrepare`、`beforeSession`、および `afterSession` 内でなぜコマンドを実行しているのかを説明するコメントがあります。 +「スペック(テスト仕様)」も `"./develop/tests/specs/**/*.js"` に設定されるので、次に「テスト仕様」を作成しましょう。 + +## テスト仕様 + +「テスト仕様」には、実際のアプリケーションをテストするコードが含まれています。 +テスト・ランナーはこの「テスト仕様」を読み込み、必要に応じて自動的に実行します。では、指定したディレクトリに「テスト仕様」を作成しましょう。 + +`test/specs/example.e2e.js`: + +```javascript +// 「16進カラー」`#abcdef` から「輝度(luma ルーマ)」を計算 +function luma(hex) { + if (hex.startsWith('#')) { + hex = hex.substring(1); + } + + const rgb = parseInt(hex, 16); + const r = (rgb >> 16) & 0xff; + const g = (rgb >> 8) & 0xff; + const b = (rgb >> 0) & 0xff; + return 0.2126 * r + 0.7152 * g + 0.0722 * b; +} + +describe('Hello Tauri', () => { + it('should be cordial', async () => { + const header = await $('body > h1'); + const text = await header.getText(); + expect(text).toMatch(/^[hH]ello/); + }); + + it('should be excited', async () => { + const header = await $('body > h1'); + const text = await header.getText(); + expect(text).toMatch(/!$/); + }); + + it('should be easy on the eyes', async () => { + const body = await $('body'); + const backgroundColor = await body.getCSSProperty('background-color'); + expect(luma(backgroundColor.parsed.hex)).toBeLessThan(100); + }); +}); +``` + +最初の [luma] 関数は、テストの一つに対する単なるヘルパー関数であり、実際のアプリケーションのテストとは関係ありません。 +もし他のテスト・フレームワークに慣れ親しんでいる方であれば、`describe`、`it`、`expect` など、用いられている同様の関数が「開放」(外部アクセス可能化)されていることに気付くかもしれません。 +その他の API、たとえば `$` などの項目や公開されたメソッドなど、については、[WebdriverIO API ドキュメント] で説明されています。 + +## テスト・スイートの実行 + +設定とテスト仕様がすべて準備できたので、実行してみましょう! + + + +次のような出力が表示されるはずです: + +```text +➜ webdriverio git:(main) ✗ yarn test +yarn run v1.22.11 +$ wdio run wdio.conf.js + +Execution of 1 workers started at 2021-08-17T08:06:10.279Z + +[0-0] RUNNING in undefined - /develop/tests/specs/example.e2e.js +[0-0] PASSED in undefined - /develop/tests/specs/example.e2e.js + + "spec" Reporter: +------------------------------------------------------------------ +[wry 0.12.1 linux #0-0] Running: wry (v0.12.1) on linux +[wry 0.12.1 linux #0-0] Session ID: 81e0107b-4d38-4eed-9b10-ee80ca47bb83 +[wry 0.12.1 linux #0-0] +[wry 0.12.1 linux #0-0] » /develop/tests/specs/example.e2e.js +[wry 0.12.1 linux #0-0] Hello Tauri +[wry 0.12.1 linux #0-0] ✓ should be cordial +[wry 0.12.1 linux #0-0] ✓ should be excited +[wry 0.12.1 linux #0-0] ✓ should be easy on the eyes +[wry 0.12.1 linux #0-0] +[wry 0.12.1 linux #0-0] 3 passing (244ms) + + +Spec Files: 1 passed, 1 total (100% completed) in 00:00:01 + +Done in 1.98s. +``` + +Spec Reporter 部には、`test/specs/example.e2e.js` ファイルからの三つのテストすべてと、最終レポート `Spec Files: 1 passed, 1 Toal (100% Complete) in 00:00:01` が表示されます。 + +[WebdriverIO] テスト・スイートを使用することで、わずか数行の設定と一つのコマンド実行だけで、Tauri アプリケーションの e2e テストを簡単に実行できました! さらに素晴らしいのは、アプリケーションを一切修正する必要がなかったということです。 + +[モデル・アプリケーションの基本設定]: /ja/develop/tests/webdriver/example/ +[webdriverio]: https://webdriver.io/ja/ +[完成版モデル・アプリケーション]: https://github.com/chippers/hello_tauri +[mocha]: https://mochajs.org/ +[webdriver ドキュメント]: https://webdriver.io/docs/configurationfile +[webdriverio api ドキュメント]: https://webdriver.io/docs/api +[luma]: https://ja.wikipedia.org/wiki/ルーマ + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/develop/Debug/tests/WebDriver/ci.md b/src/content/docs/ja/develop/Debug/tests/WebDriver/ci.md new file mode 100644 index 0000000000..2c828c4704 --- /dev/null +++ b/src/content/docs/ja/develop/Debug/tests/WebDriver/ci.md @@ -0,0 +1,102 @@ +--- +title: 継続的インテグレーション(CI) +description: WebDriver のテスト +sidebar: + order: 21 +i18nReady: true +--- + +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +Linux といくつかのプログラムを利用して仮のディスプレイを作成すると、CI (継続的インテグレーション・テストツール)上で [`tauri-driver`] を使用して [WebDriver] テストの実行が可能になります。 +以下では、[WebdriverIO] による[予め作成したテスト事例]と GitHub Actions を使用しています。 + +これには次の二点が前提になっています: + +1. Tauri アプリケーションはリポジトリのルートにあり、`cargo build --release` を実行するとバイナリがビルドされる +2. 「[WebDriverIO] テスト・ランナー」は `webdriver/webdriverio` ディレクトリにあり、そのディレクトリで `yarn test` が使用されると実行される + +以下は `.github/workflows/webdriver.yml` にあるコメント付きの GitHub Actions ワークフロー・ファイルです。 + +```yaml +# リポジトリがプッシュされたときにこのアクションを実行 +on: [push] + +# ワークフローの名前 +name: WebDriver + +jobs: + # test という名前の単一ジョブ + test: + # test ジョブの表示名 + name: WebDriverIO Test Runner + + # 最新の Linux 環境を指定(we want to run on) + runs-on: ubuntu-22.04 + + # ジョブが**順番に**実行する手順 + steps: + # 「ワークフロー・ランナー」のコードをチェックアウト(確認) + - uses: actions/checkout@v4 + + # Tauri が Linux 上でコンパイルするために必要なシステム依存関係をインストール + # `tauri-driver` を実行するための追加の依存関係 (`webkit2gtk-driver` と `xvfb`)に注意 + - name: Tauri dependencies + run: | + sudo apt update && sudo apt install -y \ + libwebkit2gtk-4.1-dev \ + build-essential \ + curl \ + wget \ + file \ + libxdo-dev \ + libssl-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + webkit2gtk-driver \ + xvfb + + - name: Setup rust-toolchain stable + id: rust-toolchain + uses: dtolnay/rust-toolchain@stable + + # 破損しているアプリケーションのテストを避けるために、WebDriver テストの前に Rust テストを実行 + - name: Cargo test + run: cargo test + + # WebdriverIO テスト中に使用されるアプリケーションのリリースビルドを実行 + - name: Cargo build + run: cargo build --release + + # 最新安定版 node バージョンをインストール(執筆時点) + - name: Node 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + + # Yarn を使って Node.js の依存関係をインストール + - name: Yarn install + run: yarn install --frozen-lockfile + working-directory: webdriver/webdriverio + + # `tauri-driver` の最新バージョンをインストール + # 注意: tauri-driver のバージョンは他の Tauri のバージョン番号とは無関係です + - name: Install tauri-driver + run: cargo install tauri-driver --locked + + # WebdriverIO テスト・スイートを実行 + # `xvfb-run`(先ほどインストールした依存関係)を実行して、仮のディスプレイ・サーバーを作成し、コードを変更せずにアプリケーションをヘッドレス(無人)で実行できるようにします + - name: WebdriverIO + run: xvfb-run yarn test + working-directory: webdriver/webdriverio +``` + +[予め作成したテスト事例]: /ja/develop/tests/webdriver/example/webdriverio/ +[webdriver]: https://www.w3.org/TR/webdriver/ +[`tauri-driver`]: https://crates.io/crates/tauri-driver +[webdriverio]: https://webdriver.io/ + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/develop/Debug/tests/WebDriver/index.mdx b/src/content/docs/ja/develop/Debug/tests/WebDriver/index.mdx new file mode 100644 index 0000000000..e140c11677 --- /dev/null +++ b/src/content/docs/ja/develop/Debug/tests/WebDriver/index.mdx @@ -0,0 +1,100 @@ +--- +title: WebDriver +description: WebDriver のテスト +sidebar: + order: 10 + label: 概要 +i18nReady: true +--- + +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +[WebDriver] は、主として自動テストを目的とした、Web ドキュメントとのやりとりを行なうための標準化されたインターフェースです。 +Tauri は、クロス・プラットフォーム・ラッパー [`tauri-driver`] の下で、ネイティブ・プラットフォームの [WebDriver] サーバーを利用することで [WebDriver] インターフェースをサポートしています。 +デスクトップでは、Windows と Linux のみがサポートされます。macOS では WKWebView ドライバー・ツールが利用できないためです。 +iOS と Android では、ソフトウェアの自動テスト・エコシステム [Appium 2] を通じて動作しますが、現在のところ、そのプロセスは簡素効率化されていません。 + +## システムの依存関係 + +次のコマンドを実行して、最新の [`tauri-driver`] をインストールするか、既存のインストールを更新します: + +```shell +cargo install tauri-driver --locked +``` + +Tauri は、現在、各プラットフォームのネイティブ [WebDriver] サーバーを利用しているため、サポートされているプラ​​ットフォームで [`tauri-driver`] を実行するには以下のようにいくつかの前提条件があります。 + +### Linux の場合 + +Linux プラットフォームでは `WebKitWebDriver` を使用します。このバイナリが既にシステム内にあるかどうかを確認してください(コマンド `which WebKitWebDriver` で確認できます)、というのも、ディストリビューションによっては、このバイナリが通常の WebKit パッケージにバンドルされているためです。 +他のプラットフォームでは、たとえば Debian ベースのディストリビューションの `webkit2gtk-driver` のように、別のパッケージが用意されている場合があります。 + +### Windows の場合 + +アプリケーションをビルドおよびテストしている Windows Edge のバージョンと一致する [マイクロソフト・エッジ・ウェブドライバ] のバージョンを必ず取得してください。 +そのバージョンは、最新版 Windows のインストールではほぼ常に最新の安定版バージョンになるはずです。 +この二つのバージョンが一致しない場合は、接続時に「WebDriver テスト・スイート」がハングする可能性があります。 + + + +**テスト・スイート** testing suite: ソフトウェアの検証時に用いる一連の「テスト・ケース」を効率的に実行するために一纏まりにしたもの。 + + + +ダウンロードには `msedgedriver.exe` というバイナリが含まれています。[`tauri-driver`] は `$PATH` でそのバイナリを検索するので、パス上でアクセス可能になっていることを確認するか、[`tauri-driver`] で `--native-driver` オプションを使用してください。 +Windows [CI](#継続的インテグレーションci) マシン上で Edge と Edge Driver とのバージョンが確実に同期するようにするために、CI セットアップ・プロセスの一環として自動的にダウンロードしたいと思うかもしれません。 +この処理の実行方法に関する手引きは後日追加されるものと思われます。 + +## モデル・アプリケーション事例 + + + +**モデル・アプリケーション** 原文 Example Applications: ソフトウェアの検証対象となる「アプリケーションの事例」の意味であるが、本稿では検証時の「モデル」とする事例の意味で「モデル・あっプリケーション」訳しています。 + + + +以下は、WebDriver を用いてテストされるアプリケーションの最小構成事例を作成するステップ・バイ・ステップの作成ガイドです。 + +この作成ガイドの結果と、完成した最小限のコードベースを手早く確認したい場合は、https://github.com/chippers/hello_tauri を参照してください。 + +import { LinkCard, CardGrid } from '@astrojs/starlight/components'; + + + + + + + +## 継続的インテグレーション(CI) + +上記の事例には、GitHub Actions を利用してテストするための CI スクリプトも付属していますが、この概念をもう少し詳しく説明している以下の「WebDriver CI ガイド」(次章)も興味深いかもしれません。 + + + + + +**CI/CD** ソフトウェア開発でのワークフロー自動化手法。詳しくは「[GitLab](https://about.gitlab.com/ja-jp/topics/ci-cd/)」を参照してください。 + + + +[webdriver]: https://www.w3.org/TR/webdriver/ +[`tauri-driver`]: https://crates.io/crates/tauri-driver +[tauri-driver]: https://crates.io/crates/tauri-driver +[マイクロソフト・エッジ・ウェブドライバ]: https://developer.microsoft.com/ja-jp/microsoft-edge/tools/webdriver/ +[Appium 2]: https://appium.io/docs/ja/latest/ + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/develop/Debug/tests/index.mdx b/src/content/docs/ja/develop/Debug/tests/index.mdx new file mode 100644 index 0000000000..cb413808e2 --- /dev/null +++ b/src/content/docs/ja/develop/Debug/tests/index.mdx @@ -0,0 +1,34 @@ +--- +title: テスト +description: Tauri ランタイム内外でのテスト手法 +sidebar: + order: 10 + label: 概要 +i18nReady: true +--- + +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +Tauri は、モック・ランタイム(模擬実行)を利用した単体テストと統合テストの両方をサポートしています。モック・ランタイムでは、ネイティブ WebView ライブラリは実行されません。 +詳細については、次章「[Mock Tauri APIs](モック・ランタイム)」をご覧ください。 + +Tauri は、また、WebDriver プロトコルを利用した「エンド・ツー・エンド」(自動システム全検証)のテスト・サポートも提供しています。デスクトップとモバイルの両方で動作しますが、デスクトップ WebDriver クライアントが提供されていない macOS では動作しません。 +詳細については、[WebDriver] の章をご覧ください。 + +Tauri では、ビルド自動化ツール「GitHub Action」の実行を支援するために [tauri-action] が提供されていますが、各プラットフォームがコンパイルに必要なライブラリをインストールしていれば、どの種類の「CI/CD ランナー」でも Tauri で使用できます。 + + + +**CI/CD** "Continuous Integration and Continuous +Deployment"(継続的統合/継続的展開)の略。ランナーは、CI/CD +と連携して、変更されたプロジェクトを自動的にパイプライン処理するビルドやテストを実行する機能。 + + + +[Mock Tauri APIs]: /ja/develop/tests/mocking/ +[WebDriver]: /ja/develop/tests/webdriver/ +[tauri-action]: https://github.com/tauri-apps/tauri-action + +
+ 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 +
diff --git a/src/content/docs/ja/develop/Debug/tests/mocking.md b/src/content/docs/ja/develop/Debug/tests/mocking.md new file mode 100644 index 0000000000..e2b3ec895f --- /dev/null +++ b/src/content/docs/ja/develop/Debug/tests/mocking.md @@ -0,0 +1,190 @@ +--- +title: Mock Tauri APIs(モック・ランタイム) +sidebar: + order: 10 +i18nReady: true +--- + +import TranslationNote from '@components/i18n/TranslationNote.astro'; + +フロントエンド・テストを作成する場合、ウィンドウをシミュレートしたり IPC 呼び出しをインターセプトしたりするための「仮の」Tauri 環境(いわゆる **モッキング**)を用意するのが一般的です。 +[`@tauri-apps/api/mocks`] モジュールは、簡単にこの擬似環境を実現するための便利なツールをいくつか提供しています: + +:::caution + +疑似環境でのテスト毎の変更(モックでの状態変化)を取り消すために、各テストの実行後に必ず「モック」をクリアしてください。詳細については、目次 **Reference** の「Mock」の章にある [`clearMocks()`] のドキュメントを参照してください。 + +::: + +## IPC 要求 + +テストでの最も一般的な検証事項は、「IPC 要求」をインターセプトすることです。これはさまざまな状況で役立ちます。たとえば: + +- 正しいバックエンド呼び出しが行なわれていることを確認する +- バックエンド関数からの異なる結果をシミュレーションする + +Tauri では「IPC 要求」をインターセプトするための mockIPC 関数が利用できます。具体的な API の詳細については、[こちら][`mockipc()`] をご覧ください。 + +:::note + +以下の事例では テスト・フレームワークの [Vitest] を使用していますが、[jest] のような他のフロントエンド・テスト・ライブラリを使用することもできます。 + +::: + +```javascript +import { beforeAll, expect, test } from "vitest"; +import { randomFillSync } from "crypto"; + +import { mockIPC } from "@tauri-apps/api/mocks"; +import { invoke } from "@tauri-apps/api/core"; + +// 「jsdom テスト環境」には WebCrypto 実装が付属していません +beforeAll(() => { + Object.defineProperty(window, 'crypto', { + value: { + // @ts-ignore + getRandomValues: (buffer) => { + return randomFillSync(buffer); + }, + }, + }); +}); + + +test("invoke simple", async () => { + mockIPC((cmd, args) => { + // 二つの数字を加算するだけの「add」という Rust コマンドをシミュレートします + if(cmd === "add") { + return (args.a as number) + (args.b as number); + } + }); +}); +``` + +時には IPC 呼び出しに関するより多くの情報を追跡したい場合があります; たとえば、コマンドは何回呼び出されたか、そもそもコマンドは呼び出されたのかどうか、などです。 +このようなテストには、他のスパイ・ツール(監視)およびモック・ツールと一緒に [`mockIPC()`] を使用できます。 + +```javascript +import { beforeAll, expect, test, vi } from "vitest"; +import { randomFillSync } from "crypto"; + +import { mockIPC } from "@tauri-apps/api/mocks"; +import { invoke } from "@tauri-apps/api/core"; + +// 「jsdom テスト環境」には WebCrypto 実装が付属していません +beforeAll(() => { + Object.defineProperty(window, 'crypto', { + value: { + // @ts-ignore + getRandomValues: (buffer) => { + return randomFillSync(buffer); + }, + }, + }); +}); + + +test("invoke", async () => { + mockIPC((cmd, args) => { + // 二つの数字を加算するだけの「add」という Rust コマンドをシミュレートします + if(cmd === "add") { + return (args.a as number) + (args.b as number); + } + }); + + // vitest が提供するスパイ・ツールを使用して、モック化された関数を追跡することができます。 + const spy = vi.spyOn(window.__TAURI_INTERNALS__, "invoke"); + + expect(invoke("add", { a: 12, b: 15 })).resolves.toBe(27); + expect(spy).toHaveBeenCalled(); +}); +``` + + + +**モック化** mocked function「モック化された関数」。テスト環境などで呼び出されるモック関数で指定され、仮想的・擬似的に実行される(仮の)関数。 + + + +「[サイドカー]」(埋め込まれた外部プログラム)やシェル・コマンドへの IPC 要求をモック化するには、`spawn()` または `execute()` が呼び出されたときのイベント・ハンドラーの ID を取得し、この ID を使用してバックエンドが返信するイベントを発行させます: + +```javascript +mockIPC(async (cmd, args) => { + if (args.message.cmd === 'execute') { + const eventCallbackId = `_${args.message.onEventFn}`; + const eventEmitter = window[eventCallbackId]; + + // 「標準出力 Stdout」イベントは何度でも呼び出し可能です + eventEmitter({ + event: 'Stdout', + payload: 'some data sent from the process', + }); + + // 「プロミス」での処理を完了するには、最後に「Terminated」イベントを呼び出します + eventEmitter({ + event: 'Terminated', + payload: { + code: 0, + signal: 'kill', + }, + }); + } +}); +``` + + + +**プロミス** Promise: Promise は JavaScript で非同期処理が完了したときに結果(resolve または reject)を返すオブジェクトです。 + + + +## Windows の場合 + +Windows では、時として Windows 固有のコード(たとえば、スプラッシュ・スクリーン・ウィンドウ)のために、異なるウィンドウのシミュレーションが必要となる場合があります。 +[`mockWindows()`] メソッドを使用すると、仮のウィンドウ・ラベルを作成できます。最初の文字列が「現在の」ウィンドウ(つまり、JavaScript 自身がそのウィンドウ内にあると認識しているウィンドウ)を識別し、その他の文字列は追加ウィンドウとして扱われます。 + +:::note + +[`mockWindows()`] はウィンドウの存在を見せ掛けるだけで、ウィンドウのプロパティを擬装するわけではありません。ウィンドウのプロパティをシミュレートするには、[`mockIPC()`] を使用して正規の呼び出しをインターセプトする必要があります。 + +::: + +```javascript +import { beforeAll, expect, test } from 'vitest'; +import { randomFillSync } from 'crypto'; + +import { mockWindows } from '@tauri-apps/api/mocks'; + +// 「jsdom テスト環境」には WebCrypto 実装が付属していません +beforeAll(() => { + Object.defineProperty(window, 'crypto', { + value: { + // @ts-ignore + getRandomValues: (buffer) => { + return randomFillSync(buffer); + }, + }, + }); +}); + +test('invoke', async () => { + mockWindows('main', 'second', 'third'); + + const { getCurrent, getAll } = await import('@tauri-apps/api/webviewWindow'); + + expect(getCurrent()).toHaveProperty('label', 'main'); + expect(getAll().map((w) => w.label)).toEqual(['main', 'second', 'third']); +}); +``` + +[`@tauri-apps/api/mocks`]: /reference/javascript/api/namespacemocks/ +[`mockipc()`]: /reference/javascript/api/namespacemocks/#mockipc +[`mockwindows()`]: /reference/javascript/api/namespacemocks/#mockwindows +[`clearmocks()`]: /reference/javascript/api/namespacemocks/#clearmocks +[Vitest]: https://vitest.dev +[jest]: https://jestjs.io/ja/ +[サイドカー]: /ja/develop/sidecar.mdx + +
+ 【※ この日本語版は、「Jan 22, 2025 英語版」に基づいています】 +