MochaJS

Mocha.js는 Node.js와 브라우저 환경 모두에서 동작하는 유연하고 강력한 JavaScript 코드의 단위 테스트, 통합 테스트 등을 위한 JavaScript 테스팅 프레임워크.
2011년 TJ Holowaychuk에 의해 개발되었으며, 개발자들에게 테스트 작성의 자유와 유연성을 제공한다.

주요 특징

  1. 유연한 테스트 스타일
    Mocha는 다양한 어설션(assertion) 라이브러리와 함께 사용할 수 있어, 개발자의 선호에 따라 테스트 스타일을 커스터마이징할 수 있다.
    대표적으로 Chai, Should.js, Expect.js 등의 라이브러리와 호환된다.

  2. 비동기 테스트 지원
    비동기 코드 테스트에 특화되어 있으며, Promise, async/await, 콜백 등 다양한 비동기 패턴을 쉽게 테스트할 수 있다.

  3. 풍부한 Hooks
    테스트 실행 전후에 사용할 수 있는 다양한 후크(hook)를 제공한다:

    • before(): 테스트 수트의 첫 테스트 전에 실행
    • after(): 모든 테스트 완료 후 실행
    • beforeEach(): 각 테스트 전에 실행
    • afterEach(): 각 테스트 후에 실행

장점

  1. 높은 유연성: 어설션 라이브러리, 리포팅 도구 선택의 자유
  2. 간결하고 표현적인 테스트 구문
  3. 브라우저와 Node.js 양쪽 지원
  4. 다양한 비동기 테스트 패턴 지원
  5. 풍부한 플러그인 생태계

단점 및 한계

  1. 기본적으로 어설션 라이브러리를 포함하지 않아 별도 설치 필요
  2. 초기 설정에 다소 복잡성
  3. 대규모 프로젝트에서는 추가 설정 필요
  4. 순수 테스트 러너이므로 모킹, 스파이 기능은 제한적

설치 및 기본 설정

  1. Npm을 통한 설치

    1
    
    npm install --save-dev mocha chai
    
  2. package.json 스크립트

    1
    2
    3
    4
    5
    6
    
    {
      "scripts": {
        "test": "mocha",
        "test:watch": "mocha --watch"
      }
    }
    

주요 사용 방법 및 예시

주요 명령어

기본 테스트 구조

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const assert = require('chai').assert;

describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal([1, 2, 3].indexOf(4), -1);
    });
    
    it('should return the correct index when the value is present', function() {
      assert.equal([1, 2, 3].indexOf(2), 1);
    });
  });
});

비동기 테스트

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
describe('Async Test', function() {
  // done 콜백 사용
  it('should complete an async operation', function(done) {
    setTimeout(function() {
      assert.ok(true);
      done();
    }, 1000);
  });

  // Promise 기반 테스트
  it('should resolve a promise', function() {
    return fetchData().then(data => {
      assert.exists(data);
    });
  });

  // Async/Await 테스트
  it('should handle async/await', async function() {
    const result = await asyncFunction();
    assert.equal(result, 'expected value');
  });
});

Hooks 사용 예시

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
describe('Database Connection', function() {
  let connection;

  before(function() {
    // 테스트 수트 시작 전 한 번만 실행
    connection = connectToDatabase();
  });

  beforeEach(function() {
    // 각 테스트 전 실행
    connection.reset();
  });

  it('should insert data', function() {
    // 테스트 로직
  });

  after(function() {
    // 모든 테스트 완료 후 실행
    connection.close();
  });
});

테스트 필터링 및 제어

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 특정 테스트만 실행
mocha test/specific-test.js

# 패턴으로 테스트 필터링
mocha 'test/**/*.test.js'

# 특정 테스트 건너뛰기
it.skip('skipped test', function() {
  // 이 테스트는 실행되지 않음
});

고급 기능

커스텀 리포터

1
2
3
4
# 다양한 리포터 사용 가능
mocha -R spec        # 기본 리포터
mocha -R json        # JSON 리포터
mocha -R nyan        # Nyan Cat 스타일 리포터

타임아웃 설정

1
2
3
4
5
6
7
describe('Slow Test', function() {
  // 개별 테스트 타임아웃
  it('should complete', function(done) {
    this.timeout(5000);  // 5초 타임아웃
    // 비동기 로직
  });
});

참고 및 출처

Fetching Title#79hq