"눈으로 확인했어요"는 통하지 않는다. 826개 페이지를 사람이 본다? 불가능. QA 하네스(QA Harness)는 자동화된 검수 스크립트로 출시 전 모든 기준을 강제한다.
웹사이트 출시 전 흔한 결함:
각각 사람이 한 페이지씩 확인하면 100페이지 = 하루. 자동 검수 스크립트 = 30초.
# 모든 페이지의 lang 추출
for url in $(cat urls.txt); do
lang=$(curl -sL "$url" | grep -oE 'html lang="[^"]+"' | head -1)
echo "$url, $lang"
done
# 한국어 페이지인데 영어 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
desc=$(curl -sL "$url" | grep -oE 'meta name="description" content="[^"]+')
[ -z "$desc" ] && echo "FAIL: missing description - $url"
canonical이 자기 자신을 가리키지 않으면 SEO 문제. 자동 검사.
한·영·중·일 4개 언어 → 각 페이지에 4개 hreflang 필수.
jsonld=$(curl -sL "$url" | grep -oE 'application/ld\+json')
[ -z "$jsonld" ] && echo "WARN: no JSON-LD - $url"
h1_count=$(curl -sL "$url" | grep -c '
imgs=$(curl -sL "$url" | grep -oE '
]+>')
no_alt=$(echo "$imgs" | grep -v 'alt=' | wc -l)
[ "$no_alt" -gt 0 ] && echo "FAIL: $no_alt imgs without alt - $url"
vp=$(curl -sL "$url" | grep 'viewport')
[ -z "$vp" ] && echo "FAIL: no viewport - $url"
Playwright로 320/375/390/414/768/1024/1440 7개 viewport에서 스크린샷 → 차이 자동 비교.
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
# 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"
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"
sitemap_urls=$(curl -sL "https://example.com/sitemap.xml" | grep -oE '[^<]+')
echo "$sitemap_urls" | wc -l
| URL | Lang | Title KR | Meta | WP | Tailwind | Total |
|---|---|---|---|---|---|---|
| /page-1 | ✅ | ✅ | ✅ | ✅ | ✅ | PASS |
| /page-2 | ✅ | ❌ | ✅ | ❌ | ❌ | FAIL |
| /page-3 | ✅ | ✅ | ❌ | ✅ | ✅ | PARTIAL |
# 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
QA 하네스는 "출시 전 한 번"이 아니라 "운영 내내 매 30분"이다. 사람의 검수는 한정되지만 스크립트는 무한하다. 품질 보증의 본질은 자동화된 강제다.