📄 d_o_h_ unit testing the dojo toolkit.mht
字号:
<LI class=3Dleaf id=3Dmenu-item-490><A class=3Dactive=20
=
href=3D"http://dojotoolkit.org/book/dojo-book-0-9/part-4-meta-dojo/d-o-h-=
unit-testing">D.O.H.=20
Unit Testing</A>=20
<LI class=3Dleaf id=3Dmenu-item-420><A=20
=
href=3D"http://dojotoolkit.org/book/dojo-book-0-9/part-4-meta-dojo/perfor=
mance-optimization">Performance=20
Optimization</A>=20
<LI class=3Dleaf id=3Dmenu-item-419><A=20
=
href=3D"http://dojotoolkit.org/book/dojo-book-0-9/part-4-meta-dojo/packag=
e-system-and-custom-builds">The=20
Package System and Custom Builds</A> </LI></UL>
<LI class=3Dcollapsed id=3Dmenu-item-301><A=20
=
href=3D"http://dojotoolkit.org/book/dojo-book-0-9/part-5-dojox-extensions=
-dojo-0">Part=20
5: DojoX</A> </LI></UL>
<LI class=3Dcollapsed id=3Dmenu-item-54><A title=3D"The Dojo Book, =
0.4"=20
href=3D"http://dojotoolkit.org/book/dojo-book-0-4">The Dojo Book, =
0.4</A>=20
</LI></UL></DIV></DIV></DIV></DIV>
<DIV class=3D"col-b content-region-container">
<DIV id=3Dmain-container><!-- main_content region -->
<H2>D.O.H. Unit Testing</H2><!--Node: -->
<DIV class=3Dnode>
<DIV class=3Dsubmitted>Submitted by alex on Sun, 08/05/2007 - =
21:09.</DIV>
<DIV class=3Dcontent>
<P>Dojo (from 0.9 onward) features a from-scratch unit testing harness, =
D.O.H.,=20
that's both flexible, easy to use, and portable. D.O.H. is designed to =
run in=20
both browser and command line environments and unlike it's predecessor =
doesn't=20
need to be run from the build system. D.O.H. has no Dojo dependencies, =
but can=20
use the Dojo package system if it's available, thereby allowing tests to =
be run=20
without need of the build tools at all. D.O.H. also includes a =
browser-based=20
test runner which can execute command-line tests as well as =
browser-specific=20
tests. When run from the command line, only pure-JS test are run. </P>
<H3>Test Registration</H3>
<P>D.O.H. defines one global object (doh.*) and code building tests can =
use APIs=20
defined on it to pass in a test, a group of tests, or a URL to pull a =
test group=20
from: </P>
<DIV class=3Dgeshifilter style=3D"FONT-FAMILY: monospace">doh.<SPAN=20
class=3Dme1>registerTest</SPAN><SPAN class=3Dbr0>(</SPAN>group, =
testFuncOrObj<SPAN=20
class=3Dbr0>)</SPAN>;<BR>doh.<SPAN class=3Dme1>registerTests</SPAN><SPAN =
class=3Dbr0>(</SPAN>group, testFuncOrObjArr<SPAN =
class=3Dbr0>)</SPAN>;<BR>doh.<SPAN=20
class=3Dme1>registerTestNs</SPAN><SPAN class=3Dbr0>(</SPAN>nsObj, =
objName<SPAN=20
class=3Dbr0>)</SPAN>;<BR>doh.<SPAN =
class=3Dme1>registerTestUrl</SPAN><SPAN=20
class=3Dbr0>(</SPAN>url<SPAN class=3Dbr0>)</SPAN>;<BR>doh.<SPAN=20
class=3Dme1>register</SPAN><SPAN class=3Dbr0>(</SPAN>...<SPAN=20
class=3Dbr0>)</SPAN>;</DIV>
<P>The tests.register() method accepts the function signatures of any of =
the=20
other registration functions and determines the correct underlying =
function to=20
dispatch registration to. </P>The contents of a typical, =
command-line-only, test=20
file might look something like:=20
<DIV class=3Dgeshifilter style=3D"FONT-FAMILY: monospace"><SPAN =
class=3Dco1>// file=20
located in core at:</SPAN><BR><SPAN class=3Dco1>// =20
tests/moduleToBeTested.js</SPAN><BR>dojo.<SPAN =
class=3Dme1>provide</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN =
class=3Dst0>"tests.moduleToBeTested"</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR>dojo.<SPAN class=3Dme1>require</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dst0>"doh.runner"</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR class=3Dgeshibr>doh.<SPAN =
class=3Dme1>register</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN =
class=3Dst0>"tests.moduleToBeTested"</SPAN>,<BR> =20
<SPAN class=3Dbr0>[</SPAN><BR> =
=20
<SPAN class=3Dco1>// single test, no test=20
fixture</SPAN><BR> =
<SPAN=20
class=3Dkw2>function</SPAN> assertTrueTest<SPAN =
class=3Dbr0>(</SPAN><SPAN=20
class=3Dbr0>)</SPAN><SPAN class=3Dbr0>{</SPAN><BR> =
=20
doh.<SPAN=20
class=3Dme1>assertTrue</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dkw2>true</SPAN><SPAN class=3Dbr0>)</SPAN>;<BR> =
=20
doh.<SPAN=20
class=3Dme1>assertTrue</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN =
class=3Dnu0>1</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR> =
=20
doh.<SPAN class=3Dme1>assertTrue</SPAN><SPAN =
class=3Dbr0>(</SPAN>!<SPAN class=3Dkw2>false</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR> =
=20
<SPAN class=3Dbr0>}</SPAN>,<BR> =
=20
<SPAN class=3Dco1>// a test fixture</SPAN><BR> =
=20
<SPAN class=3Dbr0>{</SPAN><BR> =
=20
<SPAN=20
class=3Dkw3>name</SPAN>: <SPAN =
class=3Dst0>"thingerTest"</SPAN>,<BR> =20
=
setUp:=20
<SPAN class=3Dkw2>function</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dbr0>)</SPAN><SPAN class=3Dbr0>{</SPAN><BR> =
=20
=
=20
<SPAN class=3Dkw1>this</SPAN>.<SPAN class=3Dme1>thingerToTest</SPAN> =3D =
<SPAN=20
class=3Dkw2>new</SPAN> Thinger<SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR> =
=20
<SPAN=20
class=3Dkw1>this</SPAN>.<SPAN class=3Dme1>thingerToTest</SPAN>.<SPAN=20
class=3Dme1>doStuffToInit</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR> =
=20
<SPAN class=3Dbr0>}</SPAN>,<BR> =
=20
runTest: =
<SPAN=20
class=3Dkw2>function</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN =
class=3Dbr0>)</SPAN><SPAN=20
class=3Dbr0>{</SPAN><BR> =
=20
doh.<SPAN=20
class=3Dme1>assertEqual</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dst0>"blah"</SPAN>, <SPAN class=3Dkw1>this</SPAN>.<SPAN=20
class=3Dme1>thingerToTest</SPAN>.<SPAN class=3Dme1>blahProp</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR> =
=20
doh.<SPAN=20
class=3Dme1>assertFalse</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dkw1>this</SPAN>.<SPAN class=3Dme1>thingerToTest</SPAN>.<SPAN=20
class=3Dme1>falseProp</SPAN><SPAN class=3Dbr0>)</SPAN>;<BR> =
=20
=
=20
<SPAN class=3Dco1>// ...</SPAN><BR> =
=20
<SPAN=20
class=3Dbr0>}</SPAN>,<BR> =
=20
tearDown: <SPAN =
class=3Dkw2>function</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dbr0>)</SPAN><SPAN =
class=3Dbr0>{</SPAN><BR> =20
=
=20
<SPAN class=3Dbr0>}</SPAN><BR> =
=20
<SPAN class=3Dbr0>}</SPAN>,<BR> =
=20
<SPAN class=3Dco1>// ...</SPAN><BR> =
<SPAN=20
class=3Dbr0>]</SPAN><BR><SPAN class=3Dbr0>)</SPAN>;</DIV>
<P>In this example, we see a variant of the test system that uses the=20
doh.addTests() style of add() and registers both independent tests and=20
fixture-driven tests. Note that we give the functions that are =
registered names=20
even though we could easily provide anonymous functions. This allows the =
system=20
to more correctly report on what went wrong and where, allowing you to =
talk more=20
intelligently about your tests passing or failing. The fixture-based =
example=20
uses the "name" property to provide the same information. </P>
<H3>Assertions</H3>
<P>D.O.H. exposes a small but adequate number of assertion APIs: </P>
<DIV class=3Dgeshifilter style=3D"FONT-FAMILY: monospace">doh.<SPAN=20
class=3Dme1>assertEqual</SPAN><SPAN class=3Dbr0>(</SPAN>expected, =
actual<SPAN=20
class=3Dbr0>)</SPAN>; <SPAN class=3Dco1>// aliased to: doh.is(e,=20
a)</SPAN><BR>doh.<SPAN class=3Dme1>assertTrue</SPAN><SPAN=20
class=3Dbr0>(</SPAN>condition<SPAN class=3Dbr0>)</SPAN>; <SPAN =
class=3Dco1>// aliased=20
to: doh.t(condition)</SPAN><BR>doh.<SPAN =
class=3Dme1>assertFalse</SPAN><SPAN=20
class=3Dbr0>(</SPAN>condition<SPAN class=3Dbr0>)</SPAN>; <SPAN =
class=3Dco1>// aliased=20
to: doh.f(condition)</SPAN></DIV>
<H3>Asynchronous Tests</H3>
<P>D.O.H. provides direct support for asynchronous test cases. Writing=20
asynchronous tests depends on a script context that "knows about" =
asynchronous=20
execution (aka, a browser but not Rhino) and a slightly modified test =
authoring=20
syntax: </P>
<DIV class=3Dgeshifilter style=3D"FONT-FAMILY: monospace">doh.<SPAN=20
class=3Dme1>register</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dst0>"tests.moduleToBeTested"</SPAN>,<BR> =
<SPAN=20
class=3Dco1>// the async text fixture</SPAN><BR> =
=20
<SPAN class=3Dbr0>{</SPAN><BR> =
=20
<SPAN class=3Dkw3>name</SPAN>: <SPAN=20
class=3Dst0>"thingerTest"</SPAN>,<BR> =
=20
timeout: <SPAN class=3Dnu0>2000</SPAN>, <SPAN =
class=3Dco1>// 2=20
seconds, defaults to half a second</SPAN><BR> =
=20
setUp: <SPAN class=3Dkw2>function</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dbr0>)</SPAN><SPAN =
class=3Dbr0>{</SPAN><BR> =20
=
=20
<SPAN class=3Dkw1>this</SPAN>.<SPAN class=3Dme1>thingerToTest</SPAN> =3D =
<SPAN=20
class=3Dkw2>new</SPAN> Thinger<SPAN class=3Dbr0>(</SPAN><SPAN=20
class=3Dbr0>)</SPAN>;<BR> =
=20
<SPAN class=3Dkw1>this</SPAN>.<SPAN=20
class=3Dme1>thingerToTest</SPAN>.<SPAN =
class=3Dme1>doStuffToInit</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dbr0>)</SPAN>;<BR> =
=20
<SPAN class=3Dbr0>}</SPAN>,<BR> =
=20
runTest: <SPAN =
class=3Dkw2>function</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dbr0>)</SPAN><SPAN =
class=3Dbr0>{</SPAN><BR> =20
=
=20
<SPAN class=3Dkw2>var</SPAN> testCondition =3D <SPAN=20
class=3Dkw2>true</SPAN>;<BR> =
=20
<SPAN class=3Dkw2>var</SPAN> d =3D =
<SPAN=20
class=3Dkw2>new</SPAN> doh.<SPAN class=3Dme1>Deferred</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dbr0>)</SPAN>;<BR> =
=20
setTimeout<SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dkw2>function</SPAN><SPAN =
class=3Dbr0>(</SPAN><SPAN=20
class=3Dbr0>)</SPAN><SPAN class=3Dbr0>{</SPAN><BR> =
=20
=
=20
<SPAN class=3Dkw1>try</SPAN><SPAN class=3Dbr0>{</SPAN><BR> =
=20
=
=20
<SPAN =
class=3Dkw1>if</SPAN><SPAN=20
class=3Dbr0>(</SPAN>testCondition<SPAN class=3Dbr0>)</SPAN><SPAN=20
class=3Dbr0>{</SPAN><BR> =
=20
=
=20
d.<SPAN =
class=3Dme1>callback</SPAN><SPAN=20
class=3Dbr0>(</SPAN><SPAN class=3Dkw2>true</SPAN><SPAN =
class=3Dbr0>)</SPAN>;<BR> =20
=
=20
<SPAN=20
class=3Dbr0>}</SPAN><SPAN class=3Dkw1>else</SPAN><SPAN =
class=3Dbr0>{</SPAN><BR> =20
=
=20
=
=20
d.<SPAN class=3Dme1>errback</SPAN><SPAN class=3Dbr0>(</SPAN><SPAN =
class=3Dkw2>new</SPAN> Error<SPAN class=3Dbr0>(</SPAN><SPAN =
class=3Dst0>"we got a=20
failure"</SPAN><SPAN class=3Dbr0>)</SPAN><SPAN =
class=3Dbr0>)</SPAN>;<BR> =20
=
=20
<SPAN=20
class=3Dbr0>}</SPAN><BR> =
=20
<SPAN=20
class=3Dbr0>}</SPAN><SPAN class=3Dkw1>catch</SPAN><SPAN =
class=3Dbr0>(</SPAN>e<SPAN=20
class=3Dbr0>)</SPAN><SPAN class=3Dbr0>{</SPAN><BR> =
=20
=
=20
d.<SPAN class=3Dme1>errback</SPAN><SPAN=20
class=3Dbr0>(</SPAN>e<SPAN class=3Dbr0>)</SPAN>;<BR> =
=20
=
=20
<SPAN class=3Dbr0>}</SPAN><BR> =
=20
<SPAN class=3Dbr0>}</SPAN>, =
<SPAN=20
class=3Dnu0>100</SPAN><SPAN class=3Dbr0>)</SPAN>;<BR> =
=20
<SPAN=20
class=3Dkw1>return</SPAN> d;<BR> =
=20
<SPAN class=3Dbr0>}</SPAN><BR> <SPAN=20
class=3Dbr0>}</SPAN><BR><SPAN class=3Dbr0>)</SPAN>;</DIV>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -