← Lease Bot 홈블로그
하네스 엔지니어링📅 2026-05-04⏱ 11분 읽기

QA 하네스 체크리스트 — 출시 전 100% 검증하는 14가지

"눈으로 확인했어요"는 통하지 않는다. 826개 페이지를 사람이 본다? 불가능. QA 하네스(QA Harness)는 자동화된 검수 스크립트로 출시 전 모든 기준을 강제한다.

왜 QA 하네스인가?

웹사이트 출시 전 흔한 결함:

각각 사람이 한 페이지씩 확인하면 100페이지 = 하루. 자동 검수 스크립트 = 30초.

QA 하네스 14가지 체크

1. HTML lang 속성 일관성

# 모든 페이지의 lang 추출
for url in $(cat urls.txt); do
  lang=$(curl -sL "$url" | grep -oE 'html lang="[^"]+"' | head -1)
  echo "$url, $lang"
done

2. Title — 본문 언어 일치

# 한국어 페이지인데 영어 title은 fail
title=$(curl -sL "$url" | grep -oE '[^<]+' | head -1)
korean_chars=$(echo "$title" | grep -oE '[가-힣]' | wc -l)
if [ "$korean_chars" -lt 3 ]; then
  echo "FAIL: $url - non-Korean title"
fi</code></pre>

<h3>3. Meta description 존재 여부</h3>
<pre><code>desc=$(curl -sL "$url" | grep -oE 'meta name="description" content="[^"]+')
[ -z "$desc" ] && echo "FAIL: missing description - $url"</code></pre>

<h3>4. Canonical URL 정확성</h3>
<p>canonical이 자기 자신을 가리키지 않으면 SEO 문제. 자동 검사.</p>

<h3>5. hreflang 태그 (다국어 사이트)</h3>
<p>한·영·중·일 4개 언어 → 각 페이지에 4개 hreflang 필수.</p>

<h3>6. JSON-LD 구조화 데이터</h3>
<pre><code>jsonld=$(curl -sL "$url" | grep -oE 'application/ld\+json')
[ -z "$jsonld" ] && echo "WARN: no JSON-LD - $url"</code></pre>

<h3>7. H1 단일성 + 누락 검사</h3>
<pre><code>h1_count=$(curl -sL "$url" | grep -c '<h1')
[ "$h1_count" -eq 0 ] && echo "FAIL: no H1"
[ "$h1_count" -gt 1 ] && echo "WARN: multiple H1"</code></pre>

<h3>8. 이미지 alt 속성</h3>
<pre><code>imgs=$(curl -sL "$url" | grep -oE '<img[^>]+>')
no_alt=$(echo "$imgs" | grep -v 'alt=' | wc -l)
[ "$no_alt" -gt 0 ] && echo "FAIL: $no_alt imgs without alt - $url"</code></pre>

<h3>9. 모바일 viewport meta</h3>
<pre><code>vp=$(curl -sL "$url" | grep 'viewport')
[ -z "$vp" ] && echo "FAIL: no viewport - $url"</code></pre>

<h3>10. 반응형 디자인 (실제 viewport 시뮬레이션)</h3>
<p>Playwright로 320/375/390/414/768/1024/1440 7개 viewport에서 스크린샷 → 차이 자동 비교.</p>

<h3>11. 외부 의존성 잔존 검사</h3>
<pre><code>for marker in 'wp-rocket' 'elementor-element' 'visahub' 'zoho'; do
  count=$(curl -sL "$url" | grep -c "$marker")
  [ "$count" -gt 0 ] && echo "FAIL: $marker found in $url"
done</code></pre>

<h3>12. 디자인 시스템 적용 여부</h3>
<pre><code># Tailwind grid-cols / max-w-7xl 사용 검사
tailwind=$(curl -sL "$url" | grep -cE 'grid-cols-|max-w-7xl|object-cover')
[ "$tailwind" -eq 0 ] && echo "FAIL: no Tailwind classes - $url"</code></pre>

<h3>13. 핵심 콘텐츠 최소 길이</h3>
<pre><code>text=$(curl -sL "$url" | sed 's/<[^>]*>//g' | tr -d '[:space:]')
char_count=${#text}
[ "$char_count" -lt 1000 ] && echo "WARN: thin content ($char_count chars) - $url"</code></pre>

<h3>14. Sitemap 등록 여부</h3>
<pre><code>sitemap_urls=$(curl -sL "https://example.com/sitemap.xml" | grep -oE '<loc>[^<]+')
echo "$sitemap_urls" | wc -l</code></pre>

<h2>실행 결과 — CSV로 자동 정리</h2>
<table>
  <tr><th>URL</th><th>Lang</th><th>Title KR</th><th>Meta</th><th>WP</th><th>Tailwind</th><th>Total</th></tr>
  <tr><td>/page-1</td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td><strong>PASS</strong></td></tr>
  <tr><td>/page-2</td><td>✅</td><td>❌</td><td>✅</td><td>❌</td><td>❌</td><td><strong>FAIL</strong></td></tr>
  <tr><td>/page-3</td><td>✅</td><td>✅</td><td>❌</td><td>✅</td><td>✅</td><td><strong>PARTIAL</strong></td></tr>
</table>

<h2>QA 하네스의 진짜 가치</h2>
<ul>
  <li><strong>객관성</strong>: "괜찮아 보여요" 대신 "PASS 783 / FAIL 43 / PARTIAL 0"</li>
  <li><strong>속도</strong>: 826페이지를 30초에 검사</li>
  <li><strong>회귀 방지</strong>: 어제 PASS였던 페이지가 오늘 FAIL로 바뀌면 즉시 감지</li>
  <li><strong>책임 분배</strong>: 누가 어느 페이지를 깼는지 자동 추적</li>
</ul>

<h2>운영 패턴 — 30분 단위 모니터링</h2>
<pre><code># cron으로 30분마다 자동 실행
*/30 * * * * /usr/local/bin/qa-harness.sh > /var/log/qa-$(date +%Y%m%d-%H%M).log

# 실패 1개라도 발견 시 알림
[ "$FAIL_COUNT" -gt 0 ] && curl -X POST telegram_alert</code></pre>

<h2>마치며</h2>
<p>QA 하네스는 "출시 전 한 번"이 아니라 "운영 내내 매 30분"이다. 사람의 검수는 한정되지만 스크립트는 무한하다. <strong>품질 보증의 본질은 자동화된 강제</strong>다.</p>

<div class="footer-back">
  <a href="/blog">← 블로그 목록</a> · <a href="/blog/harness-engineering-intro">관련 글: 하네스 엔지니어링 입문 →</a>
</div>

</div>
</body>
</html>