Compare Revisions

Writing xpcshell-based unit tests

Change Revisions

Revision 472935:

Revision 472935 by gps on

Revision 481773:

Revision 481773 by Ms2ger on

Writing xpcshell-based unit tests
Writing xpcshell-based unit tests
"Developing Mozilla", "Automated testing"
"Developing Mozilla", "Automated testing"

Revision 472935
Revision 481773
n27      This doesn't really test anything, but it gives you an idean27      This doesn't really test anything, but it gives you an idea
> how you'd actually write a test. If you want to execute the test> how you'd actually write a test. If you want to execute the test
>, you must first add it to the <a href="/en/Writing_xpcshell-base>, you must first add it to the <a href="/en/Writing_xpcshell-base
>d_unit_tests#Adding_your_tests_to_the_xpcshell_manifest" title="e>d_unit_tests#Adding_your_tests_to_the_xpcshell_manifest" title="e
>hell_manifest">xpcshell.ini manifest</a>.&nbsp; Add the test file>hell_manifest">xpcshell.ini manifest</a>. Add the test file to an
> to an existing set of tests (say, for example, {{ Source("netwer> existing set of tests (say, for example, {{ Source("netwerk/test
>k/test/unit/") }}, but you should put it near the code it tests).>/unit/") }}, but you should put it near the code it tests). You t
> You then execute your test using make xpcshell-tests:>hen execute your test using <a href="/en-US/docs/Developer_Guide/
 >mach" title="/en-US/docs/Developer_Guide/mach">mach</a>:
28    </p>
29    <pre>28    </p>
30$ cd objdir29    <pre>
31$ make -C netwerk/test/ xpcshell-tests30$ ./mach xpcshell-test netwerk/test/
34    <p>
35      or using <a href="/en-US/docs/Developer_Guide/mach" title="
36    </p>
37    <pre>
38$ cd objdir
39$ ./mach xpcshell-test &lt;path_to_directory&gt;
n73      xpcshell tests have access to the following utility function65      xpcshell tests have access to the following utility functio
>ns.&nbsp; All of them are defined in <a class="external" href="ht>ns. All of them are defined in <a class="external" href="http://m
>tp://>" t
>.js" title=">itle="
>/xpcshell/head.js">testing/xpcshell/head.js</a> if you want to se>ell/head.js">testing/xpcshell/head.js</a> if you want to see how 
>e how they work.>they work.
n77        <code>add_test(<em>testFunction</em>)</code>n69        <code>add_test(<var>testFunction</var>)</code>
n82    </dl>n
83    <dl>74      <dt>
84      <dt>
85        <code>do_throw(<em>messageText</em>)</code>75        <code>do_throw(<var>messageText</var>)</code>
n93    </dl>n
94    <dl>83      <dt>
95      <dt>
96        <code>do_check_eq(<em>a</em>, <em>b</em>)</code>84        <code>do_check_eq(<var>a</var>, <var>b</var>)</code>
n101    </dl>n
102    <dl>89      <dt>
103      <dt>
104        <code>do_check_neq(<em>a</em>, <em>b</em>)</code>90        <code>do_check_neq(<var>a</var>, <var>b</var>)</code>
n109    </dl>n
110    <dl>95      <dt>
111      <dt>
112        <code>do_check_true(<em>expr</em>)</code>96        <code>do_check_true(<var>expr</var>)</code>
n117    </dl>n
118    <dl>101      <dt>
119      <dt>
120        <code>do_check_false(<em>expr</em>)</code>102        <code>do_check_false(<var>expr</var>)</code>
n125    </dl>n
126    <dl>107      <dt>
127      <dt>
128        <code>do_check_null(<em>expr</em>)</code>108        <code>do_check_null(<var>expr</var>)</code>
n134        <code>do_print(<em>messageText</em>)</code>n114        <code>do_print(<var>messageText</var>)</code>
n139    </dl>n
140    <dl>119      <dt>
141      <dt>
142        <code>do_execute_soon(<em>callback</em>)</code>120        <code>do_execute_soon(<var>callback</var>)</code>
n147    </dl>n
148    <p>
149      &nbsp;
150    </p>
151    <dl>125      <dt>
152      <dt>
153        <code>do_get_file(<em>testdirRelativePath, allowNonexiste126        <code>do_get_file(<var>testdirRelativePath</var><var>al
n161    </dl>n
162    <dl>
n169    </dl>n
170    <dl>
n177    </dl>n
178    <dl>
179      <dt>
180        <code>load(<em><span style="font-style: italic;">test</sp
181      </dt>146      <dt>
182      <dd>147        <code>load(<var>testdirRelativePath</var>)</code>
183        Imports the JavaScript file referenced by <code><em>testd
>irRelativePath</em></code> into the global script context, execut 
>ing the code inside it. The file specified is a file within the t 
>est directory. For example, if your test is unit/test_something.j 
>s and you have another file unit/extra_helpers.js, you can load t 
>he second file from the first simply by calling <code>load('extra 
184      </dd>
185    </dl>
186    <dl>
187      <dt>148      </dt>
188        <code>do_load_module(</code><code><em>testdirRelativePath
189      </dt>
190      <dd>
191        Calls do_get_file(<code><em>testdirRelativePath</em></cod
>e>), then registers the returned file. 
192      </dd>149      <dd>
193    </dl>150        Imports the JavaScript file referenced by <code><var>test
 >dirRelativePath</var></code> into the global script context, exec
 >uting the code inside it. The file specified is a file within the
 > test directory. For example, if your test is unit/test_something
 >.js and you have another file unit/extra_helpers.js, you can load
 > the second file from the first simply by calling <code>load('ext
194    <dl>
195      <dt>
196        <code>do_parse_document(<em><span style="font-style: ital
>ic;">p</span></em></code><code><em><em>ath</em>, type</em></code> 
197      </dt>
198      <dd>151      </dd>
152      <dt>
153        <code>do_load_module(<var>testdirRelativePath</var>)</cod
154      </dt>
155      <dd>
156        Calls do_get_file(<code><var>testdirRelativePath</var></c
 >ode>), then registers the returned file.
157      </dd>
158      <dt>
159        <code>do_parse_document(<var>path</var>, <var>type</var>)
160      </dt>
161      <dd>
199        Parses and returns a DOM&nbsp;document.162        Parses and returns a DOM document.
n205        By default XPCShell tests will disable the idle service, n168        By default XPCShell tests will disable the idle service, 
>so that idle time will always be reported as 0.&nbsp; Calling thi>so that idle time will always be reported as 0. Calling this func
>s function will re-enable the service and return a handle to it, >tion will re-enable the service and return a handle to it, the id
>the idle time will be then correctly requested to the underlying >le time will be then correctly requested to the underlying OS. Th
>OS.&nbsp; The idle-daily notification could be fired when request>e idle-daily notification could be fired when requesting idle ser
>ing idle service. It is suggested to always get the service throu>vice. It is suggested to always get the service through this meth
>gh this method if the test has to use idle.>od if the test has to use idle.
206      </dd>
207    </dl>
208    <dl>
209      <dt>169      </dd>
210        &nbsp;
211      </dt>170      <dt>
212      <dt>
213        <code>do_register_cleanup(<em>callback</em>)</code>171        <code>do_register_cleanup(<var>callback</var>)</code>
n218    </dl>n
219    <p>
220      &nbsp;
221    </p>
222    <dl>
223      <dt>
224        <code>do_timeout(<em>delay</em>, <em>fun</em>)</code>
225      </dt>176      <dt>
177        <code>do_timeout(<var>delay</var>, <var>fun</var>)</code>
226      <dd>178      </dt>
179      <dd>
227        Call this function to schedule a timeout. The given funct180        Call this function to schedule a timeout. The given funct
>ion will be called with no arguments provided after the specified>ion will be called with no arguments provided after the specified
> delay (in milliseconds). Note that you must call do_test_pending> delay (in milliseconds). Note that you must call do_test_pending
> so that the test isn't completed before your timer fires, and yo> so that the test isn't completed before your timer fires, and yo
>u must call do_test_finished when the actions you perform in the >u must call do_test_finished when the actions you perform in the 
>timeout complete, if you have no other functionality to test.&nbs>timeout complete, if you have no other functionality to test. (No
>p; (Note: the function argument used to be a string argument to b>te: the function argument used to be a string argument to be pass
>e passed to eval, and some older branches support only a string a>ed to eval, and some older branches support only a string argumen
>rgument or support both string and function.)>t or support both string and function.)
228      </dd>
229    </dl>181      </dd>
230    <dl>
n237    </dl>n
238    <dl>
n298      Since not all platforms support multi-process (electrolysisn247      Since not all platforms support multi-process (electrolysis
>, aka "e10s"), you need to put any e10s-specific tests in a separ>, aka "e10s"), you need to put any e10s-specific tests in a separ
>ate directory, and only run them if MOZ_IPC is defined.&nbsp; See>ate directory, and only run them if MOZ_IPC is defined. See /netw
> /netwerk/test/ for an example.&nbsp;&nbsp; Note that >erk/test/ for an example. Note that any "head_" or "ta
>any "head_" or "tail_" scripts you have in your usual tests direc>il_" scripts you have in your usual tests directory will not be r
>tory will not be run automatically in the new directory (but you >un automatically in the new directory (but you can write a simple
>can write a simple wrapper to load them: see "head_channels_clone> wrapper to load them: see "head_channels_clone.js" in netwerk/te
>.js" in netwerk/test/unit_ipc).>st/unit_ipc).
299    </p>
300    <p>248    </p>
249    <p>
301      By default xpcshell tests run in the parent process.&nbsp; 250      By default xpcshell tests run in the parent process. If you
>If you wish to run test logic in the child, you have several ways> wish to run test logic in the child, you have several ways to do
> to do it:> it:
n304      <li>Create a regular test_foo.js test, and then write a wran253      <li>Create a regular test_foo.js test, and then write a wra
>pper test_foo_wrap.js file that uses the run_test_in_child() func>pper test_foo_wrap.js file that uses the run_test_in_child() func
>tion to run an entire script file in the child.&nbsp;&nbsp; This >tion to run an entire script file in the child. This is an easy w
>is an easy way to arrange for a test to be run twice, once in chr>ay to arrange for a test to be run twice, once in chrome and then
>ome and then later (via the _wrap.js file) in content.&nbsp; See > later (via the _wrap.js file) in content. See /network/test/unit
>/network/test/unit_ipc for examples.&nbsp; The run_test_in_child(>_ipc for examples. The run_test_in_child() function takes a callb
>) function takes a callback, so you should be able to call it mul>ack, so you should be able to call it multiple times with differe
>tiple times with different files, if that's useful.>nt files, if that's useful.
n306      <li>For tests that need to run logic in both the parent + cn255      <li>For tests that need to run logic in both the parent + c
>hild processes during a single test run, you may use the poorly d>hild processes during a single test run, you may use the poorly d
>ocumented SendCommand() function, which takes a code string to be>ocumented SendCommand() function, which takes a code string to be
> executed on the child, and a callback function to be run on the > executed on the child, and a callback function to be run on the 
>parent when it has completed.&nbsp; You will want to first call d>parent when it has completed. You will want to first call do_load
>o_load_child_test_harness() to set up a reasonable test environme>_child_test_harness() to set up a reasonable test environment on 
>nt on the child.&nbsp; SendCommand returns immediately, so you wi>the child. SendCommand returns immediately, so you will generally
>ll generally want to use do_test_pending/do_test_finished with it> want to use do_test_pending/do_test_finished with it. NOTE: this
>.&nbsp;&nbsp;&nbsp; NOTE:&nbsp; this method of test has not been > method of test has not been used much, and your level of pain ma
>used much, and your level of pain may be significant.&nbsp; Consi>y be significant. Consider option #1 if possible.
>der option #1 if possible. 
n310      See the documentation for&nbsp; run_test_in_child() and do_n259      See the documentation for run_test_in_child() and do_load_c
>load_child_test_harness() in testing/xpcshell/head.js for more in>hild_test_harness() in testing/xpcshell/head.js for more informat
n441      Tests should be run using <code>make -C <em>OBJDIR/path_to_n390      Tests should be run using <code>./mach xpcshell-test <var>p
>tests/</em></code> (to copy tests) and then <code>make -C <em>OBJ>ath/to/tests/</var></code>. To run a single test, use <code>./mac
>DIR/path_to_tests/</em></code> <em><code>xpcshell-tests</code></e>h xpcshell-test <var>path/to/test.js</var></code>.
>m> (to run tests). Just <code>cd</code> to an appropriate directo 
>ry (e.g. to run tests for a single module, go to <code><a href="/ 
>en/MOZ_OBJDIR" title="en/MOZ_OBJDIR">MOZ_OBJDIR</a>/<em>path_to_t 
>ests</em>/test/</code>) and run <code>make</code> <em><code>xpcsh 
442    </p>
443    <p>391    </p>
444      To run a single test, use the <code>check-one</code> target
>, as described above. 
445    </p>
446    <div class="note">
447      <strong>Note:</strong> You must run <code>make -C <em>OBJDI
>R/path_to_tests/</em></code> before trying to run tests; the test 
>s are copied to a central location to be executed, and this copyi 
>ng occurs in the <code>libs</code> target of the build, which <co 
>de>make <em><span style="font-family: Verdana,Tahoma,sans-serif;" 
>>xpcshell-tests</span></em></code> does not invoke. On platforms  
>with symlinks, you can edit and re-run the test without re-making 
> the libs target, since the symlink will point to the file in you 
>r source directory. 
448    </div>
n471      Under e10s you have two processes.&nbsp; You can debug the n414      Under e10s you have two processes. You can debug the chrome
>chrome process, the child process, or both at the same time.&nbsp> process, the child process, or both at the same time.
n477      simply use "make check-interactive" as described above.&nbsn420      simply use "make check-interactive" as described above.
t483      The child process is where your xpcshell test's JS code is t426      The child process is where your xpcshell test's JS code is 
>being run, so it is often--but not always--the process you're int>being run, so it is often--but not always--the process you're int
>erested in.&nbsp; To debug the child, set MOZ_DEBUG_CHILD_PROCESS>erested in. To debug the child, set MOZ_DEBUG_CHILD_PROCESS=1 in 
>=1 in your environment (or on the command line) and run "make che>your environment (or on the command line) and run "make check-one
>ck-one", and you will see the child process emit a printf with it>", and you will see the child process emit a printf with its proc
>s process ID, then sleep.&nbsp; Attach a debugger to the child's >ess ID, then sleep. Attach a debugger to the child's pid, and whe
>pid, and when it wakes up you can debug it: &nbsp;>n it wakes up you can debug it:

Back to History