실제 버그와 간헐적으로 실패하는 테스트를 어떻게 구별하나요?
재시도를 끄고 테스트를 여러 번 실행해 결과를 세어 보세요. 실제 버그는 실행할 때마다 같은 방식으로 실패하지만, 간헐적으로 실패하는 테스트는 아무것도 바꾸지 않아도 통과하기도 하고 실패하기도 합니다. 아래 예제는 Playwright가 있는 모든 컴퓨터에서 이 과정을 그대로 수행하며, 이어서 Nexus Studio가 각 결과를 어떻게 처리하는지 보여 줍니다.
작성: Nexus Studio 팀, Verdict System LLC. 2026년 10월 27일.
1분 안에 어떻게 구별하나요?
재시도를 끄고 테스트를 여러 번 연속 실행하세요. Playwright에서는 두 가지 옵션을 사용합니다: --retries=0은 재시도로 실패가 가려지지 않게 하고, --repeat-each=6은 각 테스트를 여섯 번 실행합니다. 그런 다음 각 테스트의 결과를 세어 보세요.
- 매번 실패한 경우: 아니라는 것을 입증할 때까지는 버그로 취급하세요. 매번 실패하더라도 요청 차단이나 호스트 접속 불가 같은 환경 문제 때문일 수 있으므로, 먼저 오류를 읽어 보세요.
- 일부 실행은 통과하고 일부는 실패한 경우: 간헐적 실패입니다. 실행 사이에 코드와 테스트가 바뀌지 않았으므로, 애플리케이션이나 테스트에 불안정한 요소가 있다는 뜻입니다.
- 매번 통과한 경우: 아직 확인된 문제는 없습니다. 50번 중 한 번 나타나는 결함은 더 많이 실행하거나 테스트 실행 기록을 살펴봐야 합니다.
실행 가능한 예제로 확인해 볼 수 있나요?
다음을 bug-or-flaky.spec.js로 저장하세요. 첫 번째 테스트는 간헐적 실패를 모의합니다: 세 번 중 한 번 실패합니다. 두 번째 테스트는 실제 버그입니다: 페이지에는 "Welcome"이라고 표시되지만 테스트는 "Welcome back"을 기대하므로 어떤 실행도 통과할 수 없습니다.
import { test, expect } from '@playwright/test';
// Fails on its first attempt of every third run, passes otherwise: a simulated flake.
test('flaky: a slow load now and then', async ({ page }, info) => {
await page.setContent('<h1>Welcome</h1>');
expect((info.repeatEachIndex + info.retry) % 3, 'simulated slow load').not.toBe(0);
});
// Fails the same way every time: the heading says "Welcome", the test expects "Welcome back".
test('real bug: wrong heading', async ({ page }) => {
await page.setContent('<h1>Welcome</h1>');
await expect(page.locator('h1')).toHaveText('Welcome back', { timeout: 300 });
});
재시도를 끄고 여섯 번 실행하세요:
npx playwright test --retries=0 --repeat-each=6
Playwright는 실패 8회, 통과 4회로 종료됩니다. 질문의 답은 테스트별 횟수에 있으며, 목록 리포터가 한 줄씩 출력한 내용도 바로 그것입니다:
flaky: a slow load now and then 4 passed, 2 failed
real bug: wrong heading 0 passed, 6 failed
이제 재시도를 두 번 허용하고 한 번 실행하세요:
npx playwright test --retries=2
Playwright는 각 그룹에 테스트가 하나씩 있는 상태로 종료됩니다. 간헐적으로 실패하는 테스트는 첫 시도에서 실패하고 재시도 #1에서 통과했습니다. 실제 버그는 세 번의 시도에서 모두 실패했습니다.
1 failed
bug-or-flaky.spec.js:10:1 › real bug: wrong heading
1 flaky
bug-or-flaky.spec.js:4:1 › flaky: a slow load now and then
재시도에서 통과하면 애플리케이션에 문제가 없다는 뜻인가요?
아닙니다. 재시도에서 통과했다는 것은 시도별 결과가 달랐다는 뜻일 뿐입니다. 실행 결과가 녹색으로 바뀌고 아무도 살펴보지 않으면, 경쟁 상태, 공유 데이터, 느린 의존 구성 요소 등으로 인한 애플리케이션의 간헐적 결함이 가려집니다. 이런 결함은 찾아내는 데 비용이 가장 많이 드는 유형에 속합니다. 간헐적 실패 결과를 무시해도 되는 통과가 아니라 발견된 문제로 받아들이고, 원인이 테스트에 있다고 단정하지 마세요.
Nexus Studio는 각 결과를 어떻게 처리하나요?
Nexus Studio는 모든 시도를 기록하고 결과에 별도의 판정을 내리므로, 재시도로 인해 결함이 단순한 녹색 실행 결과로 바뀌지 않습니다.
- FLAKY: 테스트가 실패한 뒤 재시도에서 통과했지만, 수정된 것은 없습니다. 종료 코드가 0이므로 빌드는 실패하지 않으며, 보고서와 실행 기록에는 주의 사항이 표시됩니다.
- BREACHED: 테스트가 한 번의 시도에서 실패했으며, 환경이나 테스트 실행 도구의 패턴으로는 오류를 설명할 수 없습니다. 종료 코드는 1입니다.
- BREACHED_FLAKY: 앞서 재시도를 거친 후 마지막 시도에서 테스트가 실패했으며, 환경 패턴으로는 이를 설명할 수 없습니다. 종료 코드는 1입니다. 버그를 등록하기 전에 시도별 결과를 비교하세요.
실행 기록은 각 테스트의 실행마다 한 행을 남기므로, 통과, 실패, 다시 통과를 반복하는 테스트가 재실행 속에 묻히지 않고 추세로 드러납니다. 간헐적 실패 테스트 안내에는 각 판정이 남기는 파일이 정리되어 있습니다.
어떤 한계가 있나요?
- 예제의 간헐적 실패는 반복해서 재현되도록 산술 연산으로 모의한 것입니다. 실제 간헐적 실패에는 원인이 있으며, 이를 찾는 일은 여전히 사람의 몫입니다.
- 여섯 번의 실행은 간단한 점검이지 통계적 검증이 아닙니다. 50번 중 한 번 발생하는 실패는 여섯 번 모두 통과할 수도 있습니다.
- 매번 실패한다고 해서 항상 애플리케이션의 버그인 것은 아닙니다: 느린 네트워크, 접속 차단 페이지, 작동하지 않는 브라우저도 테스트 실패를 일으킵니다. 거짓 실패 안내에서 구별 방법을 확인할 수 있습니다.
- 재시도를 끄면 Nexus Studio에서 간헐적으로 발생하는 실패는 BREACHED로 판정됩니다. FLAKY와 일반 실패는 재시도를 통해서만 구분할 수 있기 때문입니다. 분류 시 오류 메시지를 분석하므로, 예상과 다른 판정이 나오면 metadata.json을 열어 보세요.
어디에서 볼 수 있나요?
판정 안내서는 엔진이 14가지 판정을 어떤 순서로 결정하는지 설명하고, 증거 페이지는 실패한 테스트 하나가 남기는 모든 파일을 차례로 살펴봅니다. 30일 체험판에서는 동일한 엔진으로 직접 만든 테스트를 실행할 수 있습니다.