반응형
개념
HtmlUnit이란?
- 자바 기반의 headless 브라우저로, 웹페이지의 자동화 및 스크래핑을 위한 라이브러리를 말한다.
- 서버측에서 실행되며 실제 브라우저를 사용하지 않고 HTML을 파싱하고 자바스크립트를 처리할 수 있다.
HtmlUnit VS Selenium
- HtmlUnit
- 자바 환경에서 지원한다.
- 실제 브라우저를 사용하지 않는다.
- 브라우저를 사용하지 않기 때문에 빠르고 페이지 로드가 효율적이라는 장점이 있다.
- 자바스크립트 처리 지원이 제한적이며, 모든 JavaScript 기능을 지원하지 않을 수 있다는 단점이 있다.
- Selenium
- 자바 뿐만아니라 파이썬, 노드 등 다양한 환경에서 지원한다.
- 실제 브라우저를 사용한다.
- 브라우저를 사용하기 때문에 대부분의 JavaScript 기능을 지원 가능하고, 실제 브라우저 대상으로 UI 테스트가 가능하다는 장점이 있다.
- 느리다는 단점이 있다.
예제
~/src/main/resources/static/demo.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>HtmlUnit Demo</title>
</head>
<body>
<div id="container"></div>
<script>
// 페이지 로드 후 5초 뒤에 content 요소 추가
setTimeout(() => {
const content = document.createElement('div');
content.textContent = "Hello World";
content.classList.add('content');
const container = document.querySelector('#container');
container.appendChild(content);
}, 5000);
</script>
</body>
</html>
build.gradle.kts
dependencies {
// ...
implementation("org.htmlunit:htmlunit:4.4.0")
}
HtmlUnitTest
class HtmlUnitTest {
@Test
fun testHtmlUnit() {
val webClient = WebClient(BrowserVersion.CHROME)
webClient.options.isCssEnabled = true
webClient.options.isJavaScriptEnabled = true
val page = webClient.getPage<HtmlPage>("http://localhost:8080/demo.html")
waitUntilAdded(page, Duration.ofSeconds(15)) {
it is HtmlElement && it.getAttribute("class").contains("content")
}
val content = page.querySelector<HtmlElement>(".content")
val html = page.asXml()
assertEquals("HtmlUnit Demo", page.titleText)
assertEquals("Hello World", content.textContent)
assertTrue(content.getAttribute("class").contains("content"))
assertTrue(html.contains("Hello World"))
}
private fun waitUntilAdded(page: HtmlPage, duration: Duration, condition: (DomNode) -> Boolean) {
val countDownLatch = CountDownLatch(1)
val listener = object : DomChangeListener {
override fun nodeAdded(event: DomChangeEvent) {
if (condition(event.changedNode)) {
countDownLatch.countDown()
}
}
override fun nodeDeleted(event: DomChangeEvent) {
// do nothing
}
}
page.addDomChangeListener(listener)
countDownLatch.await(duration.toMillis(), TimeUnit.MILLISECONDS)
page.removeDomChangeListener(listener)
}
}
반응형
'Development > Java' 카테고리의 다른 글
[Java] Snowflake (0) | 2023.11.02 |
---|---|
[Java] Java 소스 파일 컴파일하여 Class 객체로 로딩하기 (0) | 2023.05.27 |
[Java] Mockito (0) | 2022.06.23 |
[Java] Random (0) | 2022.06.21 |
[Java] Cipher(RSA, AES) (0) | 2022.04.27 |