
End To End 테스트의 약자로 애플리케이션이 유저 시나리오대로 잘 움직이는지 확인하기 위한 테스트입니다.
이 일련의 과정이 문제없이 잘 일어나는지 미리 확인할 수 있는데, 만약 테스트 코드가 없다면, 직접 사이트에 접속해서 타이핑 및 버튼 클릭을 해줘야 하기 때문에 생산성이 많이 떨어집니다.
npm install -D cypress
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"cypress:open": "cypress open"
}
}
package.json 파일 scripts에 "cypress:open": "cypress open" 을 추가합니다.
npm run cypress:open
자동으로 cypress 창이 열리면서 루트에 cypress.config.ts 파일 및 cypress 폴더가 생성됩니다.
npm run build && npm run start
npm run cypress:open
먼저 빌드가 되어있어야 합니다. 그 다음, cypress를 실행시키면 다음과 같은 창이 뜨는데 저는 크롬을 쓰기 때문에 Chrome으로 선택했습니다.

기본적인 세팅을 마치고 테스트를 돌려보았습니다.

발행 버튼을 누르면, 디테일 페이지로 넘어가면서 /answers 가 URL에 포함되어 있는지 확인하는 과정에서 에러가 났습니다.
테스트 결과 발행 버튼을 클릭하지만, 다음 화면으로 넘어가지 않는 것으로 확인되었습니다.
http://localhost:3000/writing/... to include /answers
여러번 돌려보아도 계속해서 오류가 났기 때문에, 발행이 되지 않는 문제 즉, 서버 쪽에서 에러를 내고 있는 것이라 판단했습니다. Supabase를 사용하고 있었기 때문에 log를 확인해본 결과, 아래와 같이 409에러가 발생하고 있었습니다.


409에러는 특정 데이터가 이미 있다는 의미입니다. 저는 한 유저가 같은 질문에 동일하게 대답하는 경우를 방지하기 위해 user_id와 question_id에 unique constraint를 걸어놓았습니다. 이것이 에러를 발생시키고 있었고, 에러 처리에 대한 부분이 누락되었음을 알게되었습니다.
결국, 같은 질문 같은 유저로 여러번 테스트를 진행하다보니 생긴 에러였습니다.
일단 추천 질문은 서버에서 해당 유저가 답변하지 않은 질문들로 보여주게 세팅되어 있습니다. 즉, 같은 질문으로 여러번 답하게 되는 경우가 없단 의미입니다.
만약 테스트 상황과 같이 모종의 오류로 인해 두 번의 답변을 하게 될 시, 에러를 출력 및 대시보드로 이동시켜야 합니다.
에러 출력에 큰 힘이 들지는 않기 때문에 추가로 작업을 진행했습니다.
지금의 타입은 409 에러를 잡아내지 못하기 때문에, 해당 에러를 추가합니다.
export type SupabaseAuthErrorType = {
status: "AUTH_ERROR";
error: AuthError;
message: string;
};
export type SupabasePostgrestErrorType = {
status: "POSTGREST_ERROR";
error: PostgrestError;
message: string;
};
export const AUTH_ERROR_MESSAGES = {
"401": "인증 에러가 발생했습니다.",
"403": "권한이 없습니다.",
"422": "이미 사용 중인 이메일입니다.",
};
export const POSTGREST_ERROR_MESSAGES = {
"409": "이미 존재하는 데이터입니다.",
"500": "데이터베이스 에러가 발생했습니다.",
"400": "잘못된 요청입니다.",
"404": "찾을 수 없는 데이터입니다.",
};
다음으로 에러 객체를 리턴하는 유틸 함수를 만듭니다.
import { PostgrestError } from "@supabase/supabase-js";
import { POSTGREST_ERROR_MESSAGES } from "../types/actionTypes";
const handlePostgrestError = (error: PostgrestError) => {
const errorCode = error.code as keyof typeof POSTGREST_ERROR_MESSAGES;
const errorMessage =
POSTGREST_ERROR_MESSAGES[errorCode] || "알 수 없는 오류가 발생했습니다.";
return {
status: "POSTGREST_ERROR",
error,
message: errorMessage,
} as const;
};
export default handlePostgrestError;
아래 로직을 추가해 적절한 에러를 출력하도록 합니다.
클라이언트에서는 Alert Dialog를 통해 에러를 보여주고 있습니다.
const { data, error } = await supabase
.from("user_answers_with_question")
.insert({
title,
content,
question_id: questionId || null,
})
.select();
if (error) {
return handlePostgrestError(error);
}