# 에이슬립 QA 자동화

> 11종 중 10종은 제가 이미 같은 결론에 가 있었습니다. 값어치는 기법이 아니라 독립 검증이었습니다.

- 수치: 11종 중 1
- 사람이 보는 화면: https://aitryed.com/ko/teardowns/qa/asleep-qa/
- 반대 언어: https://aitryed.com/en/teardowns/qa/asleep-qa/index.md
- 출처(원문 8편 중 대표): https://brunch.co.kr/@jiwonleeqa/394
- 출처(멀티 디바이스 동시 제어): https://brunch.co.kr/@jiwonleeqa/398
- 이 사이트 안내(AI용): https://aitryed.com/ko/llms.txt

---

**다른 회사에서 혼자 테스트를 맡고 있는 사람이 1년 반 동안 쓴 글 여덟 편을 읽고, 제가 하는 방식과 하나씩 대 봤습니다. 열한 가지 중 열은 제가 이미 같은 방향으로 가 있었습니다.**

「그럼 읽은 보람이 없었겠네」 싶은데 반대였습니다. **이 편의 값어치는 새로 배운 하나가 아니라, 겹친 열에 있습니다.** 왜 그런지는 아래에서 풀겠습니다.

> **[도판]** 이 묶음이 특별한 건 기법이 아니라 검증 대상이다. 대상이 어려우면 도구 선택이 취향이 아니라 제약이 된다.
>
> 수면 측정 앱의 검증 대상은 화면 전환이 아니라 밤 하나 전체다. 마이크가 호흡음을 모아 30초마다 올리고, 서버가 5분 간격으로 비동기 분석하고, 콜백으로 결과가 오고, 세션이 끝나야 리포트가 나온다. 그 위에 시간·지속성·비동기·식별자 네 제약이 동시에 걸린다.

## 이 사람이 다루는 물건이 유난히 까다롭습니다

만드는 것이 **수면 측정 앱**입니다. 자는 동안 숨소리를 듣고 수면 상태를 판단하는 물건입니다.

이게 테스트하기 왜 어려운지 보겠습니다.

| 보통 앱 | 수면 측정 앱 |
|---|---|
| 버튼 누르면 바로 결과 | **여덟 시간 뒤에 결과** |
| 잘못되면 화면에 표시 | **잘못돼도 화면이 멀쩡함** |
| 다시 해 보면 됨 | **다시 하려면 또 하룻밤** |

그리고 사람의 숨소리라 **회사 밖으로 내보낼 수 없는 자료**입니다. 이 조건이 도구 선택을 좌우합니다 — **편한 걸 고르는 게 아니라 쓸 수 있는 게 몇 개 없습니다.**

## 이 사람이 「핵심」이라 부른 것은 제가 처음에 놓쳤습니다

여기가 제가 실수한 자리입니다.

기기 여러 대를 한꺼번에 쓰는 방식에 두 가지가 있습니다. 이름이 비슷해서 섞어 읽기 쉬운데 **성격이 완전히 다릅니다.**

| | 나눠서 돌리기 | **동시에 같은 걸 누르기** |
|---|---|---|
| 다섯 대가 하는 일 | **각자 다른** 시험 | **똑같은 동작을 한꺼번에** |
| 왜 하나 | 빨리 끝내려고 | **기종마다 다르게 나오는 걸 눈으로 대보려고** |
| 제일 어려운 것 | 기기끼리 안 꼬이게 하기 | **다섯 대에서 「같은 버튼」을 누르기** |

마지막 줄이 핵심입니다. 화면 크기가 다르면 **같은 버튼이 기기마다 다른 위치**에 있습니다. 그래서 「화면 왼쪽에서 300, 위에서 500」 같은 좌표로 누르면 한 대에서만 맞고 나머지는 엉뚱한 데를 누릅니다.

해법은 좌표를 버리는 것입니다. <strong>「화면에서 «확인»이라고 적힌 그 버튼」</strong>을 찾아서 누르게 하면 위치가 달라도 맞습니다.

## 그런데 이 여덟 편 전체에 빠진 것이 하나 있습니다

정직하게 적어 둡니다. **「그래서 버그를 몇 개 잡았나」가 없습니다.**

자동화를 만든 이야기는 자세한데, 그 자동화가 **실제로 결함을 얼마나 잡았는지에 대한 숫자가 여덟 편 어디에도 없습니다.**

이게 흔한 결손입니다. 자동화를 만드는 일은 눈에 보이고 자랑할 만한데, **「그래서 효과가 있었나」는 재기 어렵고 재면 초라할 때가 많아서** 대개 빠집니다. 저도 제 글을 쓸 때 이 자리를 의식적으로 채우려고 합니다.

## 겹친 열 개가 왜 이 편의 진짜 소득인가

이제 처음 이야기로 돌아갑니다.

제가 오래 붙들고 온 결정들이 있습니다. **자료를 회사 밖에 안 내보낸다, 실패하면 무조건 멈춘다, 밤에 무인으로 돌린다, 좌표 말고 화면 요소로 누른다** — 이런 것들입니다.

이 결정들의 문제는 **저 혼자 내린 것이라 맞는지 확인할 방법이 없다**는 데 있었습니다. 표본이 저 하나였습니다.

그런데 전혀 모르는 사람이, 다른 회사에서, 다른 물건을 만들면서, **같은 결론에 독립적으로 도착해 있었습니다.** 표본이 하나에서 둘이 됐습니다.

기법을 하나밖에 못 가져왔어도 **이게 더 값이 큽니다.** 새 기법은 없어도 되지만, 「내가 가는 길이 맞나」는 계속 물어야 하는 질문이라서요.

## 그리고 이 편을 쓰면서 제 판정이 두 번 뒤집혔습니다

여기가 제일 아픈 자리입니다.

**첫 번째.** 「연결이 조용히 끊긴 걸 감지하는 장치」를 새로 배웠다고 적었습니다. 그런데 제 코드를 열어 보니 **이미 들어 있었습니다.** 제가 「해야겠다」고 적어 둔 문서를 **「해 뒀다」로 착각**한 것입니다.

**두 번째.** 그래서 「새로 배운 것 0건」으로 닫으려 했습니다. 그런데 제가 읽은 발췌가 얇아서, **저자가 「이게 핵심」이라고 부른 절을 통째로 빼먹고** 있었습니다. 다시 열어서 읽었습니다.

두 실수가 반대 방향입니다 — **하나는 제 것을 과대평가했고, 하나는 남의 것을 과소평가했습니다.** 그리고 둘 다 **원문을 다시 열어서야** 드러났습니다.

## 가져온 하나는 그날 바로 넣었습니다 (2026-09 점검)

「좌표로 대충 눌러 통과한 것도 똑같은 통과로 남는다」는 구멍은, 이 편을 쓴 날(2026-08-13) 자동 검사에 <strong>«탭 원장»</strong>을 붙여 막았습니다.

누를 때마다 **무엇을 보고 눌렀는지**를 등급으로 적습니다 — 화면에서 실제로 찾아 눌렀나, 검증한 좌표인가, 검증 안 한 좌표인가, 코드에 박아 둔 비율인가. 그리고 약한 근거에 기대 통과한 검사는 **강등 후보**로 따로 보여 줍니다. 자동으로 떨어뜨리지는 않습니다 — 어디서 끊을지는 실측을 보고 정하기로 했습니다.

요즘 실행 하나(2026-09-28)를 예로 들면 탭 7번 중 약한 근거는 0번이었습니다.

## 여기부터는 자세한 기록입니다

**기법 이전은 1건입니다.** 수면 측정 앱 회사의 1인 QA가 1년 반에 걸쳐 쓴 여덟 편에서 설계 결정 열한 개를 뽑아 제 것과 대봤더니, **열은 제가 이미 같은 방향으로 가 있었습니다.** 남은 하나가 이 페이지의 값어치인데 — **이 조사의 진짜 소득은 그 하나가 아니라, 같은 제약 아래서 다른 사람이 독립적으로 같은 결정에 도달했다는 사실**이었습니다. 그리고 그 판정에 이르기까지 **제 결론이 두 번 뒤집혔습니다.**

## 무엇을 만든 사람인가

**수면 측정 앱을 만드는 회사의 1인 QA다.** 2025년 1월부터 2026년 8월까지 여덟 편을 썼고, 층위가 다 다르다 — 커리어 동기 한 편, 배포 후 모니터링, 대규모 자동화 코드 표준, 24시간 실행 중 메모리 붕괴 디버깅, 온프레미스 디바이스 팜 구축, 그리고 자체 QA 플랫폼 회고.

**클라우드를 먼저 고수하려 했다는 게 중요하다.** 클라우드 디바이스 팜 베타에서 소리 주입을 시험하다 실패했고, 벤더가 **5년 전 지원 종료된 프레임워크 버전으로 내려가라**는 해결책을 제시했다. 그 버전 이후 아키텍처가 동기에서 비동기로 바뀌었으니 생태계 몰이해라고 반박했고, 결국 최신 버전에서 동작했다. **그럼에도 소리 주입 방식 자체가 이 제품 검증에 안 맞아 모바일은 클라우드를 접었다.**

그리고 **저자의 결론이 정직하다.** 클라우드 벤더와 싸워 이기고도 이렇게 끝난다 — **"대부분은 클라우드가 맞다."** 특수 요구가 클라우드로 해결 불가하고 허브·노드로 잘 설계할 수 있을 때만 온프레미스가 좋은 방향이라고. **자기 선택을 일반화하지 않는 글은 드물다.**

## 핵심은 동시 제어다 — 병렬 실행이 아니라

둘을 섞어 읽으면 이 묶음을 잘못 읽는다. **성격이 완전히 다른 두 축**이고, 저자가 "핵심"이라 부른 건 뒤쪽이다.

| | 병렬 실행 | **동시 조작** |
|---|---|---|
| N대가 하는 일 | 각기 다른 테스트 | **같은 동작을 한꺼번에** |
| 목적 | 처리량 · 야간 무인 전수 | 기종 간 차이를 눈으로 대조 |
| 최대 난제 | 세션 충돌 · 기기 상태 오염 | **같은 버튼 누르기** |
| 해법 | 허브가 가용 노드를 스캔해 큐잉 | 좌표 대신 **화면 위 실제 요소** 기준 |

저자는 동시 제어를 <strong>"편의 기능이 아니라 1인 QA가 감당할 수 있는 검증 규모 자체를 바꾸는 기능"</strong>이라고 규정한다. 12조합을 기기 하나씩 붙잡고 확인하면 같은 조작을 기기 수만큼 반복해야 하는데, **동시 제어는 그 반복을 없앤다 — 2대든 10대든 걸리는 시간이 거의 같다.**

**성립 조건이 둘이었다.**

- **정확도** — 화면 비율로 계산한 좌표는 기종마다 여백과 상단바 높이가 달라 **같은 화면에서 100px 넘게 어긋난다.** 그래서 화면 위 실제 요소를 찾아 누르는 방식으로 바꿨다
- **속도** — 한 대라도 느리면 전체가 어긋난 것처럼 느껴진다. 그래서 표준 프레임워크를 거치지 않고 기기와 직접 연결했고, **무선에서 화면 탭 14ms · 키 입력 4~7ms**를 실측했다

**그리고 이 묶음에서 제일 제대로 된 수치가 하필 여기 붙어 있다.** 조건("무선 실측")을 밝히고 두 동작을 분리해 제시했다.

## 깨본 결과 — 결함 검출 데이터가 없다

여덟 편 전체를 관통하는 결손이 하나 있다.

> 디바이스 팜도, 플랫폼도, 자연어 검증 엔진도, 자체 테스트 900개도 만들었는데 — **"수동으로는 못 잡았을 결함을 몇 건 잡았다"는 숫자가 어디에도 없다.**

전부 **돌아가는가**로 평가되고 **찾아내는가**로 평가되지 않는다. **자동화가 가장 흔하게 실패하는 지점이 정확히 거기다.**

나머지도 적어 둔다. **"45초 안에 자동 복구"는 검증 불가**다 — 감지 기전이 서술되지 않아 측정된 복구 지연이 아니라 **설정한 타임아웃 값일 가능성이 높다.** 그렇다면 45초는 성과가 아니라 파라미터다. **"자체 테스트 900개"는 허영 지표**다 — 커버리지도, 그것이 잡은 결함 수도 없고, **플랫폼과 그 테스트를 같은 한 사람이 썼으니 자기참조 오라클이라 맹점이 그대로 복제된다.**

**가장 취약한 부품에 증거가 0**인 것도 걸린다. 자연어 시나리오 무인 검증이 이 플랫폼에서 제일 깨지기 쉬운 부분인데 정확도·플래키율·모호할 때의 동작이 한 줄도 없다.

그리고 메모리 붕괴 편은 **절반이 틀린 가설의 확대 서술**이다. 타임아웃 3계층 이야기는 유용한 지식이지만 원인이 아니었고, 실제 해결은 **"녹화 세그먼트를 힙에 쌓지 말고 즉시 디스크에 쓴다"** 한 줄이었다. 게다가 타임아웃을 전부 30시간으로 올린 건 **멈춤 감지기를 꺼 버린 것**이다 — 24시간 테스트에 한해 정당하지만, 상시 기본값이 되면 **"멈춘 세션"과 "긴 세션"을 구분할 수단이 사라진다.**

## 가져온 것은 하나였다

> **[도판]** 기법 이전이 적다는 것과 조사가 헛됐다는 것은 다른 말이다. 겹치는 열 개가 이 페이지의 실제 소득이다.
>
> 설계 결정 열한 개 중 열은 내가 이미 같은 방향으로 가 있었고, 겹치지 않는 하나만이 실제로 넘어왔다.

넘어온 하나가 이것이다.

> **요소를 못 찾아 좌표로 대신 누른 기기가 몇 대인지 세어서 화면에 즉시 표시한다.**

제겐 좌표 폴백이 있는데 **그 계수가 없다.** 그래서 정확히 눌러서 통과한 탭과, **요소를 못 찾아 좌표로 대충 눌러서 통과한 탭이 같은 PASS로 기록된다.**

**PASS가 두 종류인데 리포트에는 한 종류로 남는다는 뜻이다.** 폴백은 다음 빌드에서 조용히 깨질 자리인데, **계수가 없으면 그게 늘어나는 것도 모른다.**

**(2026-09 기준) 들어갔다.** 같은 날(2026-08-13) 러너에 `tapstat` 를 붙였다. 탭 **결정 1회마다** 근거를 `bright`(화면 실측) · `map:auto` · `map:manual` · `map:unverified`(검증 안 된 좌표) · `xy`(코드에 박힌 비율)로 적고, 런 폴더 `_tapstat.txt` 와 TC별 `탭근거`로 낸다. 약한 근거(`map:unverified`·`xy`)에 기댄 PASS 는 **강등 후보로만** 나열한다 — 강등 규칙은 첫 실측 분포를 보고 정한다(근거 없이 임계를 고르면 멀쩡한 TC 를 떨어뜨린다). 연타는 같은 근거라 1회로 센다 — 묻는 것이 «몇 번 눌렀나»가 아니라 «무엇을 보고 눌렀나»라서다.

## 그리고 제 판정을 두 번 고쳤다

**첫 번째.** "침묵 연결 감지가 신규 수확"이라고 적었다가 틀렸다. 제 코드를 열어 보니 **이미 있었다.** 화면 변화량을 별도 축으로 두고 단계 복구를 거는 장치가 배선돼 있었다. **써 둔 운영 지침을 구현된 상태로 착각한 것**이고, 이 실수는 [Prime Agent](/ko/teardowns/harness/prime-agent/index.md)에서도 똑같이 했다.

**두 번째.** 그래서 "신규 도입 0건"으로 닫으려 했는데 **그것도 틀렸다.** 저자가 "핵심"이라고 부른 절이 최초 발췌에 안 잡혀 있었고, **위의 채택 1건이 바로 거기 있었다.**

> **발췌가 얇으면 결론이 통째로 바뀐다.**

## 판정

**기법 이전은 1건.** 이 조사의 진짜 값어치는 다른 데 있었다.

같은 제약 — **1인 QA, 실기기, 장시간, 무인 회귀** — 아래서 **다른 사람이 독립적으로 같은 결정에 도달했다.** 온프레미스, 라이브 환경 기본 차단, 무인 회귀, 요소 기준 타겟팅. 제가 혼자 굴러서 얻은 결론들이라 **표본이 하나뿐이었는데, 이제 둘이다.**

기법이 적게 넘어왔다는 것과 조사가 헛됐다는 것은 **다른 말이다.**
