GS 인증이란?
GS 인증(Good Software 인증)은 국산 소프트웨어의 품질을 검증하고, 공공기관에서 사용할 수 있도록 인증해주는 제도다. 한국정보통신기술협회나 한국산업기술시험원 같은 공인 기관이 실제 운영 환경과 유사한 조건에서 소프트웨어를 테스트하며, 기능성, 효율성, 사용성, 신뢰성 등을 종합적으로 평가한다.
이 인증이 중요한 이유는 단순한 “품질 인증”을 넘어서 사업과 직접적으로 연결되기 때문이다. GS 인증을 받으면 공공기관 우선구매 대상 제품으로 지정되고, 조달청 등록 및 수의계약이 가능해진다. 즉, B2G 사업을 진행하려면 사실상 필수적인 관문이라고 볼 수 있다.
GS 인증을 신청하게 된 이유
우리 팀도 이 인증을 피할 수 없는 상황이었다. 약 2억 7천 규모의 B2G 사업을 따냈는데, 계약을 성사시키기 위해서는 GS 인증을 반드시 통과해야 했다. 문제는 시간이었다. 주어진 기간은 2개월이었다.
이게 왜 문제냐면, GS 인증은 보통 단기간에 끝나는 작업이 아니다. 이전에 GS 인증을 경험했던 개발자들의 이야기를 들어보면, 개발자 6명이 붙어서 6개월 동안 진행한 사례가 일반적이었다. 그런데 우리 팀은 AI 개발자 2명(OCR, Parser), 프론트엔드 1명, 백엔드 1명, 총 4명으로 이걸 2개월 안에 끝내야 했다. 심지어 이것만 하는 게 아니라 내부 Saas도 개발해야하고, 다른 B2B 프로젝트도 해야했다(아 진짜 너무 한 거 아니냐뇨?!).
2땡인 이유는 프론트, 백엔드가 제일 업무가 많아서…
처음에는 단순하게 생각했다. 기능만 안정적으로 동작하면 되지 않을까 싶었다. 실제로 초기에는 평소처럼 개발하고, 배포 전에 간단한 sanity test를 돌리는 방식으로 진행했다. 하지만 GS 인증을 실제로 진행하면서 이 생각이 완전히 틀렸다는 걸 깨닫게 됐다.
GS 인증은 단순한 기능 테스트가 아니었다. 서비스에서의 기능 정상 동작은 기본이고, 예외 처리, UX, UI 깨짐, 보안 설정, 성능까지 모두 확인한다. 여기까지는 어느 정도 예상 가능한 범위였다.
진짜 어려운 부분은 문서였다.
GS 인증, 어디까지 테스트하니?
GS 인증에서는 사용자 취급 설명서까지 시험 대상에 포함된다. 단순히 문서가 있는지만 보는 게 아니라, 오타, 띄어쓰기, 문단 정렬 같은 디테일까지 확인하고, 문서에 적힌 내용과 실제 서비스가 정확히 일치하는지를 본다.
예를 들어 문서에 기재된 에러 메시지와 실제 서비스에서 노출되는 에러 메시지가 다르면 그것도 결함이다. 제품 버전이 문서와 다르게 표기되어 있어도 문제다.
나중에는 ‘결함’이라는 단어에 노이로제가 걸려서 다른 프로젝트 진행할 때도 이슈나 버그를 ‘결함’이라고 말해버릴 정도였다.
이런 것까지 결함이라고…?
가장 당황스러웠던 건 인프라 관련 기준이었다. 문서에 “서버 1대”라고 적혀 있으면 실제로도 그렇게 보여야 한다. 물리 서버가 하나라고 해서 끝이 아니다. 도커 컨테이너가 두 개로 나뉘어 있으면 서버 두 개로 간주된다. 심지어 컨테이너 이름도 문서에 적힌 서버 이름과 맞춰야 한다.
이 지점에서 GS 인증의 성격이 명확해진다.
GS 인증은 단순히 “잘 동작하는 소프트웨어”를 검증하는 게 아니라, “문서와 실제 서비스가 완전히 일치하는 상태”를 요구하는 시험이다. 그리고 이 기준에서 하나라도 어긋나면 결함으로 판단된다. 기능 결함이 하나라도 발견되면 인증위원회 단계로 넘어가지 못하기 때문에, 사실상 모든 케이스를 통과해야 한다.
결국 GS 인증은 기능 개발의 문제가 아니라, 제품 전체의 완성도를 끝까지 밀어붙이는 작업에 가깝다. 이걸 2개월 안에 해야 하는 상황이었고, 이때부터 문제들이 하나씩 터지기 시작했다.
문제: 결함, 결함, 결함!
GS 인증을 진행하면서 가장 먼저 부딪힌 문제는 QA였다. 정확히 말하면, GS 인증을 시작할 당시 프로젝트 인원에 QA가 없었다.
처음에는 개발자가 배포 전에 간단한 sanity test를 돌리는 정도였다. 기능이 대략적으로 동작하는지만 확인하고 넘어가는 방식이었다. 내부적으로 쓰는 서비스라면 이 정도로도 큰 문제가 없을 수 있다. 하지만 GS 인증은 전혀 다른 이야기였다.
GS 인증에서는 “실제 사용자가 쓸 때 발생할 수 있는 모든 상황”을 기준으로 테스트를 진행한다. 이 기준에서 보면, 우리가 하고 있던 테스트는 거의 의미가 없었다. 정상 흐름만 확인하고 있었고, 예외 케이스는 사실상 고려하지 않고 있었다.
결과는 예상대로였다. 시험 진행 전, 수행기관에서 나온 담당 연구원님이 검증하실 때마다 결함이 계속 나왔다. 기능 자체는 동작하는데, 특정 조건에서 깨지거나, 예상하지 못한 입력에서 오류가 발생하거나, 안내 메시지가 애매해서 사용자 입장에서 이해하기 어려운 경우들이 반복적으로 발견됐다.
문제1. 아… QA가 필요하구나.
한 번 GS 인증 시험을 실패하고 나서야 QA가 붙었고, 그때부터 체크리스트 기반 테스트가 만들어졌다. 사용자 취급 설명서를 기준으로 테스트 케이스를 정리하고, 그 순서대로 하나씩 검증하는 방식이었다.
문제는 여기서 끝나지 않았다.
체크리스트 기반 QA는 “정의된 시나리오”를 검증하는 데는 강하다. 하지만 GS 인증에서 요구하는 수준은 그 이상이었다. 실제 사용자가 어떻게 행동할지 알 수 없기 때문에, 문서에 없는 예외 케이스까지 계속 발견됐다. 결국 체크리스트만으로는 결함을 다 잡을 수 없었다.
문제2. 아… TC 84개를 언제 다 리그레션 하냐…
그리고 더 현실적인 문제가 하나 있었다.
리그레션 테스트 비용이었다.
GS 인증을 위해 기능을 최대한 줄였음에도 불구하고, 한 번 리그레션을 돌릴 때 확인해야 하는 테스트 케이스가 80개가 넘었다. 실제로는 약 84개 정도였다. 이걸 사람이 하나씩 수행하면 한 번 돌리는 데 거의 1시간이 넘게 걸렸다.
문제는 GS 인증을 진행하는 동안 배포가 굉장히 잦다는 점이다. 결함을 수정하고, 다시 배포하고, 다시 테스트하는 사이클이 계속 반복된다. 이때마다 1시간짜리 리그레션을 계속 돌려야 한다면, QA는 계속 밀리게 된다.
해결 방법
결국 상황이 정리된다.
정상 시나리오만 검증하는 기존 방식으로는 결함을 잡을 수 없고, 체크리스트 기반 QA만으로는 예외 케이스를 커버하기 어렵고, 수동 리그레션은 비용이 너무 크다.
이 시점에서 선택지가 필요해진다.
하나는 사람을 더 투입하는 방법이고, 다른 하나는 테스트 방식을 바꾸는 방법이다.
우리는 사람이 없기 때문에 나는 후자를 선택했다.
이때 도입한 것이 Playwright와 agent-browser였다.
QA 자동화: Playwright, Agent Browser
Playwright와 agent-browser는 둘 다 테스트 자동화에 활용했지만, 역할은 분명히 달랐다. 처음에는 둘 다 “브라우저를 다루는 도구”처럼 보였지만, 실제로 써보면 잘하는 일이 다르다. 이 차이를 구분하지 않으면 둘 중 하나만 과하게 쓰게 되고, 결국 테스트 전략이 어정쩡해진다.
리그레션 테스트: Playwright
Playwright는 리그레션 테스트에 집중해서 사용했다. GS 인증을 진행하면서 가장 괴로웠던 건 결함을 하나 수정할 때마다 기존 기능이 다시 깨지지 않았는지 반복해서 확인해야 한다는 점이었다. 한두 번은 사람이 할 수 있다. 문제는 이걸 배포할 때마다 해야 한다는 것이다. 특히 시험 막바지에는 수정, 배포, 확인이 짧은 주기로 반복됐다. 이때부터는 사람이 꼼꼼한지가 아니라, 테스트가 자동으로 재현 가능한지가 훨씬 중요해진다.
그래서 Playwright에는 “매번 반드시 확인해야 하는 시나리오”를 맡겼다. 로그인, 파일 업로드, 결과 스트리밍 확인, 최종 결과 테이블 확인 같은 핵심 플로우가 여기에 해당한다. 이런 시나리오는 한 번 깨지면 영향 범위가 크고, 시험에서도 반복해서 검증되기 때문에 가장 먼저 자동화해야 했다.
기본 골격은 recording 기능으로 빠르게 만들고, 이후에 assertion과 selector를 다듬는 방식으로 정리했다. 이 방식이 좋았던 이유는, 처음부터 모든 코드를 직접 치는 것보다 훨씬 빠르게 테스트 초안을 만들 수 있기 때문이다. 다만 recording으로 생성된 코드를 그대로 쓰면 선택자가 지나치게 UI 구조에 의존하는 경우가 많아서, 최종적으로는 사람이 읽고 유지보수할 수 있는 형태로 다듬는 과정이 필요했다.
예를 들어 로그인부터 메인 화면 진입까지는 다음과 같은 식으로 정리했다.
import {test,expect }from"@playwright/test";
test("로그인 후 메인 화면에 진입한다",async ({ page }) => {
await page.goto("/login");
await page.getByLabel("이메일").fill("tester@company.com");
await page.getByLabel("비밀번호").fill("password123!");
await page.getByRole("button", { name:"로그인" }).click();
await expect(page.getByText("메인 화면")).toBeVisible();
});
TypeScript
복사
이 테스트는 복잡하지 않다. 그런데 이런 기본 흐름이 막히면 그 뒤 테스트를 아무리 잘 짜도 다 소용없다. 그래서 핵심 플로우의 앞단은 최대한 단순하고 명확하게 유지했다. Playwright의 장점은 이런 시나리오를 사람이 실수 없이 반복 검증하기 어려운 횟수만큼 꾸준히 실행해준다는 점이다. 개발자는 종종 “이건 방금도 봤는데”라는 이유로 생략하지만, 테스트 코드는 그런 감정을 가지지 않는다. 이럴 때 테스트 코드가 사람보다 훨씬 성실하다.
파일 업로드와 결과 확인도 같은 방식으로 자동화했다. 우리 서비스에서는 로그인 이후 사용자가 파일을 업로드하면 로딩 UI가 보이고, 이후 스트리밍 결과가 먼저 나타난 뒤 최종 결과 테이블이 렌더링되는 흐름이 있었다. 이 플로우는 사람이 눈으로 보기에는 단순해 보이지만, 실제로는 비동기 구간이 여러 번 이어지기 때문에 수동 테스트에서는 놓치기 쉽다.
import path from "node:path";
import { test,expect } from "@playwright/test";
test("파일 업로드 후 스트리밍 결과와 최종 테이블을 확인한다",async ({ page }) => {
await page.goto("/login");
await page.getByLabel("이메일").fill("tester@company.com");
await page.getByLabel("비밀번호").fill("password123!");
await page.getByRole("button", { name:"로그인" }).click();
await expect(page.getByText("메인 화면")).toBeVisible();
const filePath = path.join(__dirname,"fixtures","sample.pdf");
await page.getByLabel("파일 업로드").setInputFiles(filePath);
await expect(page.getByText("분석 중입니다")).toBeVisible();
await expect(page.getByTestId("streaming-result")).toBeVisible();
await expect(page.getByRole("table")).toBeVisible();
await expect(page.getByText("추출 완료")).toBeVisible();
});
TypeScript
복사
이런 테스트는 한 번 보면 단순하다. 그런데 이 단순한 테스트가 없으면, 개발자는 “업로드는 됐던 것 같은데?”, “결과도 아까 나왔던 것 같은데?” 같은 애매한 기억에 의존하게 된다. GS 인증 상황에서 그런 감각은 별 도움이 되지 않는다. 시험은 “됐던 것 같다”가 아니라 “지금도 확실히 된다”를 요구하기 때문이다.
Playwright는 특히 사람이 하기 일일히 하기 힘든 테스트에서 더 효과가 있었다. 예를 들어 모든 입력 필드에 5천 자의 긴 문자열을 넣어보는 테스트가 있었다. 사람이 직접 하면 한 번은 할 수 있지만, 시간이 너무 오래 걸린다. 이런 케이스는 자동화해야 한다.
test("긴 입력값을 저장해도 정상 동작한다",async ({ page }) => {
await page.goto("/deep-ocr");
await page.getByRole("link", { name:"sample1" }).click();
const longText = "가".repeat(5000);
const allValueFields = await page.getByLabel("value*");
for (const field of allValueFields) {
await field.fill(longText);
}
await page.getByRole("button", { name:"저장하기" }).click();
await expect(page.getByText("성공적으로 저장했습니다")).toBeVisible();
});
TypeScript
복사
파일 형식별 업로드 테스트도 같은 맥락이었다. png, jpg, txt, csv, pdf처럼 서로 다른 형식의 파일을 하나씩 올려보는 작업은 사람 손으로 하면 지루하고, 지루한 테스트는 대체로 빠뜨리기 쉽다. 그래서 이런 반복 작업을 Playwright로 넘겼다.
const files = [
"sample.png",
"sample.jpg",
"sample.txt",
"sample.csv",
"sample.pdf",
];
for (const fileName of files) {
test(`${fileName} 업로드가 정상 동작한다`, async ({ page }) => {
await page.goto("/deep-ocr");
await page
.getByLabel("파일 업로드")
.setInputFiles(path.join(__dirname, "fixtures", fileName));
// ... 중간 생략 ...
// 업로드 완료 후 테이블 확인
await expect(page.getByRole("table")).toBeVisible();
});
}
TypeScript
복사
이런 식으로 구성하면 회귀 테스트가 훨씬 단단해진다. 이전 방식에서는 개발자가 직접 sanity test를 하면서 “대충 중요한 건 봤다” 수준으로 넘어갔다면, 개선된 방식에서는 핵심 시나리오와 반복 비용이 큰 시나리오를 Playwright가 고정해준다. 덕분에 사람은 그 위에서 더 복잡한 문제를 볼 수 있게 된다.
반면 agent-browser는 조금 다른 방식으로 사용했다. 이 도구는 Playwright처럼 “미리 정해둔 시나리오를 정확히 재생하는 것”보다, 실제 사용자처럼 서비스를 탐색하면서 결함을 찾는 데 더 적합했다. Playwright가 리그레션 테스트의 도구라면, agent-browser는 탐색적 QA를 보조하는 도구에 가깝다.
이 차이는 생각보다 중요했다. GS 인증에서는 사용자 취급 설명서를 기준으로 테스트 케이스를 만들지만, 실제 시험에서는 거기서 끝나지 않는다. 담당 연구원은 서비스를 직접 써보면서 예외 상황을 계속 만든다. 예상하지 못한 순서로 버튼을 누르거나, 실패 후 재시도를 하거나, 입력이 애매한 값을 넣어보기도 한다. 이런 흐름은 사람이 직접 떠올리지 않으면 Playwright 스크립트에 잘 들어가지 않는다. 결국 “사람이 상상한 정상 흐름”과 “실제 사용자가 만들어내는 이상한 흐름” 사이에는 늘 간격이 생긴다.
탐색적 테스트: Agent Browser
agent-browser는 바로 그 간격을 줄이는 데 썼다. 예를 들어 이런 식으로 프롬프트를 줬다.
프롬프트 전문
사람이 하나하나 테스트 케이스를 적지 않아도, agent-browser가 여러 경로를 탐색하면서 의심스러운 상태를 빠르게 드러내준다. 특히 “어디가 이상한지는 모르겠는데 뭔가 불안하다” 싶은 화면에서 도움이 됐다. 개발자는 자기가 만든 화면에 익숙해져 있어서 어색한 UX를 잘 못 느끼는 경우가 많다. 그런데 agent-browser는 그런 익숙함이 없어서, 오히려 더 낯선 시선으로 화면을 훑는다.
실제로는 Playwright와 agent-browser를 같이 썼다. Playwright는 핵심 시나리오를 고정하는 데 사용했고, agent-browser는 그 바깥을 흔드는 데 사용했다. 쉽게 말해 Playwright가 “이 길은 매번 안전한지 확인하는 역할”이라면, agent-browser는 “그 길 말고 다른 길로 가면 어디서 무너지는지 찾는 역할”을 맡았다.
이전 방식과 비교하면 차이가 분명했다. 이전에는 개발자가 배포 전에 손으로 몇 가지를 확인하고 넘어갔다. 개선된 이후에는 Playwright가 반복 검증을 맡고, agent-browser가 탐색을 맡으면서 테스트의 층이 생겼다. 테스트를 더 많이 하게 된 것이 아니라, 테스트를 더 구조적으로 하게 된 셈이다. GS 인증처럼 작은 결함 하나가 전체 일정에 영향을 줄 수 있는 상황에서는, 이 차이가 꽤 크게 느껴졌다.
결과
GS 인증 준비는 약 2달 반에서 3개월 정도 진행됐다. 중간에 한 번 실패했고, 현재는 다시 시험을 진행 중이다. 결과가 확정되면 이 부분은 업데이트할 예정이다.
짧게 보면 “아직 끝나지 않은 과정”이지만, 그 사이에 바뀐 것들은 꽤 명확했다.
테스트 방식
처음 GS 인증을 시작했을 때는 테스트에 대한 기준 자체가 없었다. 개발자가 배포 전에 한 번씩 확인하는 정도였고, 테스트는 어디까지나 “문제가 없어 보이면 넘어가는 과정”에 가까웠다. 그 상태에서는 기능이 동작하더라도, 실제 사용자가 겪을 수 있는 문제를 거의 잡아내지 못했다.
지금은 테스트 방식이 완전히 달라졌다. 핵심 시나리오는 Playwright로 고정되어 있고, 배포할 때마다 동일한 기준으로 반복 검증된다. 이전에는 리그레션 한 번 돌리는 데 1시간 정도 걸렸다면, 이제는 테스트를 돌리는 동안 다른 작업을 할 수 있는 상태가 됐다. 시간 자체가 줄어든 것도 있지만, 더 중요한 건 “검증이 항상 같은 기준으로 이루어진다”는 점이다.
agent-browser를 도입한 것도 변화 중 하나였다. 이전에는 테스트 케이스를 사람이 직접 정의하고, 그 안에서만 결함을 찾았다. 지금은 그 범위를 넘어서는 탐색이 가능해졌다. 예상하지 못한 사용자 행동에서 발생하는 문제를 더 빠르게 발견할 수 있었고, 특히 UX나 에러 처리에서 애매했던 부분들을 많이 정리할 수 있었다.
테스트 커버리지 자체도 달라졌다. 예전에는 “이 정도면 됐겠지”라는 감각으로 마무리했다면, 지금은 “이 시나리오는 자동으로 보장된다”는 영역이 생겼다. 그 위에서 사람은 더 복잡한 케이스를 볼 수 있게 됐다. 테스트를 더 많이 하게 된 게 아니라, 테스트를 더 구조적으로 하게 됐다고 보는 게 맞다.
협업 방식
협업 방식도 바뀌었다. GS 인증 과정에서는 작은 변경 하나가 전체 테스트를 다시 돌리게 만드는 경우가 많았다. 그래서 기능 변경이나 구조 변경을 할 때, 이전보다 훨씬 신중하게 접근하게 됐다. 문서와 서비스가 같이 움직여야 한다는 기준이 생기면서, 자연스럽게 커뮤니케이션도 더 명확해졌다.
장인 정신
돌이켜보면, GS 인증을 준비하면서 가장 크게 바뀐 건 기술 스택이 아니라 “기준”이었다. 조금만 잘못 되어도 ‘결함’으로 판단되니, 이태리 장인 정신처럼 서비스에 대한 디테일이 중요하다는 것을 다시금 상기하게 됐다. 무엇을 테스트해야 하는지, 어디까지 검증해야 하는지, 어떤 상태를 안정적이라고 볼 수 있는지에 대한 기준도 생긴 듯하다.
GS 인증을 하며 느낀 것 + 팁
GS 인증을 준비하면서 가장 크게 느낀 건, 이 과정이 단순히 결함을 수정하는 작업은 아니라는 점이었다. 오히려 제품의 범위를 다시 정리하고, 문서와 서비스의 기준을 맞추고, 팀의 협업 방식까지 점검하게 만드는 과정에 가까웠다. 그래서 몇 가지는 초반부터 알고 있었으면 훨씬 덜 힘들었겠다는 생각이 들었다.
기능 덜어내기
가장 먼저 중요한 건, GS 인증용 사이트에서는 욕심을 버려야 한다는 점이다. 평소 같으면 “이왕 만드는 김에 이것도 넣자”가 자연스러운 흐름일 수 있다. 하지만 GS 인증에서는 그게 독이 된다. 기능이 많아질수록 테스트해야 할 범위가 늘어나고, 문서화해야 할 내용도 늘어나고, 결함이 발생할 가능성도 같이 커진다. 그렇다고 기능이 너무 없어도 문제다. 시험을 통과할 수 있을 정도의 완성도와 흐름은 갖춰야 하기 때문이다. 결국 핵심은 “많이 만드는 것”이 아니라 “꼭 필요한 기능만 안정적으로 남기는 것”이었다. GS 인증에서는 풀옵션보다 미니멈하지만 단단한 구성이 훨씬 강하다.
커뮤니케이션의 중요성
애매한 부분은 절대 팀 내부 해석으로 밀고 가지 않는 것도 중요했다. GS 인증을 진행하다 보면 기준이 예상보다 훨씬 엄격하거나, 상식적으로는 이해가 잘 안 되는 요구사항을 마주칠 때가 있다. 대표적인 게 문서와 실제 인프라의 일치 기준이었다. 물리 서버는 하나인데 도커 컨테이너가 두 개면 서버 두 개로 본다는 기준은 지금도 조금 납득이 안 간다. 그런데 GS 인증에서는 내 납득보다 수행기관의 기준이 더 중요하다. 이럴 때 “이 정도는 괜찮겠지”라고 판단하고 넘어가면 나중에 훨씬 크게 돌아온다. 조금이라도 애매하면 담당 연구원에게 먼저 물어보고, 확인받고, 그 기준에 맞추는 편이 훨씬 안전했다. 괜히 혼자 똑똑해지려다 일정만 날아간다.
UX writing
에러 문구는 생각보다 훨씬 중요했다. 개발하다 보면 “알 수 없는 오류가 발생했습니다” 같은 문구를 너무 쉽게 쓰게 된다. 구현 입장에서는 편하다. 어디서 어떤 예외가 날지 다 분류하기 어려울 때도 많고, 일단 막아두는 느낌으로 넣기 쉽다. 그런데 GS 인증에서는 이런 문구가 거의 도움이 되지 않는다. 사용자 입장에서 원인이 무엇인지 알 수 없고, 무엇을 해야 해결되는지도 드러나지 않기 때문이다. 반대로 “특수문자를 입력할 수 없습니다” 같은 문구는 훨씬 낫다. 왜 실패했는지 바로 알 수 있고, 어떻게 수정해야 하는지도 같이 전달되기 때문이다. GS 인증을 준비하면서는 에러 문구를 개발 편의가 아니라 사용자 행동 기준으로 다시 보게 됐다. 좋은 에러 문구는 예외 처리를 대신해주지는 않지만, 적어도 사용자를 길 잃게 하지는 않는다.
QA
그리고 무엇보다 QA는 선택이 아니라 필수였다. 이건 정말 뼈저리게 느꼈다. 초반에는 개발자가 배포 전에 sanity test만 하고 넘어갔다. 그때는 큰 문제가 없어 보였다. 하지만 GS 인증에서는 그 방식이 전혀 통하지 않았다. 정상 시나리오만 한 번 확인하는 것으로는 실제 사용자가 만들어내는 예외 상황을 따라갈 수 없었기 때문이다. 사용자 취급 문서를 기준으로 한 테스트도 필요하고, 문서 밖에서 터질 수 있는 예외 케이스 테스트도 필요하다. 둘 중 하나만 있어서는 부족하다. 문서 기반 테스트만 하면 시험 시나리오는 통과할 수 있어도 실제 탐색 과정에서 결함이 나오고, 예외 케이스만 보면 문서와 서비스가 어긋나는 문제를 놓치게 된다. 결국 두 가지가 같이 가야 한다.
협업 방식
하나 더 덧붙이면, GS 인증에서는 협업 방식도 기술 스펙의 일부처럼 다뤄야 한다. 평소 프로젝트에서는 누군가 구조를 조금 바꾸거나 리팩터링을 해도, 나중에 맞추면 되는 경우가 많다. 하지만 GS 인증에서는 그렇지 않다. 결함 수정이 아닌 변경은 오히려 리스크가 될 수 있다. 문서와 서비스가 함께 움직여야 하고, 작은 구조 변경 하나가 테스트 범위 전체를 흔들 수 있기 때문이다. 그래서 이 시기에는 “좋은 구조”보다 “안정적으로 유지되는 구조”가 더 중요했다. 오버엔지니어링은 보통 미래의 문제를 줄이기 위해 하지만, GS 인증 직전에는 현재의 문제를 폭발시키는 가장 빠른 방법이 되기도 한다.
팁…
결국 GS 인증을 준비하면서 얻은 팁을 한 문장으로 요약하면 이렇다. 기능을 늘리기보다 범위를 줄이고, 추측하지 말고 확인하고, 테스트를 사람의 기억에 맡기지 말아야 한다. 너무 당연한 말처럼 보이는데, 막상 일정이 촉박하고 결함이 쏟아지는 상황에 들어가면 이 기본기가 제일 먼저 무너진다. GS 인증은 그 기본기를 끝까지 붙들고 가는 팀이 버티는 싸움이었다.
_(1).jpeg&blockId=0e552736-74f0-4f5a-89e1-328d4931ca7c)


