https://crossbrowsertesting.com/blog/test-automation/selenium-vs-cypress/

Selenium에서 Cypress로 갈아탄 후기

Selenium과 Cypress의 차이점

김지환
김지환
Jan 13 · 10 min read

Selenium과 Cypress는 둘 다 기능적(functional) 자동화 테스트 도구이다. 둘 다 WebDriver를 제어하여 사용자의 행동을 모방하는 테스트를 작성할 수 있게 하고, 그 테스트의 결과를 확인할 수 있게 해준다.

최근에 HBsmith에서 활동하면서 E2E Test를 작성하며 Cypress를 사용하였는데, Selenium과 Cypress가 어떻게 다른지 느낀점, 기능적인 측면에서 내 생각을 서술해 보려 한다.

  • E2E Test란? : Changhoon Hyun님 게시물 참고

Cypress : JavaScript Only/Selenium : Python, Java, C#…etc

Cypress는 자바스크립트를, Selenium은 여러 언어를 사용한다. 굳이 사용하는 언어에 차이점을 두어야 하나? 작은 차이 아닌가? 싶기도 하지만 테스트를 작성하는 대상에 차이를 둔 것으로 볼 수도 있다.

https://www.tutorialrepublic.com/javascript-tutorial/

프런트엔드 개발 중 사용하는 언어는 Javascript 하나이다. Javascript는 브라우저에서 지원하는 유일한 언어이기 때문에 다른 언어를 사용하는 일은 매우 드물다. 따라서 Cypress가 Javascript만을 사용할 수 있다는 것은 테스트를 작성하는 주체에 프런트 엔드 개발자를 매우 큰 비중으로 삼았다고 할 수 있다. 또한 mocha기반이기 때문에 nodejs 개발자들에게도 익숙하다.

https://www.nascenia.com/necessary-factors-to-make-agile-software-development-a-success/

이러한 “프런트엔드 개발자들이 자신의 코드를 테스트 해볼 것이다” 라는 발상은 애자일 소프트웨어 방법론 에서 비롯되었다. 애자일 소프트웨어 방법론에서 프런트 엔드 개발자들은 자신의 코드를 직접 시험해보지 않으면 ‘애자일’한 개발을 할 수 없기 때문에 QA 개발자들이 작성하는 자동화 테스트와 같은 테스트 프레임워크를 이용해 실제 브라우저에서 E2E 테스트를 작성하게 되었다.

결론은 Cypress가 프런트엔드 개발자를 대상으로 한다는것과 Selenium은 QA개발자를 대상으로 한다는 것이 핵심이었다고 할 수 있다.

실제 개발에 사용해본 후기

1. 제한 사항

  • Cypress에서는 Chrome과 Electron만 지원한다.
  • Cypress는 Multi-Tab을 지원하지 않으며 향후 지원 예정도 없다.

여러가지 WebDriver를 지원하는 Selenium과는 다르게 Cypress는 Chrome를 중점적으로 지원하고 있다. 이런 이유에는 시간이 지남에 따라 ‘크로스 브라우징 이슈’가 완화되고 있으며 갈수록 브라우저간의 랜더링 결과의 차이가 줄어들고 있기 때문으로 보인다.

Multi-Tab을 지원하지 않는 것은 개인적으로 아쉬운 부분인데, 테스트 대상이 새로운 탭으로 redirecting 하는 경우에는 테스트를 진행할 수 없다. 해당 태그의 href 속성을 가져와 이동하는 방법도 있지만, 다른 방식으로 처리된 경우에는 새로운 탭에서의 테스트를 수행할 수 없었다.

2. element 선택 방법의 차이

  • Cypress에서는 XPath를 지원하지 않는다.
  • Contains()를 사용할 수 있다.

개인적으로 Selenium을 사용할 때 XPath를 사용하는 것을 선호하였는데, Cypress 에서는 사용할 수 없었다. 대신 Cypress에서 Element를 선택할 때에는 cy.get(selector) 을 사용하는데, CSS Selector와 태그+속성값으로 선택할 수 있게 해준다.

Selenium에 비해 Cypress에서 압도적으로 편리한 점은 Contains를 사용하여 브라우저 안에서 눈에 보이는 Text 값으로 Element를 선택할 수 있게 한다는 점이다. Contains 덕에 테스트를 좀 더 ‘사용자의 입장에서’ 작성할 수 있도록 도와준다.

3. 개발자 친화적인 환경

Sample code — from google to gmail

Cypress 는 위 스크린샷 처럼 테스트가 구동될 때의 명령이 좌측에 표시된다. 또한 테스트가 끝난 후 각 명령을 클릭하면 해당 명령이 구동될 때의 화면을 우측에 표시해준다.

이 기능은 테스트 실패시 굉장히 유용하게 사용하였다. 스크린샷을 통해 해당 테스트가 어떻게 실패 하였는지 이해할 때 중요한 자료로 사용되며 테스트가 어떻게 진행되는지를 천천히 분석할 수 있게 해주는 IDE와 비슷한 역할을 해준다.

4. 진행되는 프로세스의 차이

Selenium은 다음과 같은 동작 프로세스를 거친다.

  1. BrowserDriver 생성 후 선택한 Local Server에서 Browser를 동작시킨다.
  2. BrowserDriver에게 보낼 명령을 JSON Wire Protocol 기반의 URL로 Local Server에 올라간 BrowserDriver로 전달한다.
  3. BrowserDriver는 명령을 전달받은 후 Selenium Script를 사용하여 실제 Browser를 동작시킨다.
  4. 동작한 결과를 Selenium Client Library에게 전달한다.

위에서 전달받은 결과(랜더링 페이지, Response 등)은 Code Level에서 사용이 가능하다.

Cypress에서는 간단한 구조로 실행된다.

  1. Cypress가 모든 모듈, 코드를 WebPack으로 하나의 js 파일로 번들링한다.
  2. Chrome을 실행하고 빈 페이지에 코드를 삽입한다.
  3. iframe 내부에서 타켓 페이지로 이동하여 브라우저 내부에서 명령을 직접 실행한다.

Selenium보다는 훨씬 간결하게 실행되는 것을 알 수 있다.

//Google to gmail test code
describe('google -> Gamil introducing', function () {
it('should move to gmail url', function () {
cy.visit('https://www.google.com')
cy.contains('Gmail').click()
cy.url().should('eq', 'https://www.google.com/intl/ko/gmail/about/#')
})
})

그러나 Selenium과 크게 다른 점은 it 함수 안의 명령이 실시간으로 실행되는 것이 아니라는 점이다. 자세하게 말하자면, Cypress가 click, visit를 호출할 때에는 진짜로 실행되는 것이 아니라 이러한 명령들이 “완료되어야 한다” 고 기록되며 이후에 it 함수가 실행될 때에는 실행되지 않는다. 이렇게 기록된 테스트들은 it 함수가 끝난 이후에 기록에 따라 단계별로 실행된다.

내가 생각하는 가장 큰 차이는 위의 ‘기록' 이라는 메커니즘이다. 위와 같이 동작하면 어떤 차이를 불러올까?

//Sample code
describe('cart count test', function () {
it('should add 3 items and then click buy', function () {
cy.visit(target)
cy.contains('item add').click()
const cart_count = cy.contains('cart_count')
if(cart_count.innerText == '3 개 있습니다.'){
cy.contains('buy').click()
}
})
})

위와 같은 코드는 ‘기록’ 이라는 메커니즘으로 인해 동작하지 않았다. 테스트를 실행할 때는 기록이 될 뿐이라 반환된 텍스트를 확인하는 것은 소용 없는 일이다. 위와 같은 분기를 사용하고 싶으면 .then을 사용해야 한다.

//Sample code
describe('cart count test', function () {
it('should add 3 items and then click buy', function () {
cy.visit(target)
cy.contains('item add').click()
cy.contains('cart_count')
.then(cart_count ->{
if(cart_count.innerText == '3 개 있습니다.'){
cy.contains('buy').click()
}
}
})
})

위와 같이 작성하면 cypress가 실행될 때 .then 안에 실행해야 할 분기가 같이 ‘기록’되어 실제로 동작 시에 같이 실행되었다.

결론

지금까지 Selenium에서 Cypress로 넘어와 개발에 사용해 보았을 때에 느낀 점, 차이점을 서술해 보았다. Selenium과 Cypress는 서로 유사한 점이 많았지만 전혀 다른 목표를 가진 프레임워크라고 생각한다.

Selenium은 다양한 언어를 지원하는 크로스 브라우저 테스트 프레임 워크이고, Cypress 는 단 하나의 언어에 단 하나의 브라우저를 지원하는 프레임 워크로 빠르고 간단하게 코드를 작성하고 테스트할 수 있도록 도와준다.

이러한 차이점은 위에도 서술하였듯이, ‘QA 개발자를 위한 것이냐’, ‘애자일 방법론을 사용하는 프런트엔트 개발자를 위한 것이냐’ 의 차이인 것으로 추정된다.

결국 다양한 브라우저에서의 랜더링, 브라우저 별 차이를 위해 정확하고 섬세한 테스트를 위해 긴 시간을 투자할 수 있다면 Selenium을 사용할 수 있을 것이고, 프런트 엔드 개발자 본인이 자신이 작성한 코드를 빠르고 간편하게 테스트해보고 싶은 생각이 있다면 Cypress를 한번 사용해 보는 것이 나쁜 경험이 되지는 않을 것이다.


저희 HBSmith는 여러 기업들에 QA 자동화 서비스를 제공하고 있습니다. 아래 사이트에서 자세한 정보를 확인하세요 :)

HardBoiledSmith Stories

DevOps & QA 자동화 전문 스타트업 HBSmith의 Blog - https://hbsmith.io

    김지환

    Written by

    김지환

    HardBoiledSmith Stories

    DevOps & QA 자동화 전문 스타트업 HBSmith의 Blog - https://hbsmith.io

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade