Cypress에서 Playwright로 이전하며
Cypress는 웹 애플리케이션을 엔드투엔드로 테스트하기 위한 오픈소스 도구입니다. 저는 2018년 뉴욕의 한 웹 개발 밋업에서 Gleb Bahmutov가 Cypress를 시연하는 모습을 처음 봤는데, 정말 큰 충격을 받았습니다.

2018년 개발자 밋업에서 시연되는 모습을 본 이후로 계속 Cypress를 사용해 왔습니다.
Cypress를 알기 전에는 마지못해 Selenium을 사용하고 있었습니다. Cypress는 Selenium을 쓰기 어렵게 만들던 수많은 고질적인 문제들에 우아한 해법을 제시하며 상쾌한 도약을 보여주었습니다.
최근에는 Cypress에 대한 Microsoft의 대안인 Playwright를 써 보았습니다. 하루 정도 만져본 뒤, 저는 Cypress에서 Playwright로 완전히 갈아탈 준비가 되었습니다.
이렇게 말하게 되어 마음이 아프기도 합니다. Cypress의 작고 끈질긴 팀에 대한 애정이 있기 때문입니다. Microsoft 같은 거대 기업에 대한 의존성을 추가하는 것이 마냥 반갑지는 않지만, Playwright가 워낙 뛰어나서 Cypress에 남을 이유를 찾기가 어렵습니다.
이제 머릿속에 생생할 때 Cypress에서 Playwright로 전환하며 정리한 메모를 공유하려 합니다.
Cypress와 Playwright에 대한 저의 경험
지난 4년간 제가 만든 거의 모든 웹 앱에 Cypress 엔드투엔드 테스트를 작성해 왔습니다. 스스로를 중급 Cypress 사용자 정도로 평가합니다. 제가 필요로 했던 기능은 대부분 단순했고 기본 API만으로 충분했습니다. 커스텀 플러그인을 직접 만든 적은 없지만 서드파티 플러그인은 몇 개 사용해 보았습니다.
Playwright는 단 하루 사용해 보았습니다. 직접 부딪혀 보기 위해 제 앱 중 하나의 테스트 스위트를 Cypress에서 Playwright로 포팅해 보았습니다. 제가 만든 미니멀한 파일 공유 도구인 PicoShare를 선택했는데, 엔드투엔드 테스트가 10개뿐입니다. Playwright API를 익히는 시간을 포함해 약 5시간 만에 모든 테스트를 Cypress에서 Playwright로 옮길 수 있었습니다.
저는 Cypress나 Playwright에 돈을 지불한 적이 없기 때문에 어느 쪽에도 뭔가를 요구할 자격은 없습니다. Cypress에는 유료 SaaS 기능이 있지만 제 워크플로우와 맞지 않아 구매한 적이 없습니다. 제가 사용하는 다른 오픈소스 프로젝트처럼 Cypress도 기꺼이 후원하고 싶었지만, Cypress는 후원 옵션을 제공하지 않습니다.
Playwright에서 마음에 들었던 점
Playwright는 Cypress보다 훨씬 빠릅니다
CircleCI에서 제 Playwright 테스트 스위트는 동일한 Cypress 테스트보다 34% 빠르게 실행됩니다. 로컬 개발 머신에서는 Playwright가 Cypress보다 5배 빠릅니다. 엄밀한 측정은 아니지만 두 도구 사이에 상당한 속도 차이가 있음은 분명합니다.
| 작업 | Cypress | Playwright | 차이 |
|---|---|---|---|
| CircleCI에서 테스트 실행 | 127s | 84s | -34% |
| 개발 머신에서 테스트 실행 | 40s | 7s | -83% |
CI에서의 성능 차이 중 일부는 Playwright Docker 컨테이너가 Cypress 컨테이너보다 훨씬 가볍기 때문입니다. 로컬 개발에서는 한 번만 내려받으면 되니 큰 문제가 되지 않습니다. 하지만 CI에서 Cypress를 실행할 때는 매번 CircleCI가 약 1GB에 달하는 이미지를 내려받고 압축을 풀 때까지 기다려야 합니다.
| cypress/included:10.9.0 | playwright:v1.26.0-focal-amd64 | |
|---|---|---|
| 크기 | 940 MB | 651 MB |
Playwright는 일관된 어서션 API를 제공합니다
Cypress는 아홉 개의 서드파티 라이브러리를 하나로 묶어 제공하는데, 그 결과 일관성 없는 API가 뒤섞여 있습니다. should, expect, assert가 따로 있고, 어떤 맥락에 있느냐에 따라 다른 키워드를 써야 합니다.
예를 들어 다음 두 코드 조각은 동일한 어서션을 수행합니다.
cy.get("#error-message").should("be.visible");cy.get("#error-message").should(($el) => expect($el).to.be.visible);Playwright에는 단 하나의 일관된 API가 있습니다. ID가 error-message인 요소가 화면에 보이는지 확인하려면 간단한 함수 호출 한 번이면 됩니다.
expect(page.locator("#error-message")).toBeVisible();Playwright는 GUI 환경에 의존하지 않습니다
Cypress가 가장 내세우는 기능 중 하나는 데스크톱 GUI 앱입니다.

Cypress는 테스트 실행 과정을 보여주기 위해 데스크톱 앱을 사용합니다
Cypress 데스크톱 앱을 이용하면 테스트를 “시간 여행”하듯 되돌아보며 각 단계에서 브라우저 창이 어떤 모습이었는지 확인할 수 있습니다.
하지만 GUI 없이 개발한다면 어떨까요? 저는 모든 개발을 헤드리스 서버 VM에서 합니다. 4년간 Cypress를 쓰면서 데스크톱 앱을 한 번도 사용한 적이 없습니다. 대신 Docker 컨테이너 안에서 Cypress를 실행하는데, 데스크톱 GUI에서의 작업을 전제로 만든 도구에게는 때로 장애물이 되기도 합니다.
CI 환경에서 Cypress 테스트를 실행하려고 할 때도 같은 GUI 문제가 다시 나타납니다. CI 환경에도 보통 데스크톱 GUI가 없기 때문입니다. Cypress가 내놓은 해답은 자신들의 유료 CI 서비스를 이용하라는 것이며, 이는 회사를 운영하는 주요 자금원이기도 합니다.
기업이 오픈소스 제품을 어떤 방식으로 수익화하든 저는 지지합니다. 하지만 Cypress의 CI 제품은 제게 매력적으로 다가오지 않았습니다. 저는 Docker 컨테이너로 CI 환경을 로컬에서 그대로 재현할 수 있기를 원합니다. Playwright는 그걸 가능하게 해 주지만 Cypress의 CI 서비스는 그렇지 않습니다.
CircleCI에서 Cypress를 실행하려면 Docker Compose로 약간의 꼼수를 써야 했습니다. 엄청난 부담은 아니지만, 테스트 스택을 제가 원하는 것보다 조금 더 복잡하게 만듭니다.
Playwright를 써 보니 헤드리스 실행을 염두에 두고 설계된 도구라 신선한 느낌이었습니다. Playwright는 헤드리스 환경에서 별다른 설정 없이도 바로 동작하기 때문에 CI에서 실행할 때 까다로운 작업을 할 필요가 없습니다.
Playwright에도 Cypress와 동일한 시간 여행 기능이 있지만, 데스크톱 GUI 대신 웹 UI로 구현되어 더 많은 환경에서 동작합니다.
시간 여행 기능은 정말 유용합니다! Playwright의 스냅샷은 단순한 정적 스크린샷이 아닙니다. 테스트의 각 단계에서 브라우저와 직접 상호작용할 수 있어 마치 마법 같습니다.
Playwright 웹 UI를 이용하면 앱 실행 과정의 다양한 상태로 시간 여행을 하며 페이지의 모든 요소와 상호작용할 수 있습니다.
Playwright는 기능 공백이 더 적습니다
Cypress는 기본적인 엔드투엔드 테스트를 시작하기에는 쉽지만, 앱이 커질수록 테스트 도구에서 기능 공백을 자주 마주하게 됩니다.
예를 들어 파일 업로드 기능을 추가하고 나서야 Cypress로는 파일 업로드 기능을 테스트할 수 없다는 걸 알게 되곤 했습니다. 하던 일을 멈추고 그 공백을 메울 서드파티 Cypress 플러그인을 찾아 나서야 했습니다.
이 글을 쓰는 동안 올해 초 Cypress가 파일 업로드에 대한 네이티브 지원을 추가했다는 사실을 알게 되었지만, 매우 흔한 시나리오를 지원하는 데 7년이 걸렸다는 점은 다소 의아합니다.
마찬가지로 거의 모든 웹 UI 프레임워크에 존재하는 마우스 호버를 시뮬레이션하고 싶어도 Cypress는 그걸 할 수 없습니다. 해당 버그는 거의 8년째 열려 있습니다.
Playwright에도 분명 기능 공백이 있겠지만, Cypress에서 Playwright로 테스트를 포팅한 하루 동안은 아무것도 마주치지 않았습니다. Cypress의 공백을 메우기 위해 넣었던 모든 임시방편들은 Playwright에서는 네이티브로 해결되었습니다.
Playwright는 도메인 특화 지식을 덜 요구합니다
제가 Cypress를 처음 발견했을 때 마음에 들었던 점 중 하나는 Selenium이 Java 중심이었던 반면 Cypress는 JavaScript를 위해 설계되었다는 것이었습니다.
기본적인 테스트에서는 Cypress의 의미 체계가 JavaScript를 아는 사람에게는 자연스럽고 친숙하게 느껴집니다. 하지만 정해진 길을 조금만 벗어나면 Cypress는 갑자기 JavaScript 같지 않고 독자적인 도메인 특화 프레임워크처럼 느껴집니다.
예를 들어 제 앱인 PicoShare에는 인증되지 않은 사용자와 공유하려는 파일의 URL을 생성하는 기능이 있습니다. 이 기능을 테스트하려면 PicoShare의 공유 기능을 따라가면서 URL을 생성하고, 사용자 세션에서 로그아웃한 뒤, 몇 단계 전에 생성한 URL에 브라우저가 여전히 접근할 수 있는지 확인해야 했습니다.
해당 테스트를 처음에 Cypress로 구현한 모습은 다음과 같습니다.
// Save the route to the guest link URL so that we can return to it later.
cy.get('.table td[test-data-id="guest-link-label"] a')
.invoke("attr", "href")
.then(($href) => {
// Log out.
cy.get("#navbar-log-out").click();
cy.location("pathname").should("eq", "/");
// Make sure we can still access the guest link after logging out.
cy.visit($href);
// Continue with the test
});then이 보이니 invoke가 Promise를 반환했다고 생각할 수도 있습니다. 하지만 그 promise를 await 해 보면 undefined가 반환됩니다. Cypress가 실제로 반환한 것은 Promise인 척하는 무언가이기 때문입니다.
사소해 보일 수도 있지만, 앱에서 값을 동적으로 참조해야 할 때마다 Cypress는 필요한 값 하나마다 새로운 중첩 클로저를 강제합니다. await를 지원해 달라는 기능 요청에 많은 지지가 있었지만 4년간 진전이 없었고, Cypress는 최근 현재 구현할 계획이 없다고 밝혔습니다.
동일한 테스트를 Playwright로 작성하면 다음과 같습니다.
// Save the route to the guest link URL so that we can return to it later.
const guestLinkRouteValue = await page
.locator('.table td[test-data-id="guest-link-label"] a')
.getAttribute("href");
expect(guestLinkRouteValue).not.toBeNull();
const guestLinkRoute = String(guestLinkRouteValue);
// Log out.
await page.locator("#navbar-log-out").click();
await expect(page).toHaveURL("/");
// Make sure we can still access the guest link after logging out.
await page.goto(guestLinkRoute);
// Continue with the test.Playwright에서는 DOM 요소에 대한 참조가 있으면 getAttribute 같은 일반 API를 호출해 클로저의 복잡함 없이 기대한 단순한 값을 바로 돌려받을 수 있습니다. 또 Playwright가 반환하는 promise처럼 보이는 값들은 실제로 Promise이므로 await 할 수 있어 코드가 더 깔끔합니다.
Playwright에서는 텍스트 비교가 더 쉽습니다
Cypress에서 늘 답답했던 점 중 하나는 요소가 특정 텍스트 값을 포함하고 있는지를 단언하기가 매우 어렵다는 것입니다.
PicoShare에 있는 <p> 요소 예시는 다음과 같습니다.
<p data-test-id="github-instructions">
Visit our
<a href="https://github.com/mtlynch/picoshare">GitHub repo</a> to create your
own PicoShare server.
</p>Cypress에서 예상치 못한 텍스트 비교 결과
Cypress에서 텍스트 값을 단언하는 순진한 접근 방식은 다음과 같습니다.
cy.get("[data-test-id='github-instructions']").should(
"have.text",
"Visit our GitHub repo to create your own PicoShare server.",
);안타깝게도 이 테스트는 실패합니다.
Timed out retrying after 10000ms
+ expected - actual
-'
Visit our
GitHub repo to create
your own PicoShare server.
'
+'Visit our GitHub repo to create your own PicoShare server.'Cypress는 textContent 속성을 가져오는데, 여기에는 브라우저에 표시되는 모습이 아니라 원시 HTML에 나타나는 그대로의 공백이 모두 포함됩니다.
요소의 innerText를 가져오면 우회할 수 있지만, 전혀 다른 어서션 API를 사용해야 하므로 문법이 복잡하고 기억하기 어렵습니다.
cy.get("[data-test-id='github-instructions']").should(($el) => {
expect($el.get(0).innerText).to.eq(
"Visit our GitHub repo to create your own PicoShare server.",
);
});Playwright에서는 당연한 대로 동작하는 텍스트 비교
Playwright에서는 순진한 어서션이 기대한 대로 동작합니다.
await expect(page.locator("data-test-id=github-instructions")).toHaveText(
"Visit our GitHub repo to create your own PicoShare server.",
);Playwright도 요소의 textContent를 보지만, 브라우저처럼 공백을 자동으로 다듬고 축소합니다.
Cypress에서보다 훨씬 간단한 문법으로 Playwright가 대신 innerText를 보도록 강제할 수도 있습니다.
await expect(page.locator("data-test-id=github-instructions")).toHaveText(
"Visit our GitHub repo to create your own PicoShare server.",
{ useInnerText: true },
);Playwright는 이름이 비슷하고 겉보기에 동일해 보이는 API가 두 개 있다는 점에서 약간 아쉽습니다.
toHaveText: “Locator가 주어진 텍스트를 가진 요소를 가리키는지 확인합니다. 값으로 정규식도 사용할 수 있습니다.”toContainText: “Locator가 주어진 텍스트를 포함하는 요소를 가리키는지 확인합니다. 값으로 정규식도 사용할 수 있습니다.”
한 API는 요소가 “주어진 텍스트를 가진” 경우를 단언하고, 다른 API는 요소가 “주어진 텍스트를 포함하는” 경우를 단언합니다. 텍스트를 “가진다”와 “포함한다”의 차이가 무엇일까요?
문서를 더 읽어 보니 차이는 요소의 자식 요소에 대해 무엇을 기대하는지에 대한 미묘한 차이로 귀결되는 듯하지만, 문서가 확실히 개선될 필요가 있습니다.
Playwright는 섀도 DOM 탐색을 더 쉽게 만듭니다
저는 HTML 커스텀 엘리먼트를 이용해 웹 앱을 많이 만들기 때문에 코드에 중첩된 섀도 DOM이 자주 등장합니다.
Cypress에서는 섀도 DOM 안의 페이지 요소를 지정하는 것이 다소 어색합니다. 섀도 DOM 경계를 만날 때마다 CSS 선택자를 끊어야 하기 때문입니다.
cy.get("#upload-result upload-links")
.shadow()
.find("#verbose-link-box")
.shadow()
.find("#link")
.should("be.visible");Playwright는 기본적으로 섀도 DOM을 관통하므로 간결한 CSS 선택자를 사용할 수 있습니다.
await expect(
page.locator("#upload-result upload-links #verbose-link-box #link"),
).toBeVisible();업데이트(2022-10-26): 레딧 사용자 /u/Daffodils2가 알려 준 바에 따르면 Cypress에도 Playwright처럼 섀도 DOM을 관통해 요소를 선택하도록 만드는 includeShadowDom 옵션이 있습니다.
Playwright는 앱을 대신 실행해 줍니다
Cypress의 특이한 설계 결정 중 하나는 앱을 대신 실행해 주지 않는다는 것입니다. 앱을 직접 실행하는 방법을 알아낸 뒤, 앱이 서빙을 시작한 후에 Cypress 테스트가 시작되도록 직접 조율해야 합니다.
Playwright는 이런 조율의 골칫거리를 없애고 앱을 실행하기 위한 간단한 설정 옵션을 제공합니다. PicoShare에서의 모습은 다음과 같습니다.
webServer: {
command: "PS_SHARED_SECRET=dummypass PORT=6001 ./bin/picoshare",
port: 6001,
},Playwright의 로그는 실제로 동작합니다
Cypress의 큰 고충 중 하나는 터미널로 디버그 로그를 남기지 않고 사는 법을 배워야 한다는 것입니다. Cypress에는 stdout이나 stderr로 출력하는 공식적인 방법이 없습니다.
console.log 호출을 넣어도 아무 일도 일어나지 않습니다.
console.log("hello from Cypress"); // this does nothingCypress에는 자체 cy.log API가 있으니, 그걸 대신 써 보면 어떨까요?
cy.log("hello from Cypress"); // this prints nothing to the terminal안 됩니다. 그것도 Cypress 데스크톱 GUI나 Cypress의 독점 SaaS 대시보드 안에서만 출력됩니다.
Cypress 개발자인 Zach Bloomquist가 브라우저 콘솔 출력을 터미널에 찍기 위한 비공식 플러그인을 공개했지만, 어디까지나 서드파티 플러그인이며 Cypress가 공식 지원하는 기능은 아닙니다.
Playwright에서는 console.log가 그냥 동작합니다. 번거로울 것도, 복잡할 것도 없습니다.
console.log("hello from Playwright");테스트를 실행하면 터미널 출력에서 로그 메시지를 확인할 수 있습니다.
[chromium] › auth.spec.ts:3:1 › logs in and logs out
hello from PlaywrightPlaywright 팀은 자원 부족을 느끼게 하지 않습니다
Cypress 핵심 저장소에는 2,782개의 열린 버그가 있으며, 그중 일부는 수년간 방치된 중요한 기능 요청입니다. 때로는 플러그인으로 공백을 메우기도 하지만, Cypress 코어가 현대 웹 개발 속도를 따라갈 자원이 부족하다는 느낌을 자주 받습니다.
1년 전에 Cypress에 논란의 여지가 없는 PR을 보냈지만 아직까지 아무런 응답도 받지 못했습니다. 외부 풀 리퀘스트를 검토할 자원조차 없는 것이 아닌가 싶습니다.
반면 Playwright는 비슷한 양의 버그 리포트를 받으면서도 열린 버그가 603개에 불과합니다. 제가 Playwright에 버그를 제보했을 때는 하루도 안 되어 분류가 이루어지고 의미 있는 답변을 받을 수 있었습니다.
Playwright는 VS Code와 더 잘 통합됩니다
Playwright는 문맥을 인식하는 자동 완성을 제공하는 공식 VS Code 플러그인을 제공합니다. Playwright에서 보기 전까지는 Cypress에서 이런 기능이 없다는 사실조차 깨닫지 못하고 있었습니다.

Playwright의 VS Code 플러그인은 문맥 인식 자동 완성을 제공합니다.
Cypress에는 함수가 몇 개 없고, 특별한 문자열 값을 넘겨 다양한 기능을 실행합니다. IDE가 그런 의미 체계를 돕기는 어렵습니다. 반면 Playwright는 명시적인 TypeScript 함수 목록을 제공하므로 IDE가 도움을 주기가 더 쉽습니다. Cypress용 서드파티 VS Code 플러그인은 있지만 Cypress 팀이 공식 지원하는 것은 없습니다.
Playwright에서는 병렬 테스트가 무료입니다
이론적으로는 Cypress에서도 병렬 테스트를 무료로 실행할 수 있지만, 일부러 불편하게 만들어 두었습니다. 병렬 테스트가 Cypress 유료 SaaS 도구의 대표 기능 중 하나이니 무료 버전을 더 유용하게 만들면 손해를 보는 셈이라 비난할 수는 없습니다.
Microsoft는 Cypress보다 주머니 사정이 훨씬 두둑하므로 Playwright의 모든 기능을 무료로 제공할 여유가 있습니다. 그래서 Playwright는 병렬 테스트를 기본으로 지원합니다.
Cypress가 그리운 점
Cypress의 문법은 더 일관되게 유창합니다
Cypress와 Playwright 모두 플루언트 스타일 API를 제공하는데, 일련의 동작을 하나의 문장으로 이어 붙이는 방식입니다.
Cypress는 플루언트 스타일을 더 엄격하게 따르므로 개발자가 테스트 로직을 왼쪽에서 오른쪽으로 읽어 나갈 수 있습니다.
cy.get(".navbar-item [data-test-id='log-in']").should("be.visible");Cypress에서는 코드를 작성하는 순서가 테스트를 생각하는 순서와 일치합니다. 먼저 요소에 대한 참조를 가져온 뒤, 어떤 단언을 할지 생각합니다.
Playwright에서는 순서가 약간 뒤섞입니다. 테스트하려는 요소를 찾기 시작하기도 전에 코드를 expect 호출로 감싸야 합니다.
await expect(
page.locator(".navbar-item [data-test-id='log-in']"),
).toBeVisible();Playwright의 문법은 Cypress에서 익숙했던 왼쪽에서 오른쪽으로의 흐름을 끊습니다. Playwright 문법이 다음과 같았으면 좋겠다고 생각합니다.
// INVALID - not how Playwright actually behaves
await page
.locator(".navbar-item [data-test-id='log-in']")
.expect()
.toBeVisible();Cypress에는 작고 독립적인 팀이 있습니다
저는 오픈소스 기업으로서 Cypress, 특히 엔지니어링 부사장인 Gleb Bahmutov를 개인적으로 높이 평가합니다. Gleb은 수준 높은 블로그 글을 쓰고 훌륭한 컨퍼런스 발표자이기도 합니다.
제가 Cypress에 관한 블로그 글을 썼을 때 Gleb은 글을 개선할 수 있도록 친절하게 피드백을 주었습니다. 글을 발행한 뒤에는 Cypress가 자사 블로그에서 제 글을 소개해 주기도 했습니다.
반면 Microsoft는 역사적으로 오픈소스에 적대적이었습니다. 지금은 우호적인 시기를 보내고 있지만, 바람의 방향이 바뀌어 오픈소스를 짓밟는 편이 더 돈을 번다고 판단하면 아마 그렇게 할 것입니다.
이게 영화라면 Cypress는 응원하지 않을 수 없는 끈질긴 약자이고, Microsoft는 3막에서 주인공을 배신할지도 모르는 갱생한 악당일 것입니다.
Cypress 테스트 산출물은 CI에서 잘 동작합니다
Cypress 테스트가 실패하면 실패 시점의 앱 화면을 스크린샷으로 찍어 디스크에 저장합니다. CI 플랫폼에서 이 이미지를 테스트 산출물로 보관하도록 설정하면 디버깅이 쉬워집니다. 마찬가지로 Cypress는 각 테스트의 영상을 저장해 CI 테스트 산출물로 게시할 수도 있습니다.

Cypress는 CI 산출물로 쉽게 확인할 수 있는 테스트 산출물을 생성합니다
Playwright는 더 복잡한 형태의 테스트 산출물을 생성합니다. 단순한 이미지와 영상 대신, 모든 테스트 산출물을 보기 위한 정적 웹 앱을 생성합니다.
안타깝게도 Playwright의 리포트 뷰어는 CircleCI에서 동작하지 않아, CircleCI 대시보드에서 바로 확인하는 대신 에셋을 내려받아 로컬에서 Playwright 서버를 실행해야 합니다.
Cypress Docker 이미지는 실제로 소프트웨어를 포함하고 있습니다
엔드투엔드 테스트 도구에서만 본 독특한 패턴인데, Cypress와 Playwright의 공식 Docker 이미지에는 정작 도구 자체가 들어 있지 않습니다. 즉, Cypress Docker 이미지에는 Cypress가 없고, Playwright Docker 이미지에는 Playwright가 없습니다.
대신 Docker 이미지에는 각각 Cypress나 Playwright를 설치하는 데 필요한 의존성만 들어 있습니다. 그래서 Playwright Docker 이미지를 실행하면서도 환경 설정 과정의 일부로 Playwright를 별도로 설치해야 합니다.
분명 타당한 이유가 있겠지만 저는 이해한 적이 없습니다. 제가 Cypress 팀에 이 문제를 제기했을 때, 그들은 Cypress 도구 자체를 포함하는 특별한 cypress/included 이미지를 추가해 주었습니다. Playwright에는 그에 상응하는 Docker 이미지가 없는 것으로 보입니다.
정리
비록 Playwright를 몇 시간밖에 써 보지 않았지만, Cypress보다 훨씬 나은 경험이라는 걸 알 수 있었습니다. 더 명확한 API, 더 단순한 테스트 설정, 그리고 속도 덕분에 Playwright에서는 Cypress 때보다 생산성이 50~100%는 더 높아진 것 같습니다.
앞으로는 모든 신규 앱을 Playwright로 테스트할 생각입니다. 테스트 실행 시간이 5분을 넘어선 앱들의 경우 기존 Cypress 테스트 일부도 Playwright로 옮길 가능성이 높습니다.
Cypress 사용자라면 Playwright를 꼭 한 번 살펴보시길 강력히 권합니다. 제게 Cypress에서 Playwright로의 도약은 Selenium에서 Cypress로의 도약만큼이나 큽니다.
글을 무작위로 읽기