---
# System prepended metadata

title: Ash Test Base
tags: [Chromium-General, elkurin-daily-note]

---

# Ash Test Base

テストフレームワークを考えるために情報収集。  

## 概要
[AshTestBase](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=88;drc=c00c8c446476d8e93acd49ba100468221de3b163)は`/ash`にあるテスト群のベースクラスで、[ash::Shell](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell.h;l=304;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)を用意するがbrowser processなしで走る。  

TaskEnvironmentTraitsを好きに指定する、あるいはTaskEnvironmentそのものを指定できる。   
TaskEnvironmentTraitsとは例えば[MOCK_TIME](https://source.chromium.org/chromium/chromium/src/+/main:base/test/task_environment.h;l=121;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)や、[MainThreadTypeをUIスレッドにする](https://source.chromium.org/chromium/chromium/src/+/main:base/test/task_environment.h;l=134;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)など。

testing::Testのoverrideメソッドとして[SetUp](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=109;drc=c00c8c446476d8e93acd49ba100468221de3b163)があるが、それとは別に[TestShellDelegateを指定できるSetUp](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=110;drc=c00c8c446476d8e93acd49ba100468221de3b163)が定義されている。  
[TestShellDelegate](https://source.chromium.org/chromium/chromium/src/+/main:ash/test_shell_delegate.h;l=23;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)はテスト用の[ShellDelegate](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell_delegate.h;l=56;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)インターフェースの実装で、例えば[GetBrowserWebUITabStripHeight](https://source.chromium.org/chromium/chromium/src/+/main:ash/test_shell_delegate.cc;l=125;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)のような関数のFakeを用意している。

### ash::Shellとは？
[ash::Shell](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell.h;l=304;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)はAshに存在するシングルトンで、RootWindowのインターフェースを実装したグローバルにアクセス可能なAPI群。  
[様々なsingleton](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell.h;l=978-1267;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)を一括管理しており、controller系のものにだいたいアクセスできる。  
例えば[DisplayManager](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell.h;l=1172;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)、[FocusController](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell.h;l=1148;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)、[AshDBusServices](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell.h;l=1012;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)、[InputDeviceTracker](https://source.chromium.org/chromium/chromium/src/+/main:ash/shell.h;l=988;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)。  
一意に定まりそうなやつはだいたいここ。

このセットアップは結構大変。

## AshTestBase の API
Ash用のセットアップをしてくれるだけでなく、テスト用のAPIを用意してくれている。

[CreateTestWidget](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=140;drc=c00c8c446476d8e93acd49ba100468221de3b163)はwidgetを作ってshowする。  
ここでは`bounds`と`show`するかと`container_id`を指定できる。  
また偽Widgetをinjectできるように[WidgetDelegate](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/widget/widget_delegate.h;l=35;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)も指定できるようになっている。  
作ったWindowはPrimaryRootWindowのdirect childとしてattachされる。
実際にWidgetを作ってくれるのは[TestWidgetBuilder](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/test_widget_builder.h;l=24;drc=06cdbd2560e60577f26a75b4f80a67d43471f2fd)さん。次のセクションでみる。

似たAPIとして[CreateFramelessTestWidget](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=147;drc=c00c8c446476d8e93acd49ba100468221de3b163)、[CreateAppWindow](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=158;drc=c00c8c446476d8e93acd49ba100468221de3b163)、[CreateToplevelTestWindow](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=177;drc=c00c8c446476d8e93acd49ba100468221de3b163)などがあるが、どれもちょっとずつプロパティの違ったWindow creator。

他には[PressAndReleaseKey](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=223;drc=c00c8c446476d8e93acd49ba100468221de3b163)という`key_code`を指定してタイプイベントを送るAPIもある。これはEventGeneratorにパスするだけ。  
似たものに[Left/RightClickOn](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=227-231;drc=c00c8c446476d8e93acd49ba100468221de3b163)という、指定した`view`の上にクリックイベントを飛ばすものがある。これは、viewの真ん中に当たるポイントまでまず[MoveMouseTo](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.cc;l=557;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)してからClickするという優れもの。  
[GestureTapOn](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.cc;l=568;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)も同じやつのTouchイベント版。

キーボードは、[SetVirtualKeyboardEnabled](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=369;drc=c00c8c446476d8e93acd49ba100468221de3b163)でバーチャルも対応している。  
virtual keyboardはShellに存在する[KeyboardController](https://source.chromium.org/chromium/chromium/src/+/main:ash/public/cpp/keyboard/keyboard_controller.h;l=33;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)によって管理されており、そこのflagをset/unsetするだけでvirtual keyboardのサポートを切り替えられる。

[Enter/ExitOverview](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=237-241;drc=c00c8c446476d8e93acd49ba100468221de3b163)はoverview modeを出入りする。

UI以外にも、[Session ManagerやLogin系のAPIたち](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=316-365;drc=c00c8c446476d8e93acd49ba100468221de3b163)が用意されている。  
ちなみにこのSession系がない[NoSessionAshTestBase](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/ash_test_base.h;l=422;drc=c00c8c446476d8e93acd49ba100468221de3b163)も用意されている。

## TestWidgetBuilder
[TestWidgetBuilder](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/test_widget_builder.h;l=24;drc=06cdbd2560e60577f26a75b4f80a67d43471f2fd)は指定された[Widget::InitParams](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/test_widget_builder.h;l=91;drc=06cdbd2560e60577f26a75b4f80a67d43471f2fd)を元にWidgetを作ってくれるテスト用のビルダー。

2つの作り方がある。  
[BuildOwnedByNativeWidget](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/test_widget_builder.h;l=79;drc=06cdbd2560e60577f26a75b4f80a67d43471f2fd)はnative window (Ashではaura::Window)によって管理されるraw pointer。  
[BuildOwnsNativeWidget](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/test_widget_builder.h;l=88;drc=06cdbd2560e60577f26a75b4f80a67d43471f2fd)は逆にownershipも持てるwidgetでaura::Windowをownする。返り値はWidgetのunique ptr。  
実際の挙動と同じなのは前者だが、後者もテスト側で管理したい際には良い。  

TestWidgetBuilderには[SetBounds](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/test_widget_builder.cc;l=65;drc=7ea982dd12065683edd7eb7fccb482928b0e0296)などの各種セッターがあり、init_paramsを指定できる。  
これで出来上がったinit_paramsを元にwidgetを[Init](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/widget/widget.cc;l=382;drc=7c06a7a69d82892b8cd7446ed04e200dfed9eeae)し、必要なら[Show](https://source.chromium.org/chromium/chromium/src/+/main:ash/test/test_widget_builder.cc;l=135-136;drc=7ea982dd12065683edd7eb7fccb482928b0e0296)もする。

## Note
このTestWidgetBuilderがWidget作るパートとして独立しているので、ここに他ルールのWidget builderをinjectすると、他のタイプのwidgetに対してテストできそう？

Input eventなどは基本Ashのものがそのままクライアントでも使えるので良さそう。  
ただ、LeftClickOnのような`view`を指定するAPIは、Exoで`view`がないため場所指定にしてあげないとまずそう。