# NPM 테스트([name])

이 문서에서는 [link:https://nodejs.org/en/ node.js] 환경에서 three.js를 사용해 자동 테스트를 진행해보는 방법을 알려드립니다. 테스트는 커맨드 라인으로 실행이 가능하며 [link:https://travis-ci.org/ Travis]같은 CI 툴을 통해 자동으로 실행이 가능합니다.

## 간단한 버전

node와 npm이 친숙하다면, `$ npm install three --save-dev` 그리고 여기에 `const THREE = require('three');` 를 추가합니다.

## scratch에서 테스트 가능한 예제 만들기

이 툴들에 익숙치 않다면, 아래의 간단한 가이드(리눅스 기반으로, 윈도우에서의 설치 절차와는 조금 다릅니다. 하지만 NPM 커맨드는 같습니다)를 따라주세요.

### 기본 설치

1. [link:https://www.npmjs.org/ npm] 과 nodejs를 설치합니다. 가장 짧은 설치 명령어는 다음과 같습니다. `$ sudo apt-get install -y npm nodejs-legacy # 기본 레지스트리 URL에서 SSL 문제가 생기면 수정해주세요 $ npm config set registry http://registry.npmjs.org/`
2. 새 프로젝트 폴더를 만듭니다. `$ mkdir test-example; cd test-example`
3. npm에게 새 프로젝트 파일을 만들게 합니다: `$ npm init` 엔터를 계속 쳐서 기본 설정으로 동의 후 진행하세요. 이 절차가 끝나면 package.json 파일이 생길 것입니다.
4. 다음 코드로 테스트를 시작해 보세요 `$ npm test` 아마 실패가 뜰 것입니다. package.json 파일을 보면, test 스크립트의 경로가 다음과 같이 되어 있을 것입니다. `"test": "echo \"Error: no test specified\" && exit 1"`

## mocha 추가하기

[link:https://mochajs.org/ mocha]를 사용할 것입니다.

1. mocha는 아래 명령어로 설치합니다. `$ npm install mocha --save-dev` node_modules/이 생성되어 있고 파일들이 있어야 합니다. 그리고 package.json의 내용이 업데이트 되었는지도 확인해봐야 합니다. --save-dev를 통해 devDependencies 속성에 업데이트가 되어있어야 합니다.
2. mocha가 동작하는지 확인하기 위해 package.json을 수정합니다. 우리가 하고자 하는 것은 test를 치면 mocha를 동작하고 여러 리포터를 확인하는 것입니다. 기본적으로 이 명령어는 test/ 의 모든 것을 실행할 것입니다. (test/ 폴더가 없다면 npm ERR!가 나올 것입니다, mkdir test로 만들어주세요) `"test": "mocha --reporter list"`
3. test를 다시 실행시킵니다. `$ npm test` 아마 성공 메세지가 뜨고 0 passing (1ms)와 비슷한 문구가 뜰 것입니다.

## three.js 추가

1. three.js를 다음과 같이 추가합니다. `$ npm install three --save-dev`
   - 다른 three 버전을 사용하려면, 아래 명령어를 입력하고 `$ npm show three versions` 사용 가능한 버전을 확인해, npm에게 특정 버전을 사용하라고 합니다. `$ npm install three@0.84.0 --save` (이 예제에서는 0.84.0 버전을 사용했습니다.). --save 는 dev 설정이 아닌 이 프로젝트의 의존성으로 추가하는 명령어입니다. 여기([link:https://docs.npmjs.com/cli/v8/configuring-npm/package-json link])에서 더 많은 내용을 확인하세요.
2. Mocha 는 test/에서 test를 찾을 것이기 때문에, 아래 명령어를 입력합니다. `$ mkdir test`
3. 이제 마지막으로 JS 테스트가 남았습니다. three.js가 잘 작동하는지 간단한 테스트를 통해 확인해 봅시다. test/verify-three.js 파일을 만들고 안에 다음 내용을 넣어주세요: `const THREE = require('three'); const assert = require('assert'); describe('The THREE object', function() { it('should have a defined BasicShadowMap constant', function() { assert.notEqual('undefined', THREE.BasicShadowMap); }), it('should be able to construct a Vector3 with default of x=0', function() { const vec3 = new THREE.Vector3(); assert.equal(0, vec3.x); }) })`
4. 마지막으로 $ npm test로 확인해봅시다. 위의 테스트 파일을 성공적으로 실행시키고 다음과 같은 내용이 나올 것입니다. `The THREE object should have a defined BasicShadowMap constant: 0ms The THREE object should be able to construct a Vector3 with default of x=0: 0ms 2 passing (8ms)`

## 자신의 코드 추가하기

세 가지를 수행해야 합니다:

1. 자신의 코드의 예상 결과가 들어있는 예제를 만들어, test/ 폴더 안에 두세요. 여기([link:https://github.com/air/encounter/blob/master/test/Physics-test.js link])에서 진짜 프로젝트의 예제를 확인할 수 있습니다.
2. nodeJS에서 알아볼 수 있는, require를 사용해 기능들을 내보내기 하세요. 여기([link:https://github.com/air/encounter/blob/master/js/Physics.js link])를 참고하세요.
3. 테스트 파일에서 코드를 불러오세요. 같은 방식으로 우리는 위의 예제에서 require('three')를 불러왔습니다.

2번과 3번 과정은 자신의 코드를 어떻게 관리하는지에 따라 달려 있습니다. 위의 Physics.js 예제에서는 내보내기 부분이 맨 마지막에 있습니다. module.exports에 할당했습니다.

`//============================================================================= // make available in nodejs //============================================================================= if (typeof exports !== 'undefined') { module.exports = Physics; }`

## 의존성 관리

require.js나 browserify같은 현명한 방법을 사용하고 있다면 이 부분은 넘어가세요.

일반적으로 three.js 프로젝트는 브라우저에서 돌아가게 하기 위한 목적입니다. 따라서 모듈 로딩은 브라우저가 스크립트 태그를 실행함으로써 이루어집니다. 개인 파일은 의존성에 대해 걱정하지 않아도 됩니다. 하지만 nodejs 환경에서는 모든 것을 묶어놓은 index.html이 없기 때문에, 분명히 해 둘 필요가 있습니다.

다른 파일에 의존하는 모듈을 내보내기 할 때에는, node에 같이 내보내기하라고 알려줘야 합니다. 그 방법 중 하나는 다음과 같습니다:

1. 모듈의 시작 부분에서 nodejs 환경인지 체크합니다.
2. 만약 그렇다면 의존성을 명확하게 선언해줍니다.
3. 그렇지 않다면 브라우저 환경일 것이기 때문에 아무것도 할 것이 없습니다.

Physics.js의 예제입니다: `//============================================================================= // 서버사이드 테스트 설정 //============================================================================= if (typeof require === 'function') // nodejs 환경 테스트 { const THREE = require('three'); const MY3 = require('./MY3.js'); }`