入り口に戻る

原文はこちら。翻訳にあたって、GNU フリー文書利用許諾契約書などを参考にした。

原文は LGPL に基く文書である。

Linux Desktop Testing Project - LDTP

http://ldtp.freedesktop.org

Tutorial(日本語訳)

Copyright 2004 - 2007 Novell, Inc.
Copyright 2008 - 12 Nagappan Alagappan

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Lesser General Public License, Version 2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Lesser General Public License".

You should have received a copy of the GNU GNU Lesser General Public License along with this documentation; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

(訳)

(この文書を、フリー・ソフトウェア財団発行の GNU 劣等一般公衆利用許諾契約書(バージョン 2 か、それ以降のバージョンから一つを選択)が定める条件の下で複製、頒布、あるいは改変することを許可する。この文書に変更不可部分、表紙表側の文言、表紙裏側の文言は存在しない。この利用許諾契約書の複製物は「GNU 劣等一般公衆利用許諾契約書」という章に含まれている。)

(この文書とともに、GNU 劣等一般公衆利用許諾契約書を一刷受け取ったはずだが、もし受け取っていなければ、フリー・ソフトウェア財団に請求すること。宛先は the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA である。)

著者
Nagappan A <nagappan@gmail.com>
協力者:
Harsha <nharsha@gmail.com>
Premkumar J <prem.jothimani@gmail.com>
Guofu Xu <lavixu@gmail.com>
Surendran M <suren.silverprince@gmail.com>
Vamsi B <vamsi1985@gmail.com>

目次

  1. LDTP とは
  2. 対象読者
  3. 試験(testing)とは
    1. なぜ試験を行うのか
    2. なぜ自動化するのか
    3. GUI 試験の複雑さ
    4. LDTP を使ってどのような試験が出来るのか
    5. アクセシビリティ機能に依拠した試験の利点
    6. アクセシビリティ機能に依拠した試験の缺点
    7. 試験できるアプリケーションは何れか
    8. 対応するプラットフォーム
    9. 対応する言語
  4. LDTP の特徴
  5. ウェブ / 連絡
    1. LDTP 関連サイト
    2. 開発者向けメーリングリスト
    3. IRC - インターネット・リレイ・チャッティング
  6. 動作環境
    1. 必要なディスク領域
    2. 必要なソフトウェア
      1. 以下の依存パッケージをインストールする(Linux)
      2. 随意のパッケージ(Linux)
  7. LDTP の導入
    1. GIT からソースコードをダウンロードする(Linux)
    2. GIT からソースコードをダウンロードする(Windows)
    3. GIT からソースコードをダウンロードする(Mac OS X)
    4. Linux/Mac OS X の環境でソースコードから LDTP を導入する
    5. バイナリから LDTP を導入
  8. 構成
    1. LDTP 全体の構成
    2. LDTP 内部の仕組み
      1. サーバ
      2. クライアント・ハンドラ
      3. コンポーネント・ハンドラ
      4. イベント・ハンドラ
  9. LDTP の規約
    1. Appmap
    2. Appmap 規約
  10. LDTP スクリプトから UI オブジェクトにアクセスする方法
    1. ウィンドウ名
      1. ウィンドウの諸型
      2. glob パターンに対応
      3. ウィンドウ名の表示方法の諸例
      4. ウィンドウ名の形式
    2. オブジェクト名
      1. ラベル
      2. 附属ラベル(associated label)
      3. ラベル及び附属ラベルを闕き、番号でアクセスするオブジェクトの名前
      4. 番号を用いたオブジェクト名
      5. ウィンドウ ID を用いたオブジェクト名(Windows の場合)
      6. オブジェクトの型と番号とを用いたオブジェクト識別子
      7. オブジェクト名の形式
  11. アクセシビリティ・ライブラリ
  12. アクセシビリティ機能の有効化
  13. LDTP モジュールの取り込み(importing)
    1. 関数を呼び出して操作を行う
    2. LDTP の API
  14. LDTP の利用と応用
    1. 部品を指定する
    2. プッシュ・ボタン
    3. メニュー・アイテム
    4. トグル・ボタン
    5. テキスト部
    6. テーブル部
    7. プッシュ・ボタンその二
    8. チェック・ボックス
    9. スピン・ボタン
    10. ページ・タブ
    11. チェック・メニュー・アイテム
    12. ラジオ・メニュー・アイテム
    13. コンボ・ボックス - メニューアイテム
    14. コンボ・ボックス - リスト・アイテム
    15. アプリケーションの起動
    16. GUI の有無を確認
    17. 時間の制限
    18. 素のキーボード・イベントを生成する
    19. 素のマウス・イベントを生成する
    20. アプリケーションの情報
  15. コールバック - 新たなウィンドウの生成に反応
    1. 利点
    2. 見本
    3. 記録を取る
  16. 見本のスクリプト
  17. LDTP スクリプトを実行する方法
  18. LDTP 開発陣からの提言
  19. 遠隔システムから LDTP を操作する方法
    1. LDTP エンジン (Linux)
    2. LDTP エンジン (Windows)
    3. LDTP エンジン (Mac OS X)
    4. LDTP クライアント
  20. LDTP で問題が起きた時
  21. 参考文献

LDTP とは

 Linux Desktop Testing Project(LDTP) の狙いは、高品質な自動試験の仕組みを考案し、GNU/Linux デスクトップの試験と改良に使える最先端のツール群を作り出すことである。アプリケーションのユーザ・インタフェイスを調べるにあたっては、アクセシビリティ・ライブラリ(Accessibility libraries)を使用している。この計画は Microsoft Windows や Mac OS X にも広まっており、前者では Cobra、後者では ATOMac として実装済みである。これ故に我々は自信を持って次のように言える。プラットフォームに囚われない GUI 試験ツールを実装し得たと。LDTP は今のところ、Windows / Mac / Linux / Palm Source / Solaris / NetBSD / FreeBSD で動かすことが出来る。

 LDTP の core framework では、Appmap という規約と、アプリケーションを試験する定型の試行関数とが使われている。この core 部分は、試行関数の結果を出力してくれる。LDTP は、.NET / GNOME / KDE (QT >=4.8) のアプリケーションのうち、アクセシビリティ機能が有効になっているもの全てで試験を行うことが出来る。例えば、Mozilla、Open Office/Libre Office、Java アプリケーション(ユーザ・インタフェイスに Swing を用いているものに限る)である。

 当計画に参加したいという方は歓迎する。Windows/Linux の両デスクトップに対応した、堅牢・安定で信頼できる試験ツールとその仕組みを一緒に開発してほしい。Microsoft / Apple / GNOME アクセシビリティ・チーム及び Sun Microsystems アクセシビリティ・チームの素晴らしい成果と弛まざる支援に感謝する。

対象読者

 本文書は、GUI アプリケーションの UI 制御について少しだけ学んでおり、Windows / Mac OS X / Linux あるいは Unix(Solaris / BSD 系)については最低限の知識を持つ読者を想定している。(訳註:著者の little と few の使い方)

試験(testing)とは

なぜ試験を行うのか

 試験(testing)はソフトウェア・システムの缺陥を突き止める作業である。詳しくは、http://en.wikipedia.org/wiki/Software_testing

なぜ自動化するのか

 アプリケーションを同じ手順で何度も試験する場合、自動処理の方が上手くいくであろう。

GUI 試験の複雑さ

LDTP を使ってどのような試験が出来るのか

 LDTP を用いて、アクセシビリティ機能が有効になっているアプリケーションの動作(functionality)を試すことが出来る。

アクセシビリティ機能に依拠した試験の利点

アクセシビリティ機能に依拠した試験の缺点

試験できるアプリケーションは何れか

 今のところ、LDTP で試験可能なのは .NET / GNOME アプリケーションの中、アクセシビリティ機能が有効になっているもの全てである。Mozilla、Open Office / Libre Office、Java アプリケーション(UI に Swing を用いているものに限る)、及び QT 4.8 を用いる KDE アプリケーション。

対応するプラットフォーム

対応する言語

LDTP の特徴

ウェブ / 連絡

LDTP 関連サイト

開発者向けメーリングリスト

http://lists.freedeskto.org/mailman/listinfo/ldtp-dev

IRC - インターネット・リレイ・チャッティング

 #ldtp of irc.freenod.net

動作環境

必要なディスク領域

 最大使用量は 450KB (Linux)、5 MB (Windows)、450 KB (Mac OS X)。

必要なソフトウェア

以下の依存パッケージをインストールする(Linux)

以下の依存パッケージをインストールする(Mac OS X)

随意のパッケージ(Linux)

LDTP の導入

GIT からソースコードをダウンロードする(Linux)

GIT からソースコードをダウンロードする(Windows)

GIT からソースコードをダウンロードする(Mac OS X)

Linux/Mac OS X の環境でソースコードから LDTP を導入する

バイナリから LDTP を導入

 Mac OS x / Windows / RPM / Deb / Gentoo / Solaris の最新パッケージを次の場所からダウンロード「http://ldtp.freedesktop.org/wiki/Download

構成

LDTP 全体の構成

 試験スクリプトは LDTP API インタフェイスを利用し、同 API は UNIX ソケットあるいは TCP ソケットを使って LDTP エンジンと通信する。LDTP エンジンは AT-SPI ライブラリを使って試験対象のアプリケーション(Application under test - AUT)と対話する。

LDTP 内部の仕組み

 LDTP クライアントは XML RPC プロトコルを用いて LDTP エンジンと遣り取りする。

 LDTP の構想の大部分は、http://safsdev.sf.net を参考にして肉付けした。大多数のコマンドは少なくとも二つの引数をとる。先頭の引数は文脈(context - 作業を行いたいウィンドウのこと)であり、二番目の引数は部品(component - 作業を行いたいオブジェクト、その時点の文脈に則る)である。

例:click ('*-gedit', 'btnNew')
このクリック操作は、「*-gedit」(正規表現で)という名前を持つウィンドウの中の、プッシュ・ボタン型で「New」という名前を持つオブジェクトに対して実行される。

サーバ

 試験スクリプトが始動すると、LDTP クライアントは AF_UNIX / AF_INET を使って LDTP エンジンへの接続を確立する。

クライアント・ハンドラ

 スクリプトからコマンドが実行される度に、クライアントは XML データを組み、同データをサーバに送信する。LDTP エンジンは、クライアントから来たコマンド・リクエストを解析し、該当するコンポーネント・ハンドラ(各部品を担当する処理)を呼び出す。

コンポーネント・ハンドラ

 個々の部品(component)のハンドラは、AT-SPI ライブラリを用いて各アプリケーションと通信する。実行結果に基づいて、成功したのか失敗したのかをクライアントに通知する。この返信は XML 形式で記述される。例えば「gettextvalue」のように、要求の基づいて各部品(component)のデータがクライアントに返って来ることもある。

イベント・ハンドラ

 出現時点が予想できないウィンドウ(例:相手による接続のリセット / 接続の時間切れを示すダイアログ)は、コールバック関数を登録しておくことで処理できる。登録してあったタイトル(ウィンドウ名)のウィンドウが現れる度に、該当するコールバック関数が呼び出される。このウィンドウ名の指定は正規表現でも構わない。

LDTP の規約

Appmap

 「Appmap」[Application Map の略]は、試験中の GUI を文字列で表現したものである。ボタン、テキスト・ボックスなどの各 UI 部品は孰れも、予め定義してある規約(下表に記す)を用いて表す。その際には、同部品の親 UI オブジェクトの情報も援用する。実行時に特定の UI 部品にアクセスするには、試験中の GUI 向けに生成された Appmap を使う。Appmap について詳しく知りたければ http://safdev.sourceforge.net/DataDrivenTestAutomationFrameworks.htm#TheApplicationMap を参照。

Appmap 規約

Class keywordsappmap で使う慣用表現
ACCEL_LABEL
ALERTdlg
ANIMATION
ARROW
CALENDARcal
CANVAScnvs
CHECK_BOXchk
CHECK_MENU_ITEMmnu
COLOR_CHOOSER
COLUMN_HEADER
COMBO_BOXcbo
DATE_EDITOR
DESKTOP_ICON
DESKTOP_FRAMEfrm
DIALdial
DIALOGdlg
DIRECTORY_PANE
DRAWING_AREAdwg
FILE_CHOOSERdlg
FILLERflr
FONT_CHOOSERdlg
FRAMEfrm
GLASS_PANE
HTML_CONTAINERhtml
ICONico
IMAGEimg
INTERNAL_FRAME
LABELlbl
LAYERED_PANEpane
LISTlst
LIST_ITEMlsti
MENUmnu
MENU_BARmbar
MENU_ITEMmnu
OPTION_PANEopan
PAGE_TABptab
PAGE_TAB_LISTptl
PANELpnl
PASSWORD_TEXTtxt
POPUP_MENUpop
PROGRESS_BARpbar
PUSH_BUTTONbtn
RADIO_BUTTONrbtn
RADIO_MENU_ITEMmnu
ROOT_PANErpan
ROW_HEADERrhdr
SCROLL_BARscbr
SCROLL_PANEscpn
SEPARATORsep
SLIDERsldr
SPIN_BUTTONsbtn
SPLIT_PANEsplt
STATUS_BARstat
TABLEtbl
TABLE_CELLtbl
TABLE_COLUMN_HEADERtch
TABLE_ROW_HEADERtrh
TEAROFF_MENU_ITEMtmi
TERMINALterm
TEXTtxt
TOGGLE_BUTTONtbtn
TOOL_BARtbar
TOOL_TIPttip
TREEtree
TREE_TABLEttbl
UNKNOWNunk
VIEWPORTview
WINDOWdlg
EXTENDED
HEADERhdr
FOOTERfoot
PARAGRAPHpara
RULERrul
APPLICATIONapp
AUTOCOMPLETEtxt
CALENDARVIEWcal
CALENDAREVENTcal
EDITBARtxt
ENTRYtxt

LDTP スクリプトから UI オブジェクトにアクセスする方法

 オブジェクトに働きかけるための主要な二つの媒体、「ウィンドウ名」と「オブジェクト名」。

ウィンドウ名

 ウィンドウに指示を出すには、ウィンドウ名を知らなければならない。ここで言うウィンドウ名とはウィンドウのタイトルのことである。

ウィンドウの諸型

  1. Frame (frm)
  2. Dialog (dlg)
  3. Alert (dlg)
  4. Font Chooser (dlg)
  5. File Chooser (dlg)
  6. Window (この型には大抵タイトルがないので、表すのに要素番号(index)を用いる - dlg)

glob パターンに対応

 ウィンドウ名は、glob パターン( * や ? など)を使って纏めて指定できる。

ウィンドウ名の表示方法の諸例

  1. ウィンドウの型とウィンドウのタイトル (例:frmUnsavedDocument1-gedit)
  2. ウィンドウのタイトル (例:Unsaved Document 1 - gedit)
  3. ウィンドウの型、glob 表現、ウィンドウ・タイトルの一部 (例:frm*-gedit)
  4. glob パターンとウィンドウ・タイトルの一部 (例:*-gedit)
  5. ウィンドウの型、ウィンドウ・タイトルの一部、及び glob パターン (例:frmUnsavedDocument1*)
  6. ウィンドウの型、ウィンドウのタイトル、及び要素番号(index) (同じタイトルのウィンドウが二つ同時に存在する場合の例:一番目「dlgAppoinment」二番目「dlgAppoinment1」)
  7. ウィンドウの型と要素番号 (ウィンドウに利用可能なタイトルが無い場合に限る、例:dlg0)

ウィンドウ名の形式

 もしウィンドウのラベル(表示文字列)に空白文字や改行文字が含まれている場合、それらは取り除かれる。

  1. 「Unsaved Document 1 - gedit」は「UnsavedDocument1-gedit」で表す。
  2. 「Unsaved Document 1
    -
    gedit」は「UnsavedDocument1-gedit」で表す。

オブジェクト名

 オブジェクト(作業を行いたい部品)は、ラベルそのものとして同定可能であるか、さもなければ附属ラベルによって指定できる。

ラベル

 メニュー、メニュー・アイテム、プッシュ・ボタン、トグル・ボタンのような部品全般は、それらのラベルを通じてアクセスできる。

mnuFile (gedit のメニュー)
mnuNew (gedit のメニュー・アイテム)
btnNew (gedit のツール・バー、プッシュ・ボタン)
tbtnLocation (gedit のファイルを開くダイアログ、トグル・バー部)

附属ラベル(associated label)

 テキスト、テーブル、チェック・ボックス、ラジオ・ボタン、スピン・ボタン、コンボ・ボックス、これらの部品は総じて附属ラベルを使わなければアクセスできない。

txtLocation (gedit のファイルを開くダイアログ、テキスト部)
tblFiles (gedit のファイルを開くダイアログ、テーブル部)
choSearchfor (gedit の Find ダイアログ、コンボ・ボックス部)
chkMatchcase (gedit の Find ダイアログ、チェック・ボックス部)
sbtnRightmarginatcolumn (gedit の Preferences ダイアログ、スピン・ボタン部)

ラベル及び附属ラベルを闕き、番号でアクセスするオブジェクトの名前

 ラベルも附属ラベルも無い部品は、番号(index)を用いてアクセス出来る。

txt0 (gedit のテキスト表示領域)
ptl0 (gedit の Preferences ダイアログ、ページ・タブ・リスト部)
ptl0 (gedit では複数のファイルを開いている時、ページ・タブ・リスト部が現れる)

番号を用いたオブジェクト名

 同一ウィンドウ上の複数の場所に同型の部品が存在し、且つそれらのラベルが同じであるという状況も考えられる。その場合、最初の部品は標準の記法でアクセスできるが、二番目以降の部品は「部品の型」「ラベルもしくは附属ラベル」「番号」の形式で記述してアクセスする。この際、番号は 1 から数え始める。

btnAdd - 第一のプッシュ・ボタン部で、ラベルは Add である。
btnAdd1 - 第二のプッシュ・ボタン部で、ラベルは Add である。
btnAdd2 - 第三のプッシュ・ボタン部で、ラベルは Add である。

ウィンドウ ID を用いたオブジェクト名(Windows の場合)

 オブジェクトはウィンドウ ID と一対一で結び付くものと考えて良い。ある時点で実行中のアプリケーション全てを通じて、ウィンドウ ID は唯一無二のものである。これは i18n/l10n の環境でも変わらない。API に渡すオブジェクト名は、先頭に「#」、それに続けてウィジェットを表す唯一無二の数字を書いたものとなる。

#1234 - 「Visual UI Verify」では、Automation ID として使える。

オブジェクトの型と番号とを用いたオブジェクト識別子

 特定ウィンドウにおいて、ウィジェット型を同じくするものの中での番号によって、部品を指定する。オブジェクト名の形式は、LDTP 規約の下でのオブジェクト型、続けて同型オブジェクトの中でのオブジェクト番号(index)、となる。

btn#0 - 特定ウィンドウにおける第一のボタン。
txt#1 - 特定ウィンドウにおける第二のテキスト・ウィジェット

オブジェクト名の形式

 オブジェクトのラベルあるいは附属ラベルに空白、ドット、コロン、アンダースコア、改行の文字が含まれる場合、これらは取り除かれる。

「Search for」は「Searchfor」となる。

「File name 'a_txt' already exist.
Replace」は「Filename'atxt'alreadyexistReplace」となる。

アクセシビリティ・ライブラリ

 LDTP は、GNOME 環境に備わるアクセシビリティ・ライブラリを利用している。アクセシビリティを使うことで、アプリケーションの情報と、同アプリケーションの状態(プロパティ)に関する情報とを取得できる。アプリケーションの各層を自由に利用できるようにするための唯一無二の条件は、同アプリケーションのアクセシビリティ機能が有効であることである。

アクセシビリティ機能の有効化

GNOME 2.x の場合、GNOME コントロール・センターにて支援技術(訳註:要確認)を開く。

図 1:GNOME コントロール・センターにおける支援技術の設定(訳註:要確認)。

GNOME 3.x: 次のコマンドを打ち込み、アクセシビリティ機能を有効にする。

gsettings set org.gnome.desktop.interface toolkit-accessibility true

Microsoft Windows: 設定を弄る必要は無い。標準でアクセシビリティ機能が有効になっている。

Mac OS X: システム全体のアクセシビリティを有効にしなければならない。「System Preferences」 > 「Universal Access」 > 「補助装置を使用可能にする」(Enable access for assistive devices)。有効化に失敗したときは、何らかのモジュールの使用時に例外「ErrorAPIDisabled」が発生する。

図 2:支援技術設定画面のスクリーン・ショット(訳註:要確認)

LDTP モジュールの取り込み(importing)

from ldtputils import *

玄論:「import ldtp」ではなく上記の形式で取り込むのには理由がある。上の方法を選べば、ldtp の全ての関数が関数名だけで直接呼び出せるようになるからである。モジュールを「import ldtp」で取り込んだ場合、先と同じ関数を呼び出すのに「ldtp.<関数名>」と書かなければならない。

例 1:

from ldtp import *
selectmenuitem ('*-gedit', 'mnuFile;mnuNew')

例 2:

import ldtp
ldtp.selectmenuitem ('*-gedit', 'mnuFile;mnuNew')

関数を呼び出して操作を行う

 LDTP は大抵、指定したウィンドウの中の特定のオブジェクトに働きかける。

 メニュー・アイテムを選ぶには、関数 selectmenuitem を呼び出す。例を挙げると、アプリケーション「gedit」でメニュー・アイテムの「Open」を選択するには次の関数を呼び出す。

 上の関数呼び出しを行うと、新しいダイアログ・ボックスが出て来る。ウィンドウが開いたかどうかは、guiexist もしくは waittillguiexist を使って確かめることができる。

 ウィンドウ中のプッシュ・ボタンに働きかけたい場合、関数 click を用いる。

 GTK の「開くファイルを選ぶ画面」において、「Cancel」ボタンを押すには、

 上の操作を行うと、GTK のファイル選択画面が消える。実際にウィンドウが消えたか否かを確認するには、関数 waittillguinotexist を用いる。

 gedit では開いたファイルに手を加えると、そのウィンドウのタイトルも変更される。同じウィンドウで作業を続けるには、作業の文脈(context)を切り替える必要がある。理由:察しの通り、LDTP は個々のウィンドウを対象に据えて動作する。それゆえ、ウィンドウのタイトルが変更されると、ウィンドウの文脈(context)も変わる。対策は、関数 setcontext を用いること、及び文脈が不要になったら releasecontext を用いることである。

 開いたファイルのうち、現在表示されているものを編輯するには、

 これによって、ウィンドウのタイトルが変わる。上記操作を行う前のタイトルが「Unsaved Document 1 - gedit」であれば、編輯後のタイトルは「*Unsaved Document 1 - gedit」のようになる。同じウィンドウに対して続けて操作を行うには、

 これによって、同じウィンドウ名を使い続けることができるようになる。例えば、

 この関数で GTK の保存画面(save dialog box)が呼び出される。

 動作を齎す関数(selectmenuitem、click、settextvalue など)が蹉跌した場合、例外が発生する。この例外はプログラム側で処理しなければならず、実行中の操作を続けるか、あるいは単に停止するか、どちらかの措置をとる。

LDTP の API

LDTP の利用と応用

部品を指定する

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> guiexist ('*-gedit')
1
>>> guiexist ('frmUnsavedDocument1-gedit')
1
>>> guiexist ('frmUnsavedDocument1-*')
1
>>> guiexist ('frm*-gedit')
1
>>> guiexist ('Unsaved Document 1 - gedit')
1

プッシュ・ボタン

 gedit のウィンドウの中にあるオブジェクトに働きかけるには、オブジェクトの情報を知っておく必要がある。

 gedit のツール・バーの一部であるプッシュ・ボタン「Open」をクリックするには、click というAPI を用いる。この際、第一引数にはウィンドウ名を、第二引数にはオブジェクト名を指定する。下のコマンドではクリック操作を行っている。利用する情報はウィンドウ名「Unsaved Document 1 - gedit」とプッシュ・ボタン部名「Open」である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> click ('*-gedit', 'btnOpen')
1

メニュー・アイテム

 ウィンドウ中のメニューの下に表示されるメニュー・アイテムを選択するには、API selectmenuitem を用いる。

 必要な情報は、ウィンドウ名「Unsaved Document 1 - gedit」、メニュー部「File」、メニュー・アイテム部「New」である。

 メニューは、階層構造を踏まえて扱わなければならない。メニュー・アイテム「New」を利用するには、メニュー部「File」も必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> selectmenuitem ('*-gedit', 'mnuFile;mnuNew')
1

トグル・ボタン

 トグル・ボタンにクリック操作を施すために必要な情報は、ウィンドウ名「OpenFiles...」(訳註:訳者の環境では「OpenFiles」)とトグル・ボタン部「Type a file name」である。(訳註:トグル・ボタン部の上にマウスを載せると「ファイル名を入力してください」「Type a file name」などと出る)

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> click ('dlgOpenFiles...', 'tbtnTypeafilename')
1

テキスト部

 テキスト・ボックスに文字列を入力するには、ウィンドウ名「Open Files...」(訳註:訳者の環境では「Open Files」)、テキスト部附属ラベル「Location:」、書き込むべき文字列「Class1.cs」が要る。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> settextvalue ('dlgOpenFiles...', 'txtLocation', 'Class.cs')
1

テーブル部

 GTK のファイルを開く画面において選択肢の一覧から一つ選ぶには、ウィンドウ名「Open Files...」(訳註:訳者の環境では「Open Files」)、テーブル名(Files - 青い円で印されたファイル群)、選択する行「Class1.cs」といった情報が必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> selectrow('dlgOpenFiles...', 'tblFiles', 'Class1.cs')
1

プッシュ・ボタンその二

 ファイル名を選択した後、ファイルの中身を開くには、プッシュ・ボタン部「Open」をクリックする必要がある。この操作には、ウィンドウ名「Open Files...」(訳註:訳者の環境では「Open Files」)、プッシュ・ボタン・ラベル名「Open」といった情報が必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> click ('dlgOpenFiles...', 'btnOpen')
1

チェック・ボックス

 チェック・ボックス部をクリックするには、ウィンドウ名「gedit Preferences」、チェック・ボックス附属ラベル名「Display line numbers」といった情報が必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> click ('dlggeditPreferences', 'chkDisplaylinenumbers')
1

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> check ('dlggeditPreferences', 'chkEnabletextwrapping')
1

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> uncheck ('dlggeditPreferences', 'chkDisplaylinenumbers')
1

スピン・ボタン

 スピン・ボタンに働きかけるには、ウィンドウ名「gedit Preferences」、スピン・ボタン部の名前「Right margin at column」といった情報が要る。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> getvalue ('dlggeditPreferences', 'sbtnRightmarginatcolumn')
80.0
>>> setvalue ('dlggeditPreferences', 'sbtnRightmarginatcolumn', '81')
1
>>> setvalue ('dlggeditPreferences', 'sbtnRightmarginatcolumn', '80')
1

ページ・タブ

 ページ・タブの列(page tab list)に働きかけるには、ウィンドウ名「gedit Preferences」、ページ・タブ列の名(ここで取り上げるページ・タブ列部品にはラベルや附属ラベルが無いため、「ptl0」となる)、ページ・タブの名前か要素番号(index)といった情報が必要である。ページ・タブの番号は 0 から始まる。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> gettabcount ('dlggeditPreferences', 'ptl0')
5
>>> selecttabindex ('dlggeditPreferences', 'ptl0', 2)
1
>>> selecttab ('dlggeditPreferences', 'ptl0', 'Editor')
1

チェック・メニュー・アイテム

 チェック・メニュー・アイテムに働きかけるには、ウィンドウ名「Unsaved Document 1 - gedit」、メニュー名「View」、チェック・メニュー・アイテム名「Side Pane」といった情報が必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> selectmenuitem ('*-gedit', 'mnuView;mnuSidePane')
1
>>> menuuncheck ('*-gedit', 'mnuView;mnuSidePane')
1

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> menucheck ('*-gedit', 'mnuView;mnuStatusbar')
1

ラジオ・メニュー・アイテム

 ラジオ・メニュー・アイテム部に働きかけるには、ウィンドウ名「Unsaved Document 1 - gedit」、メニュー名「Documents」、メニュー・アイテム名「Class1.cs」(Class1.cs を開いているものと仮定)といった情報が必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> selectmenuitem ('*-gedit', 'mnuDocuments;mnuClass1.cs')
1
>>> menucheck ('*-gedit', 'mnuDocuments;mnuClass1.cs')
1

コンボ・ボックス - メニューアイテム

 コンボ・ボックスから下に表示されるメニュー・アイテムを選ぶには、ウィンドウ名「Open Files...」(訳註:訳者の環境では「Open Files」)、コンボ・ボックス名「Character Coding」(訳註:訳者の環境では「Character Encoding」)、メニュー・アイテム名「Current Locale云々」(訳註:この場所は空白文字を省くと失敗する)といった情報が必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> comboselect ('dlgOpenFiles...', 'cboCharacterCoding', 'Current Locale (UTF-8)')
1

コンボ・ボックス - リスト・アイテム

 コンボ・ボックス部の下に表示されるリスト・アイテムに働きかけるには、ウィンドウ名「Find」、コンボ・ボックス部の名前「Search for」、リスト・アイテム中の選択肢の名前あるいはリスト・アイテムの要素番号あるいは新しいアイテム名「OdbcMetaDataCllectionNames.cs」といった情報が必要である。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> settextvalue ('dlgFind', 'cboSearchfor', 'OdbcMetaDataCollectionNames.cs')
1

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> comboselect ('dlgFind', 'cboSearchfor', 'ObdcMetaDataCollectionNames.cs')
1

アプリケーションの起動

 LDTP API の「launchapp」を用いて、試験対象のアプリケーションを起動することが出来る。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> launchapp ('gedit')
1

GUI の有無を確認

 API「guiexist」を用いて、GUI(即ちウィンドウ)の有無を確認することができる。API には類似の関数「waittillguiexist」「waittillguinotexist」も用意されている。

時間の制限

GUI timeout

 「GUI timeout」は、制限時間の初期値であり、二つの関数「waittillguiexist」「waittillguinotexist」で用いられる。関数「guitimeout」を使うと、ウィンドウが現れるか消えるかするのを指定した秒数の間だけ待つことが出来る。制限時間の初期値は 30 秒である。

 この制限時間の初期値は、以下の方法で変更することが出来る。

例 1
export GUI_TIMEOUT=30

例 2
waittillguiexist ('*-gedit', guiTimeOut=30)
waittillguinotexist ('dlgOpenFiles...', guiTimeOut=30)

例 3
guitimeout (30)

例 4
ldtp -g 30

OBJ timeout

 「OBJ timeout」は、制限時間の初期値であり、ウィンドウの内部で用いられる。関数 objtimeout を使えば、ウィンドウ中の対象オブジェクトが現れるのを指定した秒数の間だけ待つことが出来る。制限時間の初期値は 5 秒である。

 制限時間の初期値は、以下の方法で変更することが出来る。

例 1
export OBJ_TIMEOUT=5

例 2
objtimeout (5)

例 3
ldtp -o 5

素のキーボード・イベントを生成する

 操作しようとしているウィンドウのアクセシビリティ機能が有効でないこともあるし、表示を伴わないキー入力を生成しなければならないこともある(ALT、CTRL、ENTER、BACKSPACE、ESC、F1-F12、SHIFT、CAPSLOCK、TAB、PAGE UP、PAGE DOWN、HOME、END、RIGHT / LEFT / UP / DOWN ARROW KEYS、INS、DEL)。関数 generatekeyevent や関数 enterstring を用いて、利用者が打ち込んだかのようにキー・イベントを模造することができる。付記:表示しない文字は全て山型括弧で囲う。

例 1
<ctrl>lwww.google.co.in<enter>

例 2
<alt><f1>

例 3
<control>s

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> launchapp ('gedit')
1
>>> waittillguiexist ('*-gedit')
1
>>> enterstring ('<alt><tab>')
1
>>> enterstring ('*-gedit', 'txt0', '<caps>Testing enterstring API<enter>')
1
>>> generatekeyevent ('<alt><tab>')
1

素のマウス・イベントを生成する

  b1c、b1d、b2c、b2d、b3c、b3d といった素のマウス・イベントを発生させるには、スクリーン座標の X と Y を決める必要がある。ここでの b はボタン、c は単クリック、d はダブル・クリックである。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> generatemouseevent (100, 200) # 何も指定しなければ b1c
1
>>> generatemouseevent (100, 200, 'b1d') # ダブル・クリックを作り出す
1

アプリケーションの情報

 getapplist を呼び出すと、アクセシビリティ機能を組み込んだアプリケーションの中、その時実行中であったものの名前を全て取得できる。ウィンドウの中、ローカル・キャッシュにアプリケーション・マップが存在するものの一覧を取得するには、getwindowlist を用いる。あるウィンドウに属するオブジェクトの一覧を取得するには、API「getobjectlist」を用いる。あるオブジェクトに属するプロパティの中、利用可能なものの一覧を取得するには、getobjectinfo を用いる。あるオブジェクトのあるプロパティを取得するには、getobjectproperty を用いる。

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> getapplist ()
[u'gnome-session', u'gnome-power-manager', u'gnome-settings-daemon', u'Libbonoboui-Gtk-Module-init-info', u'nautilus', u'GnomeApplicationBrowser', u'/usr/lib/zen-updater/ZenUpdater.exe', u'gaim', u'gtk-window-decorator', u'gedit', u'xchat', u'gnome-panel', u'gnome-volume-manager', u'resapplet', u'nm-applet', u'soffice.bin']
>>> getwindowlist ()
[u'frmUnsavedDocument1-gedit']
>>> getobjectlist ('*-gedit')
...
>>> getobjectinfo ('*-gedit', 'btnNew')
[u'child_index', u'class', u'description', u'parent', u'label']
>>> getobjectproperty ('*-gedit', 'btnNew', 'class')
'New'

コールバック - 新たなウィンドウの生成に反応

利点

 何時表示されるのか予測がつかないウィンドウも、これを使えば簡単に処理できる。例えば、Evolution のパスワード・ダイアログ・ボックス、相手方による接続のリセットを告げるダイアログ、アプリケーションが壊れたことを告げるダイアログなど。

見本

from ldtp import *
import threading
# スレッドの作成
callbackRunning = threading.Event ()
callbackRunning.clear ()
callbackState = threading.Event ()
callbackState.clear ()
# コールバックの定義
def cb ():

callbackState.set ()
waittillguiexist ('dlgReplace')
click ('dlgReplace', 'btnClose')
callbackState.clear ()
callbackRunning.set ()
print 'callbackend'
# コールバックの登録
onwindowcreate ('Replace', cb)
# ウィンドウを作る適当な操作
click ('*gedit', 'btnReplace')
click ('*gedit', 'btnOpen')
waittillguiexist ('dlgOpenFiles...')
click ('dlgOpenFiles...', 'btnClose')
# コールバックを呼び出した場合、終了を待つ
if callbackState.isSet ():
print 'Waiting for callback to complete'
callbackRunning.wait ()
print 'callback set'
print 'test end'

記録を取る

nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> log ('test script', 'debug')
1
>>> log ('test script', 'warning')
1
>>> log ('test script', 'error')
1
>>> log ('test script', 'cause')
1

見本のスクリプト

from ldtp import *
from ldtputils import *

try:

launchapp ('gedit')
if waittillguiexist ('*-gedit') == 0:
raise LdtpExecutionError ('Gedit window does not exist')
selectmenuitem ('*-gedit', 'mnuFile;mnuOpen')
if waittillguiexist ('dlgOpenFiles') == 0:
raise LdtpExecutionError ('Open Files dialog does not exist')
selectrow('dlgOpenFiles...', 'tblFiles', fileName[0])
click('dlgOpenFiles...', 'btnOpen')
if waittillguinotexist ('dlgOpenFiles') == 0:
raise LdtpExecutionError ('Open Files dialog still exist')
except LdtpExecutionError, msg:
raise

LDTP スクリプトを実行する方法

 作業ディレクトリに下記のファイルを入れる。

python のスクリプトを実行する

$ python <script file name.py>

python gedit.py

LDTP 開発陣からの提言

遠隔システムから LDTP を操作する方法

LDTP エンジン (Linux)

 操作対象機にて LDTP エンジン(ldtp バイナリ)を起動する。二通りのやり方がある。(訳註:訳者の環境では「-s」「-p」ではなく「s」「p」である - ldtp-3.5.0)

選択肢 1
$ldtp -s

選択肢 2
$ldtp -p <起動するポート・番号> # 未設定なら 4118 となる。

LDTP エンジン (Windows)

 コマンド・ラインから CobraWinLDTP.exe を実行する。

LDTP エンジン (Mac OS X)

 コマンド・ラインから ldtp を実行する。

LDTP クライアント

 クライアント側から LDTP エンジンと通信するには、二つのやり方がある。

選択肢 1
export LDTP_SERVER_ADDR=<ホスト名> もしくは <IP アドレス>
export LDTP_SERVER_PORT=<通信するポート番号、LDTP エンジン側で定めたもの>
python <スクリプト・ファイルの名前>.py もしくは ldtprunner test-runner.xml

選択肢 2
export LDTP_SERVER_ADDR=<ホスト名> もしくは <IP アドレス>
python <スクリプト・ファイルの名前>.py もしくは ldtprunner test-runner.xml # この場合、初期設定のポート番号を使う

LDTP で問題が起きた時

 LDTP のコマンドを実行した時に何が行われているのかを知りたい場合、下記の手順に従う。

片方の端末から

$ export LDTP_DEBUG=2 # bash shell の場合(Linux/Mac OS X)
C:¥> set LDTP_DEBUG=1 (Microsoft Windows の場合)
$ ldtp # (Linux/Mac OS X の場合) Windows では CobraWinLDTP.exe を実行
Client packet len: 82
i = 0
Data read 82, packet-len = 82, bytes read = 82, data: <?xml version="1.0"?
><REQUEST><ACTION>124</ACTION><ID>MainThread124</ID></REQUEST>
PACKET LENGTH: 0
Received packet [<?xml version="1.0"?
><REQUEST><ACTION><124</ACTION><ID>MainThread124</ID></REQUEST>] through 15
Node: ACTION
action name: 124
Node: ID
request_id: MainThread124
Command: 124
Accessible application name: Thunderbird
Accessible application name: gnome-panel
Accessible application name: xchat
Accessible application name: nm-applet
Accessible application name: nautilus
Accessible application name: gaim
Accessible application name: acroread
Accessible application name: soffice.bin
Accessible application name: gtk-window-decorator
Accessible application name: gedit
LIST: <?xml version="1.0" encoding="utf-8"?
><OBJECTLIST><OBJECT>nautilus</OBJECT><OBJECT>gaim</OBJECT><OBJECT>gtk-window-decorator</OBJECT><OBJECT>gedit</OBJECT><OBJECT>xchat</OBJECT><OBJECT>gnome-panel</OBJECT><OBJECT>Thunderbird</OBJECT><OBJECT>nm-applet</OBJECT><OBJECT>soffice.bin</OBJECT><OBJECT>acroread</OBJECT></OBJECTLIST>
resp_len = 117
Sending...
538
Response packet: <?xml version="1.0" encoding="utf-8"?
><RESPONSE><ID>MainThread124</ID><STATUS><CODE>0</CODE><MESSAGE>Successfully completed</MESSAGE></STATUS><DATA><LENGTH>325</LENGTH><VALUE><!
[CDATA[<?xml version="1.0" encoding="utf-8"?
><OBJECTLIST><OBJECT>nautilus</OBJECT><OBJECT>gaim</OBJECT><OBJECT>gtk-window-decorator</OBJECT><OBJECT>gedit</OBJECT><OBJECT>xchat</OBJECT><OBJECT>gnome-panel</OBJECT><OBJECT>Thunderbird</OBJECT><OBJECT>nm-applet</OBJECT><OBJECT>soffice.bin</OBJECT><OBJECT>acroread</OBJECT></OBJECTLIST>]]></VALUE></DATA><RESPONSE>
Msg:
Bytes sent: 542

もう片方の端末にて

$ export LDTP_DEBUG=2 # bash の場合
nags@nags:~> python
Python 2.5 (r25:51908, Nov 25 2006, 15:39:45)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on Linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ldtp import *
>>> getapplist()
124 ( )
Send packet <?xml version="1.0"?
><REQUEST><ACTION>124</ACTION><ID>MainThread124</ID></REQUEST>
Received packet size 538
Received response Packet <?xml version="1.0" encoding="utf-8"?
><RESPONSE><ID>MainThread124</ID><STATUS><CODE>0</CODE><MESSAGE>Successfully completed</MESSAGE></STATUS><DATA><LENGTH>325</LENGTH><VALUE><!
[CDATA[<?xml version="1.0" encoding="utf-8"?
><OBJECTLIST><OBJECT>nautilus</OBJECT><OBJECT>gaim</OBJECT><OBJECT>gtk-window-decorator</OBJECT><OBJECT>gedit</OBJECT><OBJECT>xchat</OBJECT><OBJECT>gnome-panel</OBJECT><OBJECT>Thunderbird</OBJECT><OBJECT>nm-applet</OBJECT><OBJECT>soffice.bin</OBJECT><OBJECT>acroread</OBJECT></OBJECTLIST>]]></VALUE></DATA><RESPONSE>
[u'nautilus', u'gaim', u'gtk-window-decorator', u'gedit', u'xchat', u'gnome-panel', u'Thunderbird', u'nm-applet', u'soffice.bin', u'acroread']
>>>

参考文献

http://en.wikipedia.org/wiki/Software_testing
http://safsdev.sf.net

GNU Lesser General Public License

入り口に戻る