Skip to content

Commit 198b41b

Browse files
committed
feat: add Playwright Java E2E guide with Gradle and MCP integration
1 parent 4ca79d8 commit 198b41b

File tree

11 files changed

+340
-0
lines changed

11 files changed

+340
-0
lines changed
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
---
2+
title: "E2E(End to End) 테스트 프레임 워크인, Playwright 로 놀아보자! (feat. playwright mcp + claude desktop)"
3+
date: "2025-08-02"
4+
tags: ["Testing", "Java"]
5+
summary: "Have fun automating the browser with Playwright for Java"
6+
description: "Playwright 를 기반으로 Java 에서 브라우저 자동화 테스트를 즐겨보자."
7+
---
8+
9+
:::info
10+
웹 테스트 자동화의 필요성을 느끼며 다양한 오픈소스 라이브러리를 찾아보게 되었는데,
11+
속도, 브라우저 지원, 개발자 친화성 면에서 눈에 띄는 도구가 하나 있었다. 바로 Playwright 다.
12+
Playwright 가 어떤 도구인지 간단히 살펴보고, 더 나아가서 MCP 와 연동하여 테스트를 자동화하는 방법까지 함께 알아보자.
13+
:::
14+
15+
---
16+
17+
<figure style={{ textAlign: 'center' }}>
18+
<img
19+
src="/img/post/testing/playwright/playwright-logo.png"
20+
alt="Playwright Logo"
21+
style={{ display: 'inline-block'}}
22+
/>
23+
<figcaption style={{ fontSize: '0.9em', color: '#666', marginTop: '0.5rem' }}>
24+
출처: <a href="https://brandfetch.com/playwright.dev" target="_blank" rel="noopener noreferrer">brandfetch</a>
25+
</figcaption>
26+
</figure>
27+
28+
---
29+
30+
## Q. Playwright 는 무엇인가요?
31+
32+
<BlueText><span style={{ fontSize: '1.5rem', }}>A. </span></BlueText>
33+
[Playwright](https://playwright.dev/java/) 는 Microsoft 에서 만든 오픈소스 E2E (End-to-End) 테스트 프레임워크이다.
34+
35+
여러 브라우저를 한 API 로 자동화할 수 있으며, 여러가지 특징을 가지고 있다.
36+
37+
* Chromium, Firefox, WebKit 지원
38+
* Headless / Headful 모드 실행
39+
* 여러 탭 및 컨텍스트 제어
40+
* 네트워크 제어, 스크린 샷, 비디오 녹화 등 지원
41+
42+
43+
---
44+
45+
## 다른 도구들과의 비교 (vs Selenium, Cypress)
46+
47+
`Playwright` 는 최신 브라우저 자동화 프레임워크로, 자동 대기, 빠른 실행 속도, 다양한 브라우저 지원 등에서 다른 도구들에 비해서 개발자 친화적인 경험을 제공한다.
48+
49+
|구분|Playwright|Selenium|Cypress|
50+
|--|--|--|--|
51+
|지원 브라우저|Chrome, Firefox, WebKit|대부분 지원 되지만 WebDriver 필요|Chromium 계열만 지원|
52+
|실행 속도|빠름 (자동 대기 + 병렬 실행 지원)|느림 (명시적 대기 필요) | 빠름|
53+
|모바일 애뮬레이션|Device Profile 내장|Driver 별도 구성 필요|Chrome 기반으로 일부만 지원|
54+
|자동 대기|기본 내장(`click()`, `fill()` 등 자동 대기)|`WebDriverWait` 등 명시적 대기 필요|일부 기본 내장|
55+
|설치 / 구성|단일 바이너리 설치로 매우 간단|브라우저마다 WebDriver 따로 필요|Node 기반으로 간단|
56+
57+
`Playwright` 는 actionability check(실제로 동작 가능한 상태인지 확인 검사)를 수행해서, 사용자 액션 등을 시뮬레이션 할 때,
58+
<BlueText>자동 대기 기능</BlueText>을 기본적으로 제공한다.
59+
60+
`Playwright` 는 요소가 DOM 에 로드되고, 표시되어 활성화 된 상태까지 자동으로 기다린 다음에 액션을 수행하게 된다.
61+
62+
그렇기 때문에 테스트 코드가 더 간결해지고, 실수할 여지가 줄어들며 테스트 실행 속도가 향상된다.
63+
64+
반면에, `Selenium` 은 개발자가 `WebDriverWait` 등으로 명시적으로 조건을 설정해야 하므로,
65+
66+
코드가 복잡해지고, 속도가 느려지는 문제가 발생하게 된다.
67+
68+
<br/>
69+
70+
아래 예시에서 `Playwright` 의 코드가 `Selenium` 보다 간결하다는 것을 알 수 있다.
71+
72+
```java
73+
// playwright
74+
page.click("button#submit"); // 요소가 로드되고 활성화될 때까지 자동으로 기다린다.
75+
76+
// Selenium
77+
// 최대 10초 동안 기다릴 수 있는 WebDriverWait 객체 생성
78+
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
79+
// id 가 submit 인 버튼이 클릭 가능할 때 까지 대기 (요소가 DOM 에 존재하고, 활성화되어 있는 상태)
80+
WebElement submitBtn = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
81+
submitBtn.click();
82+
```
83+
84+
<br/>
85+
86+
:::note
87+
<a href="https://playwright.dev/docs/actionability">playwright - actionability</a>
88+
:::
89+
90+
91+
---
92+
93+
## Playwright 를 직접 써보자!
94+
95+
`Playwright` 의 자동 대기, 다중 브라우저 지원 등은 직접 코드를 실행시켜보면 확실하게 느낄 수 있다.
96+
97+
다행스럽게도, `Playwright` 는 실제 브라우저에서 수행한 액션을 기반으로 테스트 코드를 자동 생성해주는 `codegen` 기능을 제공한다.
98+
99+
공식 문서에서는 다음과 같이 Maven 을 기준으로 안내하고 있다.
100+
101+
```shell
102+
mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="codegen https://the-internet.herokuapp.com/login"
103+
```
104+
105+
<br/>
106+
107+
:::note
108+
<a href="https://playwright.dev/java/docs/codegen">playwright - Test generator</a>
109+
:::
110+
111+
---
112+
113+
## Playwright Java - Gradle 로 codegen 실행해보자!
114+
115+
이번에는 Gradle(Groovy DSL)을 사용하여 `codegen` 기능을 실행해보겠다.
116+
117+
### 1) 의존성 추가
118+
119+
먼저, `build.gralde` 에 Playwright Java 의존성을 추가한다.
120+
121+
```groovy
122+
dependencies {
123+
// ...
124+
implementation 'com.microsoft.playwright:playwright:1.54.0'
125+
// ...
126+
}
127+
```
128+
129+
### 2) 브라우저 설치 Task
130+
131+
playwright 는 실제 브라우저 바이너리가 있어야 동작하게 되는데,
132+
gradle 에서 `installBrowsers` Task 를 정의하면 CLI 로 브라우저를 설치할 수 있다.
133+
134+
```groovy
135+
// playwright - install Browsers
136+
tasks.register("installBrowsers", JavaExec) {
137+
group = "playwright"
138+
description = "Installs Playwright browsers"
139+
classpath = sourceSets.main.runtimeClasspath
140+
mainClass.set("com.microsoft.playwright.CLI")
141+
args("install")
142+
}
143+
```
144+
145+
`installBrowsers` Task 를 실행시키면 아래와 같이 브라우저가 설치가 된다.
146+
147+
<div style={{ textAlign: 'center' }}>
148+
<img src="/img/post/testing/playwright/install-task.png" alt="gradle-playwright-install-task" style={{ display: 'inline-block' }} />
149+
</div>
150+
151+
### 3) Codegen Task
152+
153+
브라우저 설치가 완료되면, 이제 실제 `codegen` Task 를 통해 브라우저 액션을 기록하고 코드로 변환할 수 있다.
154+
155+
```groovy
156+
// playwright - codegen
157+
tasks.register("codegen", JavaExec) {
158+
group = "playwright"
159+
description = "Launches playwright codegen"
160+
classpath = sourceSets.main.runtimeClasspath
161+
mainClass.set("com.microsoft.playwright.CLI")
162+
args("codegen", "https://the-internet.herokuapp.com/login") // args 에는 실행시킬 URL 도 정의해준다.
163+
}
164+
```
165+
166+
`codegen` Task 를 실행시키면 `Playwright Inspector` 창이 뜨고, `args` 에 추가한 URL 이 Chromium 브라우저로 실행이 된다.
167+
168+
상단 메뉴에서 `Record` 를 클릭하게 되면 Chromium 브라우저의 액션이 코드상으로 기록된다.
169+
170+
<div style={{ textAlign: 'center' }}>
171+
<img src="/img/post/testing/playwright/codegen-task.png" alt="gradle-playwright-codegen-task" style={{ display: 'inline-block' }} />
172+
</div>
173+
174+
`Playwright Inspector` 에서 Target 을 클릭하게 되면, `Node.js`, `Python`, `.NET C#`, `Java` 등으로 코드가 기록되고,
175+
176+
여기서는 `Java` - `Junit` 기반으로 기록을 해보았다.
177+
178+
<div style={{ textAlign: 'center' }}>
179+
<img src="/img/post/testing/playwright/codegen-task-1.png" alt="gradle-playwright-codegen-task-1" style={{ display: 'inline-block' }} />
180+
</div>
181+
182+
테스트 자동화 연습용으로 널리 쓰이는 샘플 웹페이지인 `https://the-internet.herokuapp.com/login` 에서 간단하게 로그인하는 것을 기록하면,
183+
184+
사용자의 액션이 코드로 기록되는 것을 볼 수 있고, 다시 `Playwright Inspector` 상단 메뉴에서 `Record` 를 누르면 기록이 종료가 되고 복사가 가능한 상태가 된다.
185+
186+
<div style={{ textAlign: 'center' }}>
187+
<img src="/img/post/testing/playwright/codegen-task-finish.png" alt="gradle-playwright-codegen-task-finish" style={{ display: 'inline-block' }} />
188+
</div>
189+
190+
Chromium 브라우저 상에도 상단 UI 가 생성되는데, 메뉴를 적절히 선택해서 사용할 수 있다.
191+
192+
테스트 코드 기반으로 작성할 경우 검증하는 부분을 추가하면 된다.
193+
194+
<div style={{ textAlign: 'center' }}>
195+
<img src="/img/post/testing/playwright/codegen-task-assert.png" alt="gradle-playwright-codegen-task-assert" style={{ display: 'inline-block' }} />
196+
</div>
197+
198+
상단 UI 에 대한 설명은 공식 페이지에서 확인 가능하다.
199+
200+
:::note
201+
<a href="https://playwright.dev/java/docs/codegen-intro#inspecting-locators">playwright - Generating tests #inspecting-locators</a>
202+
:::
203+
204+
<br/>
205+
206+
최종 생성 된 코드는 아래와 같은데,
207+
208+
`@UserPlaywright` annotation 이 있으면 default 로 headless 상태로 실행되며, `Playwright` 인스턴스를 자동 생성해주고 (Playwright, Browser, BrowserContext, Page 등)
209+
테스트 종료 후 `browser.close()` 등을 자동으로 수행해주는 annotation 이다.
210+
211+
```java
212+
import com.microsoft.playwright.Page;
213+
import com.microsoft.playwright.junit.UsePlaywright;
214+
import com.microsoft.playwright.options.AriaRole;
215+
import org.junit.jupiter.api.Test;
216+
217+
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
218+
219+
@UsePlaywright
220+
class TestExample {
221+
222+
@Test
223+
void test(Page page) {
224+
page.navigate("https://the-internet.herokuapp.com/login");
225+
page.getByRole(AriaRole.TEXTBOX, new Page.GetByRoleOptions().setName("Username")).click();
226+
page.getByRole(AriaRole.TEXTBOX, new Page.GetByRoleOptions().setName("Username")).fill("tomsmith");
227+
page.getByRole(AriaRole.TEXTBOX, new Page.GetByRoleOptions().setName("Username")).press("Tab");
228+
page.getByRole(AriaRole.TEXTBOX, new Page.GetByRoleOptions().setName("Password")).fill("SuperSecretPassword!");
229+
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(" Login")).click();
230+
assertThat(page.getByText("You logged into a secure area")).isVisible();
231+
}
232+
}
233+
```
234+
235+
headless 가 아닌 모드로 실행을 시키려면, `-Dplaywright.launch.headless=false` 이런식으로 옵션을 주고 실행시키거나,
236+
237+
`Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));` 와 함께,
238+
239+
`@UsePlaywright` 어노테이션이 하는 것을 직접 구현 하면 된다.
240+
241+
`Playwright``AutoCloseable` 을 구현하고 있어서 `try-with-resources` 구문으로 처리가 된다.
242+
243+
```java
244+
class PlaywrightTests {
245+
246+
@Test
247+
void test() {
248+
try (Playwright playwright = Playwright.create()) {
249+
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
250+
BrowserContext context = browser.newContext();
251+
Page page = context.newPage();
252+
253+
page.navigate("https://the-internet.herokuapp.com/login");
254+
255+
page.getByRole(AriaRole.TEXTBOX, new Page.GetByRoleOptions().setName("Username")).fill("tomsmith");
256+
page.getByRole(AriaRole.TEXTBOX, new Page.GetByRoleOptions().setName("Password"))
257+
.fill("SuperSecretPassword!");
258+
page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(" Login")).click();
259+
260+
assertThat(page.getByText("You logged into a secure area")).isVisible();
261+
}
262+
}
263+
}
264+
```
265+
266+
:::tip
267+
<a href="https://github.com/eottabom/let-me-code/tree/main/src/test/java/com/eottabom/letmecode/example/_02_playwright">playwright - 예시 보러 가기</a>
268+
:::
269+
270+
271+
---
272+
273+
## Claude Desktop + MCP 연동해보기
274+
275+
`Playwright`[MCP](https://github.com/microsoft/playwright-mcp) 도 지원하는데, 간단히 Claude Desktop 을 이용해서 MCP 연동해서 사용해보자.
276+
277+
:::note
278+
<b>필수 조건</b>
279+
Node.js 18 이상
280+
Claude Desktop 앱 설치
281+
:::
282+
283+
설정은 생각보다 간단하다.
284+
285+
#### 1) Claude Desktop 를 실행시키고, [좌측 메뉴] - [파일] - [설정] 메뉴에서
286+
287+
<div style={{ textAlign: 'center' }}>
288+
<img src="/img/post/testing/playwright/claude-desktop-setting-1.png" alt="claude-desktop-setting-1" style={{ display: 'inline-block' }} />
289+
</div>
290+
291+
#### 2) [개발자] - [구성 편집] 을 누르게 되면,
292+
293+
<div style={{ textAlign: 'center' }}>
294+
<img src="/img/post/testing/playwright/claude-desktop-setting-2.png" alt="claude-desktop-setting-2" style={{ display: 'inline-block' }} />
295+
</div>
296+
297+
#### 3) 아래와 같이, `claude_desktop_config.json` 을 열어주고,
298+
299+
<div style={{ textAlign: 'center' }}>
300+
<img src="/img/post/testing/playwright/claude-desktop-setting-3.png" alt="claude-desktop-setting-3" style={{ display: 'inline-block' }} />
301+
</div>
302+
303+
#### 4) playwright mcp server 를 추가해주고, Claude Desktop 앱을 다시 실행 시켜 주자.
304+
305+
```json
306+
{
307+
"mcpServers": {
308+
"playwright": {
309+
"command": "npx",
310+
"args": ["@playwright/mcp@latest"]
311+
}
312+
}
313+
}
314+
```
315+
316+
#### 5) Prompt 를 작성해주면 playwright mcp 를 실행시켜서 Prompt 내용대로 동작한다.
317+
<div style={{ textAlign: 'center' }}>
318+
<img src="/img/post/testing/playwright/claude-desktop.png" alt="claude-desktop-playwright" style={{ display: 'inline-block' }} />
319+
</div>
320+
321+
---
322+
323+
:::success
324+
✔ Playwright 는 빠르고 신뢰할 수 있는 테스트 자동화 도구로 개발자에게 매우 직관적인 기능을 제공한다.
325+
✔ codegen 기능을 이용해서 복잡한 사용자 액션을 쉽게 코드로 생성 가능하다.
326+
✔ Claude Desktop 과 MCP 를 연동하면 브라우저 자동화 테스트를 LLM 기반 프롬프트로 제어할 수 있어서 쉽게 테스트가 가능하다.
327+
✔ 단순한 테스트를 넘어서 개발 - 테스트 - 운영을 아우르는 도구라고 생각되고 Playwright 는 충분히 가치가 있는 도구라고 생각된다.
328+
:::
329+
330+
---
331+
332+
333+
## 📚 Reference
334+
335+
* [Playwright 공식 홈페이지](https://playwright.dev/)
336+
* [Playwright for Java 공식 문서](https://playwright.dev/java/)
337+
* [Playwright Test Generator (codegen)](https://playwright.dev/java/docs/codegen)
338+
* [Playwright Actionability 설명](https://playwright.dev/docs/actionability)
339+
* [Playwright MCP 프로젝트](https://github.com/microsoft/playwright-mcp)
340+
* [The Internet - Test Practice Site](https://the-internet.herokuapp.com/login)
43.1 KB
Loading
61.6 KB
Loading
291 KB
Loading
186 KB
Loading
65 KB
Loading
302 KB
Loading
92.9 KB
Loading
403 KB
Loading
362 KB
Loading

0 commit comments

Comments
 (0)