aboutsummaryrefslogtreecommitdiff
path: root/files/ja/mozilla/projects/mochitest/index.html
blob: e649f3c05961df9be8d1e20c3c9217b945e0bbb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
---
title: Mochitest
slug: Mozilla/Projects/Mochitest
tags:
  - Automated testing
  - Developing Mozilla
translation_of: Mozilla/Projects/Mochitest
---
<p>Mochitestは、<a class="external" href="http://mochikit.com/">MochiKit</a> JavaScriptライブラリに基づいて構築された<a class="internal" href="/ja/docs/Mozilla_automated_testing" title="Mozilla automated testing">自動テストフレームワーク</a>です。これはMozillaによって利用されている、後退バグの自動テストフレームワークの一つです。テストはテストハーネスに対して、JavaScriptの関数を用いて成功あるいは失敗の旨を報告します。</p>
<p>Mochitestのユニークな特長は、Webページの形で書かれたテストを、完全なブラウザ環境の中でChrome(に昇格した)特権付きで実行できるという点です。これは、他のフレームワークでできることよりも非常に多くの事をテストの中のJavaScriptでできるようにします。通常のスクリプトが可能な事(DOM操作など)に加えて、テストのスクリプトはXPCOMコンポーネントやサービス、そしてブラウザそれ自体にすらもアクセスする事ができます。これによって、例えば、入力が意図されたとおりの結果をもたらすかどうかを確認するために、ブラウザのユーザーインターフェースに対してユーザによる入力をシミュレートして渡すなどのことができます。</p>
<p>Mochitestにおける、テストの成否を通知するためのJavaScript関数の呼び出し方は、いくつかの種類のテストに対しては不向きです。(Chrome特権付きの)JavaScriptによってテストできるような内容だけが、このフレームワークを使ってテストできます。創造性を発揮する事によって、あなたが最初に考えているよりもずっとたくさんの事ができますが、しかし、例えばスクリプトではないC++のコンポーネントを直接テストするようなMocihkitテストを書く事は不可能です(それを行うには<a class="internal" href="/ja/docs/Compiled-code_automated_tests" title="Compiled-code automated tests">コンパイル済みコードのテスト</a>を使ってください)。</p>
<h3 id="Running_tests" name="Running_tests">テストを実行する</h3>
<p>MozillaのビルドマシンはMochitestをビルドの過程の一つとして実行します。そのため、誰かがソースコードにコミットした変更が何かを壊していれば、それを極めて迅速に知る事ができます。しかし依然として、あらゆる新しい危険性のあるコードをコミットする前には、あなた自身の手でMochitestを走らせておくべきです。あなたも、避けられるなら、ツリーを壊して他のみんなの時間を無駄にさせる元凶になどなりたくないでしょう? :-)</p>
<h4 id="Running_the_whole_test_suite" name="Running_the_whole_test_suite">テストスイート全体を実行する</h4>
<p>Mochitestを実行するには、まずあなたが行った変更を含めて<a href="/ja/docs/Developer_Guide/Build_Instructions" title="Build_Documentation">Mozillaをビルド</a>します。次に、以下のようにします:</p>
<ul>
  <li>1.9.1およびそれ以降(bug 417516が修正されて以降)では、トップレベルのディレクトリで以下のコマンドを実行してください:
    <ul>
      <li><code>make -C $(OBJDIR) mochitest-plain</code></li>
    </ul>
  </li>
  <li>それより古いブランチでテストを行う場合は、Mochitestの<code>runtests.py</code>スクリプトをオプション指定無しでコマンドラインから実行してください:
    <ul>
      <li><code>cd $(OBJDIR)/_tests/testing/mochitest<br>
        python runtests.py</code></li>
    </ul>
  </li>
</ul>
<p><img alt="Image:Mochitest.png" class="internal" src="/@api/deki/files/269/=Mochitest.png"></p>
<p><strong>注意:</strong> テストを実行している間は、ブラウザウィンドウがフォーカスされた状態を保つべきです。そうでないと、いくつかのテストが失敗する事があります(例えば{{ Bug(330705) }}のテストがそうです)。Linuxユーザは、ダミーのXサーバを使う事でその状態を保存する事ができます(後述の<a href="#Diverting_X_output">Xの出力を迂回させる手順</a>を参照してください)。</p>
<h4 id="Running_select_tests" name="Running_select_tests">テストを選択して実行する</h4>
<p>テストを一つだけ実行する場合(あなたが書いたばかりの新しいテストなど)や、Mochitestスイート全体のうち一部分だけを実行する場合は、runtests.pyの<code>--test-pathオプションを使って、実行したいテストまたはサブディレクトリを指定してください。例えば、Mozillaのソースツリーの</code>{{ Source("content/base/test/test_CrossSiteXHR.html", "test_CrossSiteXHR.html") }}のテストだけを実行したい場合は、以下のようなコマンドを使う事になります:</p>
<pre><code>TEST_PATH=content/base/test/test_CrossSiteXHR.html make -C $(OBJDIR) mochitest-plain</code>
</pre>
<p>あるいは、mochitest-plain targetがサポーとされていないブランチでは以下のようにします:</p>
<pre>python runtests.py --test-path=content/base/test/test_CrossSiteXHR.html</pre>
<p>{{ Source("content/svg/") }}の中にあるすべてのテストを実行する場合は、以下のコマンドを使います:</p>
<pre class="eval">TEST_PATH=content/svg/ <code>make -C $(OBJDIR) mochitest-plain</code>
</pre>
<p><code>--test-path</code>によって指定されるパスは、Mozillaのソースツリー内のテストまたはディレクトリへの物である事に注意してください。パスがディレクトリの場合、そのディレクトリおよびすべてのサブディレクトリ内のテストが読み込まれます。</p>
<p>{{ h3_gecko_minversion("Gecko 2.0 およびそれ以降で特定のテストを実行する", "2.0") }}</p>
<p>Gecko 2.0 {{ geckoRelease("2.0") }} から、mochitest-1 から mochitest-5 までを make コマンドで簡単に実行できるようになりました。例:</p>
<pre>make mochitest-1
</pre>
<p>これによって、すべてのテストスイートを実行したり、トライサーバの buildbot のコードを調べて特定のテストだけを実行するための書き方を調べる代わりに、buildbot の挙動を真似る事ができます。</p>
<h4 id="個々のテストのデバッグ">個々のテストのデバッグ</h4>
<p>ある1つのテストについてデバッグする必要が生じた場合に、そのテストだけを実行するために、Firefox にデバッガをアタッチし、デバッガがアタッチされた状態でテストを含むページをリロードするのにも、前述の方法が利用できます。もし問題が起こる前にデバッガをアタッチする事が難しい場合には(例えば、テストが読み込まれた時にブラウザがクラッシュするような場合)、以下のようにしてテストスイート全体をまず最初に実行できます:</p>
<pre>python $OBJDIR/_tests/testing/mochitest/runtests.py
</pre>
<p>この時、デバッガをアタッチして、新しいタブを開き、"<a class="external" href="http://mochi.test:8888/tests/PATH/TO/MY/TEST" rel="freelink">http://mochi.test:8888/tests/PATH/TO/MY/TEST</a>" のようにテストを手動で指定することができます。例: "<a class="external" href="http://mochi.test:8888/tests/modules/plugin/test/test_pluginstream.html" rel="freelink">http://mochi.test:8888/tests/modules...ginstream.html</a>"</p>
<p>あるいは、あなたはmochitestの実行時にデバッガを指定するよう試みるかもしれません:</p>
<pre>TEST_PATH='...' EXTRA_TEST_ARGS='--debugger=gdb' make mochitest-plain
</pre>
<p>引数の --debuggerArgs と --debuggerInteractive も参照してください。</p>
<h4 id="Finding_errors" name="Finding_errors">エラーを探す</h4>
<p>予期されない失敗を探すには、「TEST-UNEXPECTED-FAIL」という文字列を検索してください。最終的なテストの実行結果の要約を見るには「SimpleTest FINISHED」を検索してください。連結されたログではMochitestの出力は最後にあるとは限らないので、すべてのTinderboxのログをまとめて見る時に、後者は特に便利です。</p>
<h4 id="Logging_results" name="Logging_results">結果のロギング</h4>
<p>テストの実行による出力は、コンソールおよび(または)ファイルに送る事ができます(デフォルトでは、結果はブラウザ上にのみ表示されます)。出力の詳細さはいくつかのレベルで指定できます。DEBUG、INFO、WARNING、ERROR、FATALの各レベルがあり、DEBUGでは出力は最も詳細(すべて出力)になり、FATALでは出力は最も少なく(テストを中断させるようなイベントが発生した時だけメッセージを出力)なります。</p>
<p>ファイルにログを保存するには --log-file=<var>ファイルのパス</var> オプションを使います。デフォルトではファイルへのログ出力レベルはINFOですが、--file-level=<var>レベル</var> オプションを使う事でレベルを変更できます。</p>
<p>コンソールへのログ出力を有効にするには、--console-level=<var>レベル</var> オプションを使います。</p>
<p>例えば、テスト実行時の出力を <code>~/mochitest.log</code> というファイルにDEBUGレベルの詳細さで保存したい場合は以下のようになります:</p>
<pre class="eval">python runtests.py --log-file=~/mochitest.log --file-level=DEBUG
</pre>
<h4 id="Diverting_X_output" name="Diverting_X_output">Xの出力を迂回させる</h4>
<p>テスト実行中のコンピュータでユーザが行うあらゆる他の操作による影響を防ぐために、テストは必ずフォーカスされたウィンドウの中で実行されなくてはなりません。Linuxユーザはスイートに指示を与える事で、不可視の仮想デスクトップを使うようにすることができます。もし<a class="external" href="http://en.wikipedia.org/wiki/Xvfb">Xvfb</a>がインストールされている、またはインストールできる場合は、以下のコマンドは現在のセッションをブロックすることなくテストを実行します。:</p>
<pre class="eval">nice xvfb-run python _tests/testing/mochitest/runtests.py --log-file=./mochitest-plain.log --file-level=DEBUG --autorun --close-when-done --console-level=DEBUG
</pre>
<p>他に可能な設定については、{{ Bug(434365) }}で議論されています。</p>
<h4 id="Other_.27runtests.27_options" name="Other_.27runtests.27_options"><code>runtests.py</code>のその他のオプション</h4>
<p><code>runtests.py</code>スクリプトは他にもいくつかのオプションを解釈します。それらの一覧を見るには --help オプションを使ってください。ちなみに、<a href="/ja/docs/Chrome_tests" title="Chrome_tests">--chrome</a><a href="/ja/docs/Browser_chrome_tests" title="Browser_chrome_tests">--browser-chrome</a><a href="/ja/docs/Accessibility" title="Accessibility">--a11y</a>の各オプションについては個別のドキュメントがあります。</p>
<h3 id="Writing_tests" name="Writing_tests">テストを書く</h3>
<p>Mochitest用のテストファイルは、いくつかの条件についてテストを行うJavaScriptを含んだシンプルなHTML、XHTML、またはXULのファイルです。</p>
<p>Mozillaをビルドせずに大部分のテストを実行するために、<a class="external" href="http://ted.mielczarek.org/code/mozilla/mochitest-maker/">Mochitest maker</a>を利用できます。</p>
<h4 id="Try_to_avoid_Mochitest" name="Try_to_avoid_Mochitest">Mochitestを使わない事を試みる</h4>
<p>はい、これは冗談ではなく本当にです。様々な理由のために、Mochitestは過剰な物となっています。一般的な用途では、より軽量なテストフレームワーク使うように常に試みる事をお勧めします。例えば、ある一つのXPCOMコンポーネントをテストしたいだけであれば、<a href="/ja/docs/Writing_xpcshell-based_unit_tests" title="Writing_xpcshell-based_unit_tests">xpcshell</a>を使うべきです。また、Mochitestにもできない事や、それをするようには設計されていないという事がいくつかあります。こちらの例は視覚的な出力についてのテストで、その場合は<a href="/ja/docs/Creating_reftest-based_unit_tests" title="Creating_reftest-based_unit_tests">reftest</a>フレームワークを使うのがお勧めです。他の異なる種類の自動テストフレームワークについての情報は、<a href="/ja/docs/Mozilla_automated_testing" title="Mozilla_automated_testing">Mozillaの自動テスト</a>を参照してください。</p>
<h4 id="Test_templates" name="Test_templates">テストのテンプレート</h4>
<p>定型的な内容を毎回入力する手間を省くために、{{ Source("testing/mochitest/gen_template.pl", "gen_template.pl") }} Perlスクリプトがテストのテンプレートの生成に利用できます。このスクリプトは2つの省略可能な引数を取ります:</p>
<ol>
  <li>-b : バグの番号。</li>
  <li>-type : 連符レートの種類。html、xhtml、xul のいずれかを選択する。デフォルトはhtml。</li>
</ol>
<p>利用例:</p>
<pre class="eval">cd mozilla/testing/mochitest/
perl gen_template.pl -b=123456 &gt; path/to/test_bug123456.html
perl gen_template.pl -b=123456 --type=xul &gt; path/to/test_bug123456.xul
</pre>
<p>Mochitest ではすべてのテストのファイル名は「test_」で始まっている必要がある事に注意してください。テストをツリーのどの位置に置けばよいのかを決める手助けとしては、後述の内容を参照してください。</p>
<p>Mochitest の定型的なコードに加えて、このスクリプトは 'content' という id を持った要素と 'display' という id を持った要素も生成するでしょう。あなたが書くテストでは、これらを他のあなたが追加する要素と同様に操作して構いません。</p>
<h4 id="Test_functions" name="Test_functions">テスト関数</h4>
<p>個々のテストは、Mochitestに対してテストが成功したのか失敗したのかを通知するために実行されるいくつかのJavaScriptを含んでいる必要があります。 {{ Source("testing/mochitest/tests/SimpleTest/SimpleTest.js", "SimpleTest.js") }} は、テストにおいてMochitestにテストの成否を知らせるための様々な関数を含んでいます。これらには以下の物が含まれます:</p>
<ul>
  <li><code>ok(<var>trueになるべき文</var>, "<var>エラーメッセージ</var>")</code> -- 値が真である事をテストする。</li>
  <li><code>is(<var>実際の値</var>, <var>期待される値</var>, "<var>エラーメッセージ</var>")</code> -- 二つの値を比較する(===ではなく==を使用)。</li>
  <li><code>isnot(<var>実際の値</var>, <var>期待されない値</var>, "<var>エラーメッセージ</var>")</code> -- is()の逆。</li>
</ul>
<p>これらの関数の使い方の例は、 {{ Source("testing/mochitest/README.txt", "README") }} を参照してください。</p>
<p>もし、現在のところは失敗するというテストを含めたい場合、単にその部分をコメントアウトしないでください! その代わりに、 相当する「todo」を使ってください。これによってTinderboxは、不意にテストが成功するようになった時に、(いつの時点でテストが成功するようになったのかを)知らせる事ができます。:</p>
<ul>
  <li><code>todo(<var>今はfalseになるが本当はtrueになるべき文</var>, "<var>エラーメッセージ</var>"</code><code>)</code></li>
  <li><code>todo_is(<var>実際の値</var>, <var>期待される値</var>, "<var>エラーメッセージ</var>")</code></li>
  <li><code>todo_isnot(<var>実際の値</var>, <var>期待されない値</var>, "<var>エラーメッセージ</var>")</code></li>
</ul>
<h4 id="Helper_functions" name="Helper_functions">ヘルパー関数</h4>
<p>現時点では、すべてのMochikitの機能が利用できます(これは{{ Bug(367393) }}によって変わるでしょう)。{{ Bug(367569) }}で、ヘルパー関数として<code>sendChar</code><code>sendKey</code><code>sendString</code>が追加されました。これらは{{ Source("testing/mochitest/tests/SimpleTest/EventUtils.js") }}において利用できます。</p>
<h3 id="Adding_tests_to_the_tree" name="Adding_tests_to_the_tree">テストをツリーに追加する</h3>
<p>新しいテストを書いたら、すぐにそれをMozillaのソースツリーに追加して、ビルドシステムにその事を通知する必要があります。これによって、Mozilla tinderboxはそれを自動的に実行するようになります。</p>
<h4 id="Choosing_a_location" name="Choosing_a_location">場所の選択</h4>
<p>新しいMochitestのテストはテストされるコードの近くのどこか、できれば同じモジュールに置かれるべきで、これにより、テストケースが何のための物なのかが明確になります。例えば、あるHTMLの機能のテストを作成した場合、おそらく、テストを{{ Source("content/html/content/test") }}または{{ Source("content/html/document/test") }}に置きたいと思うでしょう。もしも、テストしようとしているコードの近くにテスト用のディレクトリがなければ、{{ Bug(368531) }}のパッチで実際にそうしているように、新しいテスト用のディレクトリを作成する事ができます。</p>
<h4 id="Makefile_changes" name="Makefile_changes">Makefileの変更</h4>
<p>あなたが書いた新しいテストの事をビルドシステムに通知するために、あなたが書いたテストファイルの名前をそのテストディレクトリの<code>Makefile.in</code>の中の<code>_TEST_FILES</code>に追加する必要があります。</p>
<p>もしもあなたが書いたテストが複数のファイルに渡っているなら、その場合はメインのファイルの名前を「test_...」としてください。これは実行するテストのリストに登場する名前となります。他のファイルはそれ以外の名前になっているべきですが、<code>Makefile.in</code><code>_TEST_FILES</code>に追加されなければならないという点は変わりません。</p>
<p>Chromeのテストを追加する場合、テストを <code>_tests/testing/mochitest/<strong>tests</strong></code> ではなく <code>_tests/testing/mochitest/<strong>chrome</strong></code> にインストールするようMakefileを変更する事を忘れないでください。</p>
<h4 id="Building_and_running_new_tests" name="Building_and_running_new_tests">ビルドと新しいテストの実行</h4>
<p>新しいテストをコミットする前に、Makefile.inの変更内容が正しく、また、あなたが書いたテストが期待通りに成功する事を確認してください。あなたが書いたテストを確認するには、まず、以下のコマンドでそのテストをMochitestのディレクトリ(ソースツリーのテストファイルの位置と同じ場所)に取り出してください:</p>
<pre class="eval">make
</pre>
<p>次に、Mochitestを前述の通りに開きますが、この時、「Run Tests」リンクをクリックする代わりに、あなたが書いたテストを一覧から探してそれをクリックしてください。</p>
<h3 id="FAQ" name="FAQ">SSLと<code>https</code>を有効にしたテスト</h3>
<p>Mochitestのテストは、正常な動作のために <code><span class="nowiki">http://localhost:8888</span></code> で実行されなくてはなりません。しかし、テストの中にはオリジンが異なる場合のための機能のテストとして、他のプロトコル、ホスト、ポートを使う必要があるものもあるでしょう。Mochitestのテストハーネスは、元のサーバのすべてのコンテンツをproxy autoconfigとSSLトンネリングを用いて他の様々なサーバに<em>同期(ミラー)する</em>ことで、この問題を解決します。テストを実行したいすべてのスキーム、ホスト、ポートのリスト(それらはすべて <code><span class="nowiki">http://localhost:8888</span></code> と完全に同じコンテンツを返す必要があります)は{{ Source("build/pgo/server-locations.txt") }}で指定します。ただし、そこに記述されたオリジンのすべてが完全に同じである必要はありません。テスト用として特定のSSL証明書を指定された物や、そのサーバ上のページで特権の昇格の要求を許可する物も設定できます。完全な詳細説明については、ファイルの内容を参照してください。</p>
<h4 id="動作させる方法">動作させる方法</h4>
<p><br>
  Mochitestのハーネスは、要求されたURLをサーバにマッチさせるためにブラウザに<a class="external" href="http://en.wikipedia.org/wiki/Proxy_auto-config" title="http://en.wikipedia.org/wiki/Proxy_auto-config">proxy autoconfig</a> を使わせる設定を含んでいます。<code>network.proxy.autoconfig_url</code> の設定は、要求されたURLがマップされているホストを認識するための<code>FindProxyForURL</code>という JavaScript 関数をエンコードしたdata: URLがセットされます。SSLのサイトがミラーされる場合、その関数はリクエストを、<a class="external" href="http://www.ietf.org/rfc/rfc2817.txt" title="http://www.ietf.org/rfc/rfc2817.txt">RFC 2817</a>で定められた<code>CONNECT</code>メソッドによる説明に応じて、トラフィックを実際のサーバへ透過的に転送するSSLトンネルにマップします。このようにして、<code><a class="external" href="http://127.0.0.1:8888" rel="freelink">http://127.0.0.1:8888</a></code>に立てられた単一のサーバは異なる場所を示す何十ものサーバをエミュレートします。</p>
<p>MochitestのSSL関連の機能や、署名を変更する方法、新しいhttpsのサーバを追加する手順などのさらに詳細な説明については、<a class="internal" href="/ja/docs/Modifying_Mochitest_SSL_behavior" title="Modifying Mochitest SSL behavior">MochitestのSSLの動作の変更</a>を参照してください。</p>
<h3 id="stacks" name="stacks">スタックトレースの取得</h3>
<p>Mochitest がクラッシュした時のスタックトレースを取得する方法は以下の通りです:</p>
<ol>
  <li><code><a class="external" href="http://hg.mozilla.org/build/tools/file/b680aba8e49a/breakpad/" rel="freelink">http://hg.mozilla.org/build/tools/fi...e49a/breakpad/</a></code> からあなたのプラットフォーム用の <code>minidump_stackwalk</code> のバイナリを取得します。</li>
  <li>環境変数 <code>MINIDUMP_STACKWALK</code> にそのバイナリのパスを指定します。</li>
</ol>
<p>もし結果のスタックトレースが行番号を含んでいない場合には、必須のシンボルファイルを生成するために <code>make buildsymbols</code> を実行して下さい。詳しくは <a href="/ja/docs/Building_Firefox_with_Debug_Symbols" title="Building Firefox with Debug Symbols">Firefox をデバッグ用のシンボル付きでビルドする</a>を参照して下さい。</p>
<h3 id="FAQ" name="FAQ">FAQ</h3>
<h4 id="What_if_my_tests_aren.27t_done_when_onload_fires.3F" name="What_if_my_tests_aren.27t_done_when_onload_fires.3F">onloadイベントの時に実行されるようなテストが動かない時はどうすればいいですか?</h4>
<p>onloadイベントが発行される前に <code>SimpleTest.waitForExplicitFinish()</code> を呼んでください。その場合は、テストを完了したら <code>SimpleTest.finish()</code> を呼んでください。</p>
<h4 id="What_if_I_need_to_change_a_preference_to_run_my_test.3F" name="What_if_I_need_to_change_a_preference_to_run_my_test.3F">テストの中で設定(Preference)を変える必要がある時はどうすればいいですか?</h4>
<pre class="eval">netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                            .getService(Components.interfaces.nsIPrefService);
var domBranch = prefService.getBranch("dom.");
var oldVal = domBranch.getIntPref("max_script_run_time");
domBranch.setIntPref("max_script_run_time", 0);

// 必要な処理(テストの内容)

domBranch.setIntPref("max_script_run_time", oldVal);
</pre>
<p>あるテストを実行している間だけ設定を変更する必要がある場合には、make target <code>mochitest-plain</code> を実行する時に環境変数 <code>EXTRA_TEST_ARGS</code> を設定して下さい。</p>
<pre>EXTRA_TEST_ARGS='--setpref=javascript.options.jit.chrome=false'
</pre>
<p>文字列型の設定を変更する必要がある場合は、バックスラッシュでエスケープしたダブルクォートで文字列を括ります:</p>
<pre>EXTRA_TEST_ARGS='--setpref=webgl.osmesa=\"libOSMesa.so.6\"'
</pre>
<h4 id="Can_tests_be_run_under_a_chrome_URL.3F" name="Can_tests_be_run_under_a_chrome_URL.3F">テストはChrome URLの中でも実行できますか?</h4>
<p>はい。 <code>python runtests.py --chrome</code> を使ってください。ただしXPCOMをテストするための最初の選択肢としては<a href="/ja/docs/Writing_xpcshell-based_unit_tests" title="Writing_xpcshell-based_unit_tests">xpcshellテストハーネス</a>を使うべきであることを心に留めておいてください。Mochitestが必要になるのは、イベントやブラウザの機能、ネットワーク関係の機能がテストに必要な場合だけです。</p>
<h4 id="How_can_I_get_around_the_error_.22Permission_denied_to_get_property_XPCComponents.classes.22.3F" name="How_can_I_get_around_the_error_.22Permission_denied_to_get_property_XPCComponents.classes.22.3F">どうすれば「Permission denied to get property XPCComponents.classes」エラーを回避できますか?</h4>
<p>以下の行をあなたの書いたテストファイル(およびそれぞれのイベントハンドラ)に書き加えてください。すべてのXPCOMが利用できるようになるでしょう。</p>
<pre>netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');</pre>
<p>この方法は明らかに不便です。これこそが、テスト実行用にテストをChromeのディレクトリにコピーするのに必要なハックを行おうと私たちが作業している理由です。</p>
<h4 id="How_do_I_change_the_HTTP_headers_or_status_sent_with_a_file_used_in_a_Mochitest.3F" name="How_do_I_change_the_HTTP_headers_or_status_sent_with_a_file_used_in_a_Mochitest.3F">Mochitestで使われるファイルのHTTPヘッダやステータスを変えるにはどうすればよいですか?</h4>
<p>テキストファイルを作成して、ヘッダを変えたいと思っているファイルの隣に置いてください。テキストファイルの名前はヘッダを変えようとしているファイルの名前の末尾に <code>^headers^</code> を付けた物にします。例えば <code>foo.jpg</code> というファイルがある場合は、テキストファイルの名前は <code>foo.jpg^headers^</code> となります。(ヘッダ指定用のファイルはテストの中で他の目的では使わないでください。HTTPサーバの不可視ファイル機能は、「^」で名前が終わっているすべてのファイルを見えなくするからです。)そして、あなたが設定したいヘッダおよび(もしくは)ステータスをそのファイルの内容として記述してください。例:</p>
<pre class="eval">HTTP 404 Not Found
Content-Type: text/html
Random-Header-of-Doom: 17
</pre>
<p>最初の行はそのファイルに関連付けられたHTTPステータスと(任意で)説明文を設定しています。この行は省略可能で、通常のレスポンスステータスと説明文で問題ない場合は記述する必要はありません。他の行は、レスポンスヘッダ中で追加または上書きしたい(後者の最も典型的な例はContent-Typeヘッダでしょう)、そのファイルについて説明する追加のヘッダです。様式はHTTPの仕様でのものと同じですが、HTTPの行末を示す必要は無く、一つのヘッダを複数書く事はできません(同じヘッダを複数回多場合は最後の物だけが有効となります)。 ファイルはUnixのテキストファイルの様式に沿って一つの空行で終わる場合がありますが、それは厳密に必要というわけではありません。</p>
<h4 id="How_do_I_test_issues_which_only_show_up_when_tests_are_run_across_domains.3F" name="How_do_I_test_issues_which_only_show_up_when_tests_are_run_across_domains.3F">複数のドメインに渡って実行されるテストでのみ発生する事象をテストするにはどうすればよいですか?</h4>
<p>Mochitestのハーネスはテストを行うために一つのWebサーバだけを起動しますが、proxy autoconfigの働きにより、すべてのテストファイルは異なるドメイン、異なるポートで実行できます。これらのサーバ(権限昇格のための機能に関する2つの例外を除く)で動作しているあらゆるテストは自動的に、UniversalXPConnectなどの特権の取得を要求する事ができるようになります。テストの実行が可能で、<code><span class="nowiki">http://localhost:8888</span></code>と全く同じコンテンツを提供するドメインとポートの完全なリストは、{{ Source("build/pgo/server-locations.txt") }}で指定されます。</p>
<h4 id="How_do_I_write_tests_that_check_header_values.2C_method_types.2C_etc._of_HTTP_requests.3F" name="How_do_I_write_tests_that_check_header_values.2C_method_types.2C_etc._of_HTTP_requests.3F">HTTPリクエストのヘッダの値、メソッドの種類などを確認するテストはどのように書けばよいですか?</h4>
<p>その種のテストを書くには、それ用のSJS(server-side JavaScript)を書くだけでよいです。SJSは <code>sjs</code> という拡張子を持つ単純なJavaScriptファイルで、サンドボックス内に読み込まれます。スクリプト内でグローバルな名前空間において <code>handleRequest</code> という名前で定義された関数は、リクエストとレスポンスのオブジェクトを伴って実行され、そのスクリプトはリクエストの情報に基づいてレスポンスを生成します。</p>
<p>以下は単純なSJSの例です:</p>
<pre class="eval">function handleRequest(request, response)
{
  // avoid confusing cache behaviors
  response.setHeader("Cache-Control", "no-cache", false);

  response.setHeader("Content-Type", "text/plain", false);
  response.write("Hello world!");
}
</pre>
<p>引数として渡されるリクエストとレスポンスのオブジェクトが持つ正確なプロパティは、<code>{{ Source("netwerk/test/httpserver/nsIHttpServer.idl", "nsIHttpServer.idl") }}</code><code>nsIHttpRequestMetadata</code><code>nsIHttpResponse</code> インターフェースとして定義されています。ブラウザはあなたが書いたスクリプトによって生成されたレスポンスを自由にキャッシュする事に気をつけてください。もしSJSが同じURLへの複数のリクエストに対して異なるデータを返したい場合は、   Mochitestの同じセッションで手動で複数回実行された際にテストが意図せず失敗してしまう事を防ぐために、レスポンスに <code>Cache-Control: no-cache</code> ヘッダを加えるとよいでしょう。</p>
<p>reftestにおけるSJSの簡単な利用例としては、<code>{{ Source("modules/libpr0n/test/reftest/generic/check-header.sjs", "check-header.sjs") }}</code>があります。</p>
<h4 id="How_do_I_test_issues_which_only_show_up_when_tests_are_run_across_domains.3F" name="How_do_I_test_issues_which_only_show_up_when_tests_are_run_across_domains.3F">異なるサーバサイドスクリプトの間で状態を引き継ぐにはどうすればよいですか?</h4>
<p>Mochitest のサーバサイドスクリプトは、それぞれの読み込みごとに新たに生成されるサンドボックスの中で実行されます。そのため、ハンドラの中で定義されたいかなる変数も、それぞれの読み込みごとの実行コンテキストを超えて状態を保持し続ける事はありません。状態を保存する手助けとしては、グローバルオブジェクトにおいて定義されている <code>getState(k)</code> および <code>setState(k, v)</code> メソッドを利用します。これらのメソッドはキーと値(どちらも文字列を使用)によるストレージの仕組みをサーバに提供します。(オブジェクトやその他の構造化されたデータを保存するにはJSONを使用してください。)Mochitest における無数のサーバが、プロキシとトンネリングによってそう見せられているだけで実際には単一のサーバであるために、保存された状態はすべてのサーバで常に同じとなることに注意してください。</p>
<p><code>getState</code> および <code>setState</code> メソッドは、サーバサイドスクリプトが読み込まれた時点のパスでスコープが決まります。<code>/foo/bar/baz</code>, <code>/foo/bar/baz?quux</code>, <code>/foo/bar/baz#fnord</code> のような絶対 URL はすべて同じ状態を共有します(この場合 <code>/foo/bar</code> の状態はそれらとは別に保持されます)。テスト同士の依存性とバグの発生を避けるためにも、可能な限り常に、状態はパスごとに使用するべきです。しかしながら、2つのスクリプトが関連して協調動作することが必要であるなどのレアケースで、そのスクリプトから分岐に応じた挙動を要求するための専用のクエリ文字列を利用できないような場合もあります。<em>このような用途についてのみ</em>、あなたはグローバルオブジェクトで定義されている <code>getSharedState(k, v)</code> および <code>setSharedState(k, v)</code> メソッドを使う事ができます。このサーバ全体で共有される状態へのアクセスについては何も制限はかけられておらず、どのスクリプトからも新しい状態を設定でき、どのスクリプトからもそれを削除できます。衝突を避けるために、あなたは名前空間(意図しない衝突を避けるため、これもテスト用の物を作って下さい)をキーに含める事が望ましいです。例えば、ある HTML5 ビデオのテストで状態を共有する必要がある場合なら、<span style="font-family: monospace;">dom.media.video</span><code>:sharedState</code> のようなキーを使う事になります。</p>
<p>より強力な状態保存のための機能として、あらゆる <code>nsISupports</code> 形式のオブジェクトを保持することができる <code>getObjectState(k)</code> および <code>setObjectState(k, v)</code> メソッドもあります。これらのメソッドは <code>nsIHttpServer</code> インターフェースにこの形式で存在していますが、SJS レスポンス処理用のサーバで使われるサンドボックスオブジェクトの制限のため、前者のメソッドは SJS リクエストハンドラのグローバル環境においては、<code>getObjectState(k, callback)</code> という形式(<code>callback</code> は、第1引数で示されたキーに対応するオブジェクトを引数として <code>getObjectState</code> の内部で呼ばれるコールバック関数)で存在します。この、値のマッピングのために、値が XPCOM オブジェクトである必要がある必要があることに注意して下さい。<code>QueryInterface</code> メソッドを持たない任意の JavaScript オブジェクトは利用できません。JavaScript のオブジェクトを保持させたい場合には、<code>QueryInterface</code> の実装を持ち、XPConnect でラップされたオブジェクトから実際の JavaScript オブジェクトを取得するための <a class="internal" href="/ja/docs/wrappedJSObject" title="wrappedJSObject">wrappedJSObject</a> プロパティも持つオブジェクトを使って下さい。</p>
<p>httpd.js によって提供される状態保存の仕組みの詳細については、{{ Source("netwerk/test/httpserver/nsIHttpServer.idl") }} および <code>nsIHttpServer.get(Shared|Object)?State</code> メソッドを参照して下さい。</p>
<h4 id="非同期にレスポンスを返す_SJS_スクリプトはどのように書けばいいですか?">非同期にレスポンスを返す SJS スクリプトはどのように書けばいいですか?</h4>
<p>例えば一定の時間待つという風に、リクエストに対するレスポンスを非同期に返したいという場合があるでしょう。これは <code>handleRequest()</code> 関数に渡される <code>response</code> オブジェクトの <code>processAsync()</code> および <code>finish()</code> 関数によって実現できます。</p>
<p><code>processAsync()</code> は必ず、<code>handleRequest()</code> からリターンする前に呼ばれなくてはなりません。この関数を実行すると、さらに追加のレスポンスを送信するために、request オブジェクトのメソッドを好きな時点で呼ぶ事ができるようになります。必要なレスポンスを送信し終えたら、<code>finish()</code> 関数を呼んでください。例えば、上で説明した <code>setState()</code>/<code>getState()</code> 関数を、request を保存して、後でその内容を参照し、さらに終了するために利用できます。しかしながら、ブラウザはリクエストを異なる順番で行う事があり、そのためあなたが書くコードは時々起こる失敗を避けるよう耐性を高くしなければならないということに気をつけてください。</p>
<pre class="eval">var timer = null;

function handleRequest(request, response)
{
  response.processAsync();
  response.setHeader("Content-Type", "text/plain", false);
  response.write("hello...");

  timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
  timer.initWithCallback(function()
  {
    response.write("world!");
    response.finish();
  }, 5 * 1000 /* ミリ秒 */, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}
</pre>
<p>より詳しい情報については、{{ Source("netwerk/test/httpserver/nsIHttpServer.idl") }} にある <code>processAsync()</code> 関数の説明を参照してください。</p>
<h4 id="How_do_I_change_the_HTTP_headers_or_status_sent_with_a_file_used_in_a_Mochitest.3F" name="How_do_I_change_the_HTTP_headers_or_status_sent_with_a_file_used_in_a_Mochitest.3F">SJS スクリプトからサーバ上にあるファイルに XPCOM オブジェクトとしてアクセスするにはどうすればよいですか?(Gecko 1.9.3 およびそれ以降の場合)</h4>
<p>ファイルにアクセスする必要がある場合(例えば、画像データはファイルとして保存しておく方が、SJS スクリプトの中に直接画像を埋め込むよりも扱いが簡単です)、Mochitest で実行されている SJS スクリプトで最初から定義済みの <code>SERVER_ROOT</code> オブジェクトステートを利用して下さい:</p>
<pre class="eval">function handleRequest(req, res)
{
  var file;
  getObjectState("SERVER_ROOT", function(serverRoot)
  {
    file = serverRoot.getFile("tests/content/media/test/320x240.ogv");
  });

  // この時点で file は指定されたファイルを参照する XPCOM オブジェクトになっています。
  res.write("file: " + file);
}
</pre>
<p>指定するパスは、httpd.js が取り扱うルートディレクトリからの相対パスとして扱われ、その位置に対応する<code>nsIFile</code> のオブジェクトが返されます。この時は、パスの書き間違いに注意してください。ファイルのオブジェクトはパス文字列を保持しているだけなので、指定したファイルは実際に存在している必要がありません。</p>