채점 스크립트 작성하기

1. 나이트워치 (Nightwatch.js)

구름EDU에서는 웹 서비스/애플리케이션 개발 문제 혹은 HTML/CSS/JS 프로그래밍 문제는 나이트워치 라는 UI테스트 프레임워크를 활용하여 채점을 합니다. 웹 관련 문제의 정확한 채점을 위해서는 나이트워치 라는 UI테스트 프레임워크에 익숙해져야 합니다.

Nightwatch.js 공식 사이트

2. 채점 스크립트 작성해보기 #1

본 도움말에서 Nightwatch.js의 모든 기능과 API에 대해서 설명을 할 수는 없기에 공식 사이트에 있는 아래의 예제를 기준으로 개념적인 부분을 설명합니다.

module.exports = {
  'Demo test Google' : function (browser) {
    browser
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .setValue('input[type=text]', 'nightwatch')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('#main', 'Night Watch')
      .end();
  }
};
  1. module.exports = { : node.js의 문법으로써 사용자 모듈을 만드는 과정입니다. { 이하로 할당되었기 때문에 여러 테스트 메소드를 가지는 객체가 될 것입니다.

  2. 'Demo test Google' : function (browser) { : 테스트 케이스의 이름과 거기에 할당되는 테스트 메소드입니다. 이 코드에서는 'Demo test Google' 이라는 이름으로 작성이 시작되었습니다.

  3. browser : Nightwatch.js 에서는 가상의 웹브라우저가 객체 형태로 각각의 테스트 메소드에 전달됩니다. 이 browser는 우리가 개념적으로 알고 있는 웹브라우저로서, 눈에 보이지는 않지만 마치 웹브라우저처럼 동작하는 가상의 객체라고 이해하면 됩니다.

  4. .url('http://www.google.com') : .url()browser 객체에게 특정 웹사이트의 URL로 접속하게 만드는 메서드로써, 이 코드에서는 구글로 접속하게 하고 있습니다.

  5. .waitForElementVisible('body', 1000) : 웹페이지의 기본 골격을 담당하는 body 태그가 화면에 보여질(Visible) 때까지 최대 '1초(=1000ms)간' 기다린다는 의미의 메서드입니다.

  6. .setValue('input[type=text]', 'nightwatch') : 화면에 보이는 요소 중에 input 태그요소이면서 그 속성이 type=text인 것을 찾아서 'nightwatch'라는 문자열 값을 입력하는 메서드입니다. 이 메서드는 결국 구글 첫 화면의 검색어 입력창에 'nightwatch'를 입력한 효과를 보여주게 됩니다.

  7. .waitForElementVisible('button[name=btnG]', 1000) : 5번째 라인과 동일한 메서드로서, 이번엔 button 태그요소 중 name=btnG인 것이 화면에 나타날 때까지 최대 1초간 기다린다는 의미입니다.

  8. .click('button[name=btnG]') : 메서드 명인 click() 이라는 의미 그대로 해당 요소(button[name=btnG])를 클릭합니다.

  9. .pause(1000) : 1초간 기다립니다.

  10. .assert.containsText('#main', 'Night Watch') : id 속성 값이 main인 HTML DOM 요소를 찾아서 'Night Watch'라는 문자열이 포함되어 있는지 확인합니다.

  11. .end() : 지금까지 가상의 브라우저와 상호작용하는 일련의 작업들을 그만하고 끝내겠다는 의미입니다.

자바스크립트 및 node.js 문법에 익숙해져야하고, 다소 복잡할 수 있지만 익숙해지면 쉽게 작성할 수 있는 것이 Nightwatch.js UI Testcase 입니다. 웹 서비스/애플리케이션이 실제로 동작한다고 가정하고 사용자의 행동을 기술하는 것이기 때문입니다. 위의 예에서는 서비스가 잘 만들어졌고, 원하는 대로 잘 동작하고 있는지 확인하는 부분이 바로 10번 라인입니다.

3. 채점 스크립트 작성해보기 #2

나이트워치를 이용하여 정답 판정은 테스트가 실패(fail)하거나 에러(error)가 하나라도 발생하면 오답, 그렇지 않으면 정답 판정을 내립니다. 오답이 나타나는 대표적인 케이스들에 대하여 하단에 열거하겠습니다.

  1. browser.waitForElementVisible(css_셀렉터, 최대_기다리는_시간_밀리세컨_단위) : 설정한 DOM이 기다리는 시간 내에 보이지 않을 경우, 실패

  2. browser.waitForElementPresent(css_셀렉터, 최대_기다리는_시간_밀리세컨_단위) : 설정한 DOM이 기다리는 시간 내에 존재하지 않을 경우, 실패

  3. browser.waitForElementNotVisible(css_셀렉터, 최대_기다리는_시간_밀리세컨_단위) : 설정한 DOM이 기다리는 시간 내에 보이지 않은 상태가 되지 않으면, 실패.

  4. browser.waitForElementNotPresent(css_셀렉터, 최대_기다리는_시간_밀리세컨_단위) : 설정한 DOM이 기다리는 시간 내에 존재하지 않은 상태가 되지 않으면 경우, 실패

  5. browser.assert : assert 뒤에 이어지는 구문의 조건이 만족되지 않으면 실패.

나이트워치 테스트 스크립트를 작성하다 보면, DOM을 지정해야 하는 경우가 많습니다. 나이트워치 API에서 DOM을 지정하기 위해서는 CSS 셀렉터나, XML의 Xpath를 이용해야 하는데, 여기 CSS 셀렉터에 대한 레퍼런스가 있습니다.

W3C는 월드 와이드 웹 컨소시움(World Wide Web Consortium)이라는 뜻으로, 웹 표준을 개발하고 장려하는 조직입니다.

Mozilla는 최초의 그래픽 웹 브라우저인 모자이크의 대를 잇는 자유 소프트웨어 커뮤니티입니다. 자바스크립트가 최초 적용된 넷스케이프 브라우저와도 연관이 깊습니다.

W3C CSS Selector Reference Mozilla Developer Network CSS Selector Reference

좀 더 깊은 이해를 위해 실제로 테스트 스크립트로 쓰이는 예제 스크립트 코드를 하단에 첨부했습니다.

해당 문제는 로그인 폼 처리하는 문제이며, 아래 스크립트 코드가 확인하는 기능은, 로그인이 된 이후에는 로그인 폼이 보이지 않게 되는 기능입니다.

  1. 사이트 접속

  2. 페이지가 로딩되고, id값을 입력하는 input이 나타날 때 까지 기다림

  3. id값 입력하는 input에 Anonymous라고 입력함.

  4. 로그인 버튼 클릭

  5. 잠시 기다림

  6. form 태그가 보이지 않는지 확인

var site_url;
module.exports = {
  'case' : function (browser) {
    site_url = browser.globals.server_url; 
    browser
        .maximizeWindow()
        .url(site_url)
        .waitForElementVisible('body', 2000)
        .waitForElementVisible('#id', 2000)
        .setValue('#id', 'Anonymous')
        .click('#login')
        .url(site_url)
        .pause(200)
        .waitForElementNotPresent('form', 2000)
  }
};

1~5번째 라인까지는 기본적으로 들어있는 템플릿 코드입니다. browser라는 객체의 메소드를 이용해서 테스트 케이스를 진행하면 됩니다. 라인 별로 설명을 하겠습니다.

  1. var site_url; : 어떤 사이트로 접속할 지 URL을 저장하기 위한 변수의 선언부입니다.

  2. module.exports = { : node.js의 문법으로써 사용자 모듈을 만드는 과정입니다. { 이하로 할당되었기 때문에 여러 테스트 메소드를 가지는 객체가 될 것입니다.

  3. 'case' : function (browser) { : 테스트 케이스의 이름과 거기에 할당되는 테스트 메소드입니다. 이 코드에서는 'case' 이라는 이름으로 작성이 시작되었습니다.

  4. site_url = browser.globals.server_url; : 구름EDU에서 자동으로 실행되는 웹 서버의 주소는 browser.globals.server_url이라는 곳에 그 값이 미리 들어가 있습니다. 따라서 비어있는 site_url에 채점하고자 하는 대상 웹서버 주소, 즉 수강자가 작성한 코드가 실행되는 웹 서버의 주소를 넣어주는 과정입니다.

  5. browser : Nightwatch.js 에서는 가상의 웹브라우저가 객체 형태로 각각의 테스트 메소드에 전달됩니다. 이 browser는 우리가 개념적으로 알고 있는 웹브라우저로서, 눈에 보이지는 않지만 마치 웹브라우저처럼 동작하는 가상의 객체라고 이해하면 됩니다.

  6. .maximizeWindow() : maximizeWindow라는 메소드는 테스트용 브라우저의 윈도우 화면을 최대화 하라는 뜻입니다. 화면이 작아서 웹 페이지가 모바일용 형태로 보인다던지 하는 예외상황을 막아줄 수 있습니다.

  7. .url(site_url) : url이라는 메소드는 해당 url로 이동하라는 뜻입니다.

  8. .waitForElementVisible('body', 2000) : waitForElementVisible이라는 메소드는 첫번째 파라메터인 body태그가 보일 때까지 최대 2000밀리세컨(2초)동안 기다린다는 뜻입니다. 이 테스트 케이스에서 이 메소드는 해당 웹 url을 통해 접속을 하는데, 웹 페이지의 body 태그가 로딩될 때까지 최대 2초동안 기다린다는 맥락을 가지고 있습니다. 만약 2초 내에 body 태그가 보이지 않으면, 이 테스트 케이스는 실패로 끝나게 됩니다.

  9. .waitForElementVisible('#id', 2000) : 8번째 라인의 메소드와 같으며, id값이 id인 태그를 최대 2초동안 기다린다는 뜻을 가지고 있습니다. 해당 문제는 id만 입력하여 로그인을 하는 문제이며, id값이 id인 태그는 사용자의 아이디를 입력하는 Text input태그입니다.

  10. .setValue('#id', 'Anonymous') : setValue라는 메소드는 #id라는 셀렉터, 즉 id값이 id인 태그에 'Anonymous'라는 문자열 값을 입력하라고 하는 뜻을 가지고 있습니다. 만약 #id라는 셀렉터에 해당되는 DOM이 없다면 이 테스트 케이스는 에러로 끝나게 됩니다.

  11. .click('#login') : click이라는 메소드는 #login이라는 셀렉터, 즉 id값이 login태그를 클릭하라는 뜻을 가지고 있습니다. 만약 #login이라는 셀렉터에 해당되는 DOM이 없다면 이 테스트 케이스는 에러로 끝나게 됩니다.

  12. .url(site_url) : url이라는 메소드는 7번째 라인의 내용과 같습니다.

  13. .pause(200) : pause라는 메소드는 200 밀리세컨(0.2초)만큼 잠시 멈추라는 뜻을 가지고 있습니다. 웹 페이지가 랜더링 되는 시간을 기다리는 부분입니다.

  14. .waitForElementNotPresent('form', 2000) : waitForElementNotPresent라는 메소드는 form 태그가 보이지 않게 될 때 까지 최대 2000밀리세컨 (2초)까지 기다린다는 뜻입니다. 로그인 한 뒤 form 태그가 보이지 않게 되는지 확인하는 부분입니다.

위와 같은 방식으로 채점 스크립트를 작성하면 되며, 좀더 자세한 API들을 알고 싶으면 나이트워치 공식 홈페이지의 API 레퍼런스를 참조하시면 됩니다.

Nightwatchjs API Reference

Last updated