본문 바로가기

Software Development

Jasmine을 활용한 Front-end JS Test Automation

Jasmine

http://jasmine.github.io/

BDD 사상을 가지고 구현 된 테스팅 프레임워크.

Jasmine 설치

NPM을 이용 해 jasmine을 머신에 설치한다.

# shell command를 이용해 jasmine을 설치한다. global로 설치 수행
# npm이 없다면 npm과 nodejs를 설치해야 함.
 
$ npm install -g jasmine

프로젝트 초기화

jasmine init 명령어로 jasmine 프로젝트를 생성한다.

$ jasmine init
$ tree
.
└── spec
    └── support
        └── jasmine.json

프로젝트 디렉토리 안에 위와 같은 구조의 파일이 생겨남

spec

jasmine test script가 저장되는 디렉토리

support

jasmine test를 위한 설정파일이 존재하는 디렉토리

jasmine.json

jasmine test project의 설정파일

기존 프로젝트에 Jasmine 적용해 보기

hello-jasmine 프로젝트

요구사항

일단 jasmine적용에 대한 내용에 앞서, 간단한 가상의 프로젝트를 하나 정의해 본다. 요구사항은 아래와 같음.

  • 웹페이지가 하나 있는데, 웹 페이지가 로드 되고 나면 console창에 hello 라는 텍스트를 출력해야 함.

끝.

디자인 스크래치

구현에 대한 간단한 스크래치를 해 보고, 구현체들에 대한 디자인을 간략하게 정의 해 보자.

  • 웹페이지가 하나 있어야 하므로, html을 하나 만들어 준다.
  • 웹페이지가 로드되고 나서 console에 텍스트를 출력해야 하니, 그에 필요한 js파일이 필요하다.

좀 더 수월한 TDD를 위해 몇가지 더 생각해 보자.

  • console에 출력하는 스크립트를 테스트 하기 위해, 모듈화를 해야한다.
  • hello 텍스트를 리턴하는 함수를 하나 만들자.

hello-jasmine 프로젝트 구성

소스를 저장 할 src 디렉토리와 jasmine test를 위한 jasmine 디렉토리를 생성함.

$ mkdir src jasmine
$ tree
.
├── jasmine
├── README.md
└── src

 

src 디렉토리에 index.html을 생성하고, 콘솔에 hello를 출력하는 스크립트를 저장 할 js 디렉토리를 만든다.

# src 디렉토리로 이동
$ cd src
$ touch index.html
$ mkdir js

 

index.html을 다음과 같이 만들어 본다.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src='./js/hello-jasmine.js'></script>
</head>
<body>
</body>
</html>

 

hello-jasmine.js를 생성해 준다.

$ touch js/hello-jasmine.js
 
# src 하위 디렉토리 구조
$ tree
.
├── index.html
└── js
    └── hello-jasmine.js

 

기본적인 틀은 다 잡혔으니 tdd를 위한 jasmine 테스트 코드를 작성해 본다.

# src에서 프로젝트 디렉토리로 이동한다.
$ cd ..
$ cd jasmine
 
# jasmine 프로젝트를 초기화 한다.
$ jasmine init
 
# spec 디렉토리 안에 hello-jasmine.js를 테스트 하기 위한 spec문서를 만들자
$ touch spec/hello-jasmine_spec.js
 

 

테스트 코드를 작성해 보자.

// file: spec/hello-jasmine_spec.js
 
// hello-jasmine에 대해 묘사한다..
describe('hello-jasmine.js'function() {
 
    var helloJasmine;
 
    // 각각의 테스트 이전에...
    beforeEach(function() {
 
        // helloJasmine에 정의한 모듈을 로드한다.
        helloJasmine = require('../../src/js/hello-jasmine.js');
    });
 
    // 그것은.. undefined가 되어선 안된다.
    it('should not be undefined'function() {
        expect(typeof helloJasmine).not.toBe('undefined');
    });
 
    // 그것은. getHello라는 함수를 가지고 있어야 한다.
    it('should have getHello'function() {
        expect(typeof helloJasmine.getHello).not.toBe('undefined');
        expect(typeof helloJasmine.getHello).toBe('function');
    });
 
    // getHello 함수가 호출될 때, hello라는 텍스트를 반환해야 한다.
    it('should returns hello when getHello is called.'function() {
        expect(helloJasmine.getHello()).toBe('hello');
    });
});

(테스트 코드에 사용되는 함수들의 이름이 꽤나 인상적임.)

 

hello-jasmine.js에 대한 행위가 모두 정의되었으면 한번 테스트를 돌려본다.

# jasmine 디렉토리에서 jasmine 실행
$ jasmine
FFF
 
# :
# 아무것도 구현된 것이 없으므로, 테스트는 실패할 것이다.

테스트를 모두 통과 할 때까지 열심히 디버깅 한다.

 

hello-jasmine.js

첫번째 스펙 만족시키기

일단 첫번째 행동에 대한 스펙을 만족시키기 위해 export를 해서 undefined가 되지 않도록 하자.

// file: hello-jasmine.js
 
// jasmine 테스트를 돌리기 위해 node module로 정의해야 하므로
// exports객체를 object로 정의한다.
!function() {
    if (typeof module !== 'undefined')
        module.exports = {};
}();

 

저장하고 다시 테스트를 돌려보면..

$ jasmine
.FF
 
# : 어쩌고저쩌고

첫번째 테스트를 통과한다.

module.exports를 사용하는 이유

jasmine이 구동되는 환경이 nodejs다 보니, 부득이하게 front-end script에 module.exports 객체에 매핑시키는 함수가 포함이 되었다.

jasmine을 webpage로 구성하여 nodejs대신 테스트를 수행할 수도 있지만.. 이럴 경우 자동화 구성이 다소 까다로워 지는 단점이 있다.

 

다음은 두번째 스펙

모듈이 가진 getHello가 함수가 되도록 해야한다.

웹페이지 에서도 출력 되어야 하니 일단 global로 함수를 선언 하고, exports에 포함시키도록 하자.

// file: hello-jasmine.js
 
// 함수를 정의한다.
var getHello = function() {
};
// module을 object로 정의한다.
!function() {
    if (typeof module !== 'undefined')
        module.exports = {
            // getHello를 exports에 매핑 시켜 준다.
            getHello: getHello
        };
}();

 

다시 jasmine 스펙 문서를 돌려 보면..

$ jasmine
..F

 

이제 하나만 더 만족 시키면 됨.

 

마지막 스펙 hello 출력하기

getHello 함수에 hello를 리턴 하도록 해서, 마지막 스펙도 만족 시킬 수 있도록 한다.

// file: hello-jasmine.js
 
// 함수를 정의한다.
var getHello = function() {
 
    // hello string를 리턴한다.
    return 'hello';
};
 
// module을 object로 정의한다.
!function() {
    if (typeof module !== 'undefined')
        module.exports = {
            // getHello를 exports에 매핑 시켜 준다.
            getHello: getHello
        };
}();

 

다시 jasmine을 돌려보면..

$ jasmine
...

모든 스펙을 만족하는 코드가 만들어 졌다.

완성 된 hello-jasmine.js를 웹 페이지에 적용하기

아까 작성한 index.html의 body태그에 script를 불러와서, DOM이 완전히 로드되고 스크립트가 실행될 수 있도록 한다.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src='./js/hello-jasmine.js'></script>
</head>
<body>
    <script type="text/javascript">
        console.log(getHello());
    </script>
</body>
</html>