diff --git a/src/components/atoms/page-title/PageTitle.test.tsx b/src/components/atoms/page-title/PageTitle.test.tsx
new file mode 100644
index 00000000..69d5aa05
--- /dev/null
+++ b/src/components/atoms/page-title/PageTitle.test.tsx
@@ -0,0 +1,49 @@
+import "@testing-library/jest-dom";
+
+import { render, screen } from "@testing-library/react";
+
+import PageTitle from "./PageTitle";
+
+describe("PageTitle Component", () => {
+ test("제목이 정상적으로 렌더링되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toBeInTheDocument();
+ });
+
+ test("기본 클래스가 올바르게 적용되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toHaveClass("text-base");
+ expect(heading).toHaveClass("font-semibold");
+ expect(heading).toHaveClass("text-slate-900");
+ });
+
+ test("isMobileFixed 속성이 true일 때 fixed 클래스가 적용되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toHaveClass("fixed");
+ expect(heading).toHaveClass("top-0");
+ expect(heading).toHaveClass("right-0");
+ expect(heading).toHaveClass("left-10");
+ expect(heading).toHaveClass("px-4");
+ expect(heading).toHaveClass("py-3");
+ });
+
+ test("사용자 정의 className이 올바르게 적용되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toHaveClass("custom-class");
+ });
+
+ test("title 속성이 정상적으로 표시되는지 확인", () => {
+ render();
+ const heading = screen.getByText("Hello, World!");
+
+ expect(heading).toBeInTheDocument();
+ });
+});
diff --git a/src/components/atoms/plus-icon/PlusIcon.test.tsx b/src/components/atoms/plus-icon/PlusIcon.test.tsx
new file mode 100644
index 00000000..0fc2ae2e
--- /dev/null
+++ b/src/components/atoms/plus-icon/PlusIcon.test.tsx
@@ -0,0 +1,71 @@
+import "@testing-library/jest-dom";
+
+import { render, screen } from "@testing-library/react";
+
+import PageTitle from "../page-title/PageTitle";
+
+describe("PageTitle Component", () => {
+ test("제목이 정상적으로 렌더링되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toBeInTheDocument();
+ });
+
+ test("기본적으로 h1 요소로 렌더링되는지 확인", () => {
+ render();
+ const heading = screen.getByRole("heading", { level: 1 });
+
+ expect(heading).toBeInTheDocument();
+ });
+
+ test("기본 클래스가 올바르게 적용되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toHaveClass("text-base");
+ expect(heading).toHaveClass("font-semibold");
+ expect(heading).toHaveClass("text-slate-900");
+ });
+
+ test("isMobileFixed 속성이 true일 때 fixed 클래스가 적용되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toHaveClass("fixed");
+ expect(heading).toHaveClass("top-0");
+ expect(heading).toHaveClass("right-0");
+ expect(heading).toHaveClass("left-10");
+ expect(heading).toHaveClass("px-4");
+ expect(heading).toHaveClass("py-3");
+ });
+
+ test("isMobileFixed 속성이 false일 때 fixed 클래스가 없는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).not.toHaveClass("fixed");
+ expect(heading).not.toHaveClass("top-0");
+ expect(heading).not.toHaveClass("right-0");
+ expect(heading).not.toHaveClass("left-10");
+ });
+
+ test("사용자 정의 className이 올바르게 적용되는지 확인", () => {
+ render();
+ const heading = screen.getByText("테스트 제목");
+
+ expect(heading).toHaveClass("custom-class");
+ });
+
+ test("title 속성이 정상적으로 표시되는지 확인", () => {
+ render();
+ const heading = screen.getByText("Hello, World!");
+
+ expect(heading).toBeInTheDocument();
+ });
+
+ test("스냅샷 테스트", () => {
+ const { container } = render();
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/src/components/atoms/plus-icon/__snapshots__/PlusIcon.test.tsx.snap b/src/components/atoms/plus-icon/__snapshots__/PlusIcon.test.tsx.snap
new file mode 100644
index 00000000..5ef5eba3
--- /dev/null
+++ b/src/components/atoms/plus-icon/__snapshots__/PlusIcon.test.tsx.snap
@@ -0,0 +1,11 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`PageTitle Component 스냅샷 테스트 1`] = `
+
+
+ 스냅샷 테스트
+
+
+`;
diff --git a/src/components/atoms/progress-bar/ProgressBar.tsx b/src/components/atoms/progress-bar/ProgressBar.tsx
index 64922fb6..d02d82ec 100644
--- a/src/components/atoms/progress-bar/ProgressBar.tsx
+++ b/src/components/atoms/progress-bar/ProgressBar.tsx
@@ -12,6 +12,7 @@ export default function ProgressBar({ progress }: ProgressBarProps) {
initial={{ width: 0 }}
animate={{ width: `${progress}%` }}
transition={{ duration: 1, ease: "easeOut" }}
+ data-testid="progress-fill"
/>
);
diff --git a/src/components/atoms/todo-chip/TodoChip.test.tsx b/src/components/atoms/todo-chip/TodoChip.test.tsx
new file mode 100644
index 00000000..d2f46437
--- /dev/null
+++ b/src/components/atoms/todo-chip/TodoChip.test.tsx
@@ -0,0 +1,35 @@
+import "@testing-library/jest-dom";
+
+import { render, screen } from "@testing-library/react";
+
+import TodoChip from "./TodoChip";
+
+describe("TodoChip Component", () => {
+ test("기본적으로 'To do' 텍스트가 렌더링되는지 확인", () => {
+ render();
+ const chipElement = screen.getByText("To do");
+
+ expect(chipElement).toBeInTheDocument();
+ });
+
+ test("isDone이 true일 때 'Done' 텍스트가 렌더링되는지 확인", () => {
+ render();
+ const chipElement = screen.getByText("Done");
+
+ expect(chipElement).toBeInTheDocument();
+ });
+
+ test("isDone이 false일 때 'To do' 텍스트가 렌더링되는지 확인", () => {
+ render();
+ const chipElement = screen.getByText("To do");
+
+ expect(chipElement).toBeInTheDocument();
+ });
+
+ test("사용자 정의 className이 올바르게 적용되는지 확인", () => {
+ render();
+ const chipElement = screen.getByText("To do");
+
+ expect(chipElement).toHaveClass("custom-class");
+ });
+});
diff --git a/src/components/molecules/popup/Popup.test.tsx b/src/components/molecules/popup/Popup.test.tsx
new file mode 100644
index 00000000..1c4d766c
--- /dev/null
+++ b/src/components/molecules/popup/Popup.test.tsx
@@ -0,0 +1,86 @@
+import "@testing-library/jest-dom";
+
+import { fireEvent, render, screen } from "@testing-library/react";
+
+import Popup from "./Popup";
+
+describe("Popup Component", () => {
+ const mockOnClose = jest.fn();
+ const mockOnConfirm = jest.fn();
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test("Popup이 정상적으로 렌더링되는지 확인", () => {
+ render(
+
+ 팝업 내용
+ ,
+ );
+ const popupContent = screen.getByText("팝업 내용");
+
+ expect(popupContent).toBeInTheDocument();
+ });
+
+ test("확인 버튼 클릭 시 onConfirm 핸들러가 호출되는지 확인", () => {
+ render(
+
+ 팝업 내용
+ ,
+ );
+ const confirmButton = screen.getByText("확인");
+
+ fireEvent.click(confirmButton);
+ expect(mockOnConfirm).toHaveBeenCalledTimes(1);
+ });
+
+ test("닫기 버튼(배경 클릭) 시 onClose 핸들러가 호출되는지 확인", () => {
+ render(
+
+ 팝업 내용
+ ,
+ );
+ const overlay = screen.getByTestId("popup-overlay");
+ fireEvent.click(overlay);
+ expect(mockOnClose).toHaveBeenCalledTimes(1);
+ });
+
+ test("isCancelEnabled가 true일 때 취소 버튼이 렌더링되는지 확인", () => {
+ render(
+
+ 팝업 내용
+ ,
+ );
+ const cancelButton = screen.getByText("취소");
+
+ expect(cancelButton).toBeInTheDocument();
+ });
+
+ test("isCancelEnabled가 false일 때 취소 버튼이 렌더링되지 않는지 확인", () => {
+ render(
+
+ 팝업 내용
+ ,
+ );
+ const cancelButton = screen.queryByText("취소");
+
+ expect(cancelButton).not.toBeInTheDocument();
+ });
+
+ test("취소 버튼 클릭 시 onClose 핸들러가 호출되는지 확인", () => {
+ render(
+
+ 팝업 내용
+ ,
+ );
+ const cancelButton = screen.getByText("취소");
+
+ fireEvent.click(cancelButton);
+ expect(mockOnClose).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/src/components/molecules/popup/Popup.tsx b/src/components/molecules/popup/Popup.tsx
index 8cd12325..0609cb83 100644
--- a/src/components/molecules/popup/Popup.tsx
+++ b/src/components/molecules/popup/Popup.tsx
@@ -20,6 +20,7 @@ export default function Popup({