Linuxmaniaトップ活用ガイドDogtail を使ってみよう

Linuxmania:活用ガイド


■ Dogtail を使ってみよう


Dogtail は、GUIアプリケーション用の自動テストツールです。
スクリプトにより、GUIを自動的に操作させることができます。
Linuxmania製品の出荷時の動作テストにも使用されている技術です。


手順


1. Dogtail とは?


 Dogtail は、GUIアプリケーション用の自動テストツールで、
 Python 言語向けモジュールとして提供されています。
 バックエンドに AT-SPI(Assistive Technology Service Provider Interface) を
 利用しています。

 Dogtail のパッケージには、
  (1) dogtail モジュール (Python スクリプトから利用されます)
  (2) AT-SPI Browser (GUI アプリのツリー構造を表示します)
  (3) Dogtail Script Recorder (ユーザの GUI 操作を記録します)
 の3つが収録されています。



2. AT-SPI(Assistive Technology Service Provider Interface) とは?


 GUI アプリケーションの部品構成を論理的ツリー構造で表現し、
 GUI 部品の情報取得や操作を可能にするものです。

 ツリーの各ノードはName(名前), RoleName(GUI部品タイプ), Description(説明),
 Actions(許可されている操作), States(GUI部品の状態) などの情報を持ちます。

 論理ツリー構造は AT-SPI Browserで見ることができます。



 AT-SPI は、スクリーンリーダや拡大鏡、DogtailやLDTPから利用されています。
 Dogtail の検索では、Name や RoleName、Description などの情報が利用されています。



3. Dogtail の考え方


 手続き指向、オブジェクト指向、いずれの場合でも、ツリーの上から順番にたどっていき、
 目標のGUI部品に近づいてから操作する形をとります。


3.1 手続き指向の場合


 目標GUI部品の上の部品にフォーカスを当ててから、操作(クリックなど)を実行します。


[例]
  from dogtail.procedural import *
  ...
  focus.application('gedit')              # (1) アプリケーション
  focus.frame('test.txt (~) - gedit')    # (2) ウィンドウ
  click('ファイル(F)', roleName='menu')  # (3) メニュー
  click('保存(S)', roleName='menu item') # (4) メニューアイテム


3.2. オブジェクト指向の場合


 GUI部品に対応するNodeオブジェクトを取得後、Nodeオブジェクトに対し操作を指示します。


[例]
  from dogtail.tree import *
  ...
  gedit = root.application('gedit')                        # (1) アプリケーション
  gedit_win = gedit.window('test.txt (~) - gedit')         # (2) ウィンドウ
  gedit_win.child('ファイル(F)', roleName='menu').click()  # (3) メニュー
  gedit_win.child('保存(S)', roleName='menu item').click() # (4) メニューアイテム


3.3 例 (gedit) のツリー構成





4. Dogtail のインストール方法


 Fedora、CentOS、Ubuntu では標準リポジトリに収録されています。


[Fedora, CentOS]
# yum install dogtail

[Ubuntu]
$ sudo apt-get install python-dogtail


 Dogtail の初回利用前に、支援技術を有効にする必要があります。
 支援技術を有効にするには、[システム]→[設定]→[ユーザ向け]→[支援技術]で
 「支援技術を有効にする」にチェックを入れ、一度ログアウトします。



5. Dogtail の利用方法


 Python スクリプトを作成後、端末から実行します。
 スクリプトの作成方法には3つあります。

 (1) Dogtail Script Recorder を利用する
 (2) 自分で作成する(手続き指向モジュールを利用)
 (3) 自分で作成する(オブジェクト指向モジュールを利用)


5.1. Dogtail Script Recorder を利用する


 GNOMEメニュー [アプリケーション]→[プログラミング]→[Dogtail Script Recorder] を実行します。
 [●録画] を押すとGUIに対する操作の記録を開始します。[□停止] を押すまでの間、操作が記録されます。





 ※ただし、マウスカーソルの移動量などは記録できません。
  また、一部取りこぼす操作があるため、保存後に少し修正する必要があります。

 [演奏] を押すと、記録された操作が自動的に実行されます。
 [保存] を押すとスクリプトをファイルに保存できます。


5.2. 自分で作成する (手続き指向モジュールを利用)


 エディタで Python スクリプトを自作します。
 手続き指向モジュールを利用する場合は、次のように書き始めます。


#!/usr/bin/env python
# -*- encoding:UTF-8 -*-

from dogtail.procedural import *


5.3. 自分で作成する (オブジェクト指向モジュールを利用)


 エディタで Python スクリプトを自作します。
 オブジェクト指向モジュールを利用する場合は、次のように書き始めます。


#!/usr/bin/env python
# -*- encoding:UTF-8 -*-

from dogtail.tree import *



6. サンプルソース


6.1. 手続き指向モジュール (dogtail.procedural)


 1| #!/usr/bin/env python
 2| # -*- encoding:UTF-8 -*-
 3| from dogtail.procedural import *
 4| 
 5| run('gedit', 'test.txt')
 6| focus.application('gedit')
 7| focus.frame('test.txt (~) - gedit')
 8| type("test")
 9| click('ファイル(F)', roleName='menu')
10| click('保存(S)', roleName='menu item')
11| click('ファイル(F)', roleName='menu')
12| click('終了(Q)', roleName='menu item')


3行…dogtail.procedural (手続き指向モジュール) をimport
5行…gedit を起動し、test.txt を開きます
6行…geditにフォーカスを当てます
7行…geditのウィンドウにフォーカスを当てます
8行…文字列「test」を入力
9行…メニュー [ファイル(F)] をクリック
10行…メニューアイテム [保存(S)] をクリックし、ファイルを保存
11行…メニュー「ファイル(F)」をクリック
12行…メニューアイテム「終了(Q)」をクリックし、gedit を終了


6.2. オブジェクト指向モジュール (dogtail.tree)


 1| #!/usr/bin/env python
 2| # -*- encoding:UTF-8 -*-
 3| from dogtail.tree import *
 4| 
 5| run('gedit test.txt')
 6| gedit = root.application('gedit')
 7| gedit_win = gedit.window('test.txt (~) - gedit')
 8| type("test")
 9| gedit_win.child('ファイル(F)', roleName='menu').click()
10| gedit_win.child('保存(S)', roleName='menu item').click()
11| click('ファイル(F)', roleName='menu')
12| click('終了(Q)', roleName='menu item')


3行…dogtail.tree (オブジェクト指向モジュール) をimport
5行…gedit を起動し、test.txt を読み込みます
6行…gedit アプリケーションを指す Application オブジェクトを取得します
7行…gedit ウィンドウを指す Node オブジェクトを取得します
8行…文字列「test」を入力
9行…メニュー [ファイル(F)] をクリック
10行…メニューアイテム [保存(S)] をクリックし、ファイルを保存
11行…メニュー「ファイル(F)」をクリック
12行…メニューアイテム「終了(Q)」をクリックし、gedit を終了



7. Dogtail API解説


7.1. dogtail.procedural モジュール (手続き指向)


7.1.1 アプリケーションの実行


[関数]
  run(application, arguments='')

[引数]
  application … 起動するコマンド名 (文字列)
  arguments   … 起動時に与える引数 (文字列)

[例]
  run('gedit', arguments='test.txt')


7.1.2 GUI部品にフォーカスを当てる


7.1.2.1 アプリケーションにフォーカスを当てる


[関数]
  focus.application(name)

[引数]
  name … アプリケーション名 (文字列)

[例]
  focus.application('soffice')


7.1.2.2 ウィンドウにフォーカスを当てる


[関数]
  focus.frame(name)

[引数]
  name … ウィンドウ名 (文字列)

[例]
  focus.frame('test.txt - gedit')


7.1.2.3 ダイアログにフォーカスを当てる


[関数]
  focus.dialog(name)

[引数]
  name … ダイアログ名 (文字列)

[例]
  focus.dialog('別名で保存…')


7.1.2.4 テキストエリアにフォーカスを当てる


[関数]
  focus.text(name)

[引数]
  name … テキストエリア名 (文字列) (省略可)

[例]
  focus.text()



7.1.3 GUI部品に対する操作


7.1.3.1 GUI部品をクリックする


[関数]
  click(name='', roleName='', description='', raw=True, button=1, delay=1.0)

[引数]
  name … クリックしたいアイテムの名前を指定 (デフォルトでは指定なし)
  roleName … クリックしたいアイテムのroleNameを指定 (デフォルトでは指定なし)
  description … クリックしたいアイテムの説明文を指定 (デフォルトでは指定なし)
  button … マウスのどのボタンでクリックするか指定 (1(左)、2(中)、3(右))
  delay … クリック後の待ち時間(ディレイ)

[例]
  click('保存(S)', roleName='menu item')


7.1.3.2 GUI部品にテキストを入力する


[関数]
  type(text)

[引数]
  text … 入力するテキスト (文字列)

[例]
  type('hogehoge')


7.1.3.3 GUI部品にキー入力を行う


[関数]
  keyCombo(combo)

[引数]
  combo … 入力するキー入力 (文字列)

[例]
  keyCombo("Return")
  keyCombo("<Control>s")



7.2. dogtail.tree モジュール (オブジェクト指向)


7.2.1 Root クラス


 AT-SPI ツリーのルートノードを表すクラスです。
 Root クラスは Node の派生クラスです。

 dogtail.tree.root オブジェクトとして作成済みです。


[メソッド]
  applications()
  application(appName) … アプリケーションを検索して Application オブジェクトを返します

[引数]
  appName … アプリケーション名 (文字列)


7.2.2 Application クラス


 アプリケーションを表すクラスです。
 Application クラスは Node の派生クラスです。


7.2.2.1 ウィンドウを検索する


[メソッド]
  window(windowName, recursive=False)

[引数]
  windowName … ウィンドウ名 (文字列)
 recursive … 再帰的に検索するか指定 (論理値) (省略可)


7.2.2.2 ダイアログを検索する


[メソッド]
  dialog(dialogName, recursive=False)

[引数]
  dialogName … ダイアログ名 (文字列)
 recursive … 再帰的に検索するか指定 (論理値) (省略可)



7.2.3 Node クラス


 GUI部品を表すクラスです。
 アプリケーションの構成にあわせ、ツリー構造を形成します。


7.2.3.1 自ノードをクリックする


[メソッド]
  click(button=1)

[引数]
  button … クリックするボタンを指定 (1(左)、2(中)、3(右)) (省略可)


7.2.3.2 条件を指定して子ノードを検索する


[メソッド]
  child(name='', roleName='', description='', recursive=True)

[引数]
  name … GUI部品の名前を指定 (文字列) (省略可)
  roleName … GUI部品のタイプを指定 (文字列) (省略可)
  description … GUI部品の説明文を指定 (文字列) (省略可)
  recursive … 再帰的に検索を行うか指定 (論理値) (省略可)

 ※name、roleName、description のうちどれか1つは必ず指定する必要があります


7.2.3.3 自ノードにテキストを打ち込む


[メソッド]
  typeText(string)

[引数]
  string … 打ち込む文字列 (文字列)


7.2.3.4 自ノードにキー入力を行う


[メソッド]
  keyCombo(comboString)

[引数]
  comboString … キー入力を指定 (文字列)


7.2.3.5 メニューノードを検索する


[メソッド]
  menu(menuName, recursive=True)

[引数]
  menuName … メニュー名を指定 (文字列)
 recursive … 再帰的に検索するか指定 (論理値) (省略可)


7.2.3.6 メニューアイテムノードを検索する


[メソッド]
  menuItem(menuItemName, recursive=True)

[引数]
  menuItemName … メニューアイテム名を指定 (文字列)
 recursive … 再帰的に検索するか指定 (論理値) (省略可)


7.2.3.7 テキストエントリを検索する


[メソッド]
  textentry(textEntryName, recursive=True)

[引数]
  textEntryName … テキストエントリ名を指定 (文字列)
 recursive … 再帰的に検索するか指定 (論理値) (省略可)


7.2.3.8 ボタンを検索する


[メソッド]
  button(buttonName, recursive=True)

[引数]
  buttonName … ボタン名を指定 (文字列)
 recursive … 再帰的に検索するか指定 (論理値) (省略可)


7.2.3.9 ページタブを検索する


[メソッド]
  tab(tabName, recursive=True)

[引数]
  tabName … タブ名を指定 (文字列)
 recursive … 再帰的に検索するか指定 (論理値) (省略可)


7.2.3.10 プロパティ


  .children … 子ノードのリスト
  .roleName … 自ノードのroleName
  .indexInParent … 自ノードが親ノードの何番目の子か
  .actions … 自ノードが許可するアクションの辞書
  .text           # テキストをgetしたりsetしたりする
  .position       # Nodeの位置(x,y)をゲットする
  .size           # Nodeのサイズ(w,h)をゲットする
  .sensitive … 自ノードのGUI部品が有効かどうか
  .focusable … 自ノードのGUI部品がフォーカス可能かどうか



8. 参考URL


Dogtail 公式サイト
https://fedorahosted.org/dogtail/

Package dogtail (リファレンス)
https://fedorapeople.org/~zmc/dogtail/epydoc/

「Dogtailによる自動GUIテスト」
https://www.jp.redhat.com/magazine/NO24/

Dogtail's Python Modules (and how to use them)
https://www.redhat.com/magazine/021jul06/features/dogtail/

AT-SPI C Bindings Reference Manual
https://library.gnome.org/devel/at-spi-cspi/

AT-SPI Interfaces and Subinterfaces
https://www.gnome.org/~billh/at-spi-idl/

Python 2.5 公式チュートリアル
http://www.python.jp/doc/release/tut/




[作成日 2009/6/22 ]