Testing-with-NPM.html 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <base href="../../../" />
  6. <script src="page.js"></script>
  7. <link type="text/css" rel="stylesheet" href="page.css" />
  8. </head>
  9. <body>
  10. <h1>[name]</h1>
  11. <p class="desc">
  12. This article shows how to get three.js into a [link:https://nodejs.org/en/ node.js] environment so that you
  13. can execute automated tests. Tests can be run on the command line, or by automated
  14. CI tools like [link:https://travis-ci.org/ Travis].
  15. </p>
  16. <h2>The short version</h2>
  17. <p>
  18. If you're comfortable with node and npm,
  19. <code>
  20. $ npm install three --save-dev
  21. </code>
  22. and add
  23. <code>
  24. const THREE = require('three');
  25. </code>
  26. to your test.
  27. </p>
  28. <h2>Create a testable project from scratch</h2>
  29. <p>
  30. If you're not familiar with these tools, here's a quick guide (for linux, the installation process
  31. will be slightly different using windows, but the NPM commands are identical).
  32. </p>
  33. <h3>Basic setup</h3>
  34. <div>
  35. <ol>
  36. <li>
  37. Install [link:https://www.npmjs.org/ npm] and nodejs. The shortest path typically looks something like
  38. <code>
  39. $ sudo apt-get install -y npm nodejs-legacy
  40. # fix any problems with SSL in the default registry URL
  41. $ npm config set registry http://registry.npmjs.org/
  42. </code>
  43. </li>
  44. <li>
  45. Make a new project directory
  46. <code>
  47. $ mkdir test-example; cd test-example
  48. </code>
  49. </li>
  50. <li>
  51. Ask npm to create a new project file for you:
  52. <code>
  53. $ npm init
  54. </code>
  55. and accept all defaults by hitting Enter on all the prompts.
  56. This will create package.json.
  57. </li><br />
  58. <li>
  59. Try and start the test feature with
  60. <code>
  61. $ npm test
  62. </code>
  63. This will fail, which is expected.
  64. If you look in the package.json, the definition of the test script is
  65. <code>
  66. "test": "echo \"Error: no test specified\" && exit 1"
  67. </code>
  68. </li>
  69. </ol>
  70. </div>
  71. <h2>Add mocha</h2>
  72. <div>
  73. We're going to use [link:https://mochajs.org/ mocha].
  74. <ol>
  75. <li>
  76. Install mocha with
  77. <code>
  78. $ npm install mocha --save-dev
  79. </code>
  80. Notice that node_modules/ is created and your dependencies appear in there.
  81. Also notice that your package.json has been updated: the property devDependencies
  82. is added and updated by the use of --save-dev.
  83. </li><br />
  84. <li>
  85. Edit package.json to use mocha for testing. When test is invoked, we just want to run
  86. mocha and specify a verbose reporter. By default this will run anything in test/
  87. (not having directory test/ can run into npm ERR!, create it by mkdir test)
  88. <code>
  89. "test": "mocha --reporter list"
  90. </code>
  91. </li>
  92. <li>
  93. Rerun the test with
  94. <code>
  95. $ npm test
  96. </code>
  97. This should now succeed, reporting 0 passing (1ms)
  98. or similar.
  99. </li>
  100. </ol>
  101. </div>
  102. <h2>Add three.js</h2>
  103. <div>
  104. <ol>
  105. <li>
  106. Let's pull in our three.js dependency with
  107. <code>
  108. $ npm install three --save-dev
  109. </code>
  110. <ul>
  111. <li>
  112. If you need a different three version, use
  113. <code>
  114. $ npm show three versions
  115. </code>
  116. to see
  117. what's available. To tell npm the right one, use
  118. <code>
  119. $ npm install [email protected] --save
  120. </code>
  121. (0.84.0 in this example). --save makes this a dependency of this project, rather than
  122. dev dependency. See the docs [link:https://www.npmjs.org/doc/json.html here] for more info.
  123. </li>
  124. </ul>
  125. </li>
  126. <li>
  127. Mocha will look for tests in test/, so let's
  128. <code>
  129. $ mkdir test
  130. </code>
  131. </li>
  132. <li>
  133. Finally we actually need a JS test to run. Let's add a simple test that will verify that
  134. the three.js object is available and working. Create test/verify-three.js containing:
  135. <code>
  136. const THREE = require('three');
  137. const assert = require('assert');
  138. describe('The THREE object', function() {
  139. it('should have a defined BasicShadowMap constant', function() {
  140. assert.notEqual('undefined', THREE.BasicShadowMap);
  141. }),
  142. it('should be able to construct a Vector3 with default of x=0', function() {
  143. const vec3 = new THREE.Vector3();
  144. assert.equal(0, vec3.x);
  145. })
  146. })
  147. </code>
  148. </li>
  149. <li>
  150. Finally let's test again with $ npm test. This should run the tests above and succeed,
  151. showing something like:
  152. <code>
  153. The THREE object should have a defined BasicShadowMap constant: 0ms
  154. The THREE object should be able to construct a Vector3 with default of x=0: 0ms
  155. 2 passing (8ms)
  156. </code>
  157. </li>
  158. </ol>
  159. </div>
  160. <h2>Add your own code</h2>
  161. <div>
  162. You need to do three things:
  163. <ol>
  164. <li>
  165. Write a test for the expected behaviour of your code, and place it under test/.
  166. [link:https://github.com/air/encounter/blob/master/test/Physics-test.js Here] is an example from a real project.
  167. </li>
  168. <li>
  169. Export your functional code in such a way that nodejs can see it, for use in conjunction with require.
  170. See it [link:https://github.com/air/encounter/blob/master/js/Physics.js here].
  171. </li>
  172. <li>
  173. Require your code into the test file, in the same way we did a require('three') in the example above.
  174. </li>
  175. </ol>
  176. <p>
  177. Items 2 and 3 will vary depending on how you manage your code. In the example of Physics.js
  178. given above, the export part is right at the end. We assign an object to module.exports:
  179. </p>
  180. <code>
  181. //=============================================================================
  182. // make available in nodejs
  183. //=============================================================================
  184. if (typeof exports !== 'undefined')
  185. {
  186. module.exports = Physics;
  187. }
  188. </code>
  189. </div>
  190. <h2>Dealing with dependencies</h2>
  191. <div>
  192. <p>
  193. If you're already using something clever like require.js or browserify, skip this part.
  194. </p>
  195. <p>
  196. Typically a three.js project is going to run in the browser. Module loading is hence done by
  197. the browser executing a bunch of script tags. Your individual files don't have to worry
  198. about dependencies. In a nodejs context however, there is no index.html binding everything
  199. together, so you have to be explicit.
  200. </p>
  201. <p>
  202. If you're exporting a module that depends on other files, you're going to have to tell node to load them.
  203. Here is one approach:
  204. </p>
  205. <ol>
  206. <li>
  207. At the start of your module, check to see if you're in a nodejs environment.
  208. </li>
  209. <li>
  210. If so, explicitly declare your dependencies.
  211. </li>
  212. <li>
  213. If not, you're probably in a browser so you don't need to do anything else.
  214. </li>
  215. </ol>
  216. Example code from Physics.js:
  217. <code>
  218. //=============================================================================
  219. // setup for server-side testing
  220. //=============================================================================
  221. if (typeof require === 'function') // test for nodejs environment
  222. {
  223. const THREE = require('three');
  224. const MY3 = require('./MY3.js');
  225. }
  226. </code>
  227. </div>
  228. </body>
  229. </html>