← Phase 1 Phase 1.5 • Day 13 E2E Integration

Local SE Agent Masterclass

MacBook M3 16GB • Complete Implementation Standard
📍 ส่วนที่ 1: หมุดตั้งโจทย์ & วัตถุประสงค์หลัก (Title Connection)

Chapter 13 — End-to-End Integration Testing & Real-World Simulation

ทำไมต้องชื่อนี้และเรียนไปเพื่ออะไร?

ตั้งแต่ Day 1 ถึง Day 12 เราได้สร้างและทดสอบชิ้นส่วนทีละชิ้นอย่างประณีต: ตัวยิง Ollama (Day 1-2), ตัวจัดการ Tool Dispatcher (Day 3), เครื่องมืออ่านไฟล์ (Day 4), เครื่องมือรัน Maven Subprocess (Day 5), วงจร ReAct Loop (Day 6), หน้ากาก CLI (Day 7 & 11), หน่วยความจำ Sliding Window (Day 8), ฐานข้อมูล ChromaDB Vector Search (Day 9), ระบบ Safe Patch Diff (Day 10), และกำแพงป้องกัน Guardrails (Day 12)

แต่คำถามคอขาดบาดตายก่อนนำไปใช้จริงคือ: "เมื่อชิ้นส่วนทั้งหมดต้องมาทำงานร้อยเรียงพร้อมกันในโปรเจกต์ที่มีบั๊กแอบแฝงจริงๆ ระบบจะสามารถคุยกันรู้เรื่องตั้งแต่ต้นจนจบ (End-to-End) หรือไม่?"

Day 13 เราจึงต้องสร้าง Test Harness & Simulation Pipeline เพื่อทำการจำลองสถานการณ์จริง (Real-World Bug Simulation):
1. Full Component Pipeline: สั่งงาน 1 คำสั่ง ให้ Agent วิเคราะห์ Error Log ➔ ค้นหาไฟล์ด้วย Vector/Reader ➔ แก้ไขโค้ดด้วย Unified Diff ➔ รันซ้ำจนผ่าน
2. Regression Zero-Check: พิสูจน์ว่าการแก้บั๊กจุดหนึ่ง ไม่ได้แอบไปทำลายส่วนอื่นๆ จนเทสตัวเดิมพัง
3. Automated Test Harness (`test_e2e_simulation.py`): สคริปต์อัตโนมัติที่สั่งรันและ Assert สถานะความสำเร็จระดับ 100% บน Mac M3!

✓ Day 1-7: Core Engine & CLI ✓ Day 8-10: Memory, Vector & Diff ✓ Day 11-12: Rich Cockpit & Guardrails Day 13: E2E Integration Simulation 🎯⚡ Day 14: Personal Developer Workspace
📂 ส่วนที่ 2: ผังโครงสร้างโปรเจกต์จริง & ตำแหน่งไฟล์ (Project File Structure)

ใน Day 13 เราจะเพิ่มชุดจำลองโปรเจกต์ที่มีหลายไฟล์และหลายเทสใน sample_maven_project/ และสร้างสคริปต์ทดสอบบูรณาการระบบรวม test_e2e_simulation.py เพื่อประเมินผล:

se_agent/
├── requirements.txt                       # ollama, chromadb, rich
├── main.py                               # Production Rich CLI Entrypoint (Day 11)
├── test_e2e_simulation.py                 # [ไฟล์ใหม่ Day 13] สคริปต์รัน E2E Harness ตรวจสอบทั้งวงจร
├── memory/
│   ├── __init__.py
│   ├── context.py                          # Sliding Window Context (Day 8)
│   └── vector_store.py                     # ChromaDB Vector Store (Day 9)
├── core/
│   ├── __init__.py
│   ├── client.py                          # Ollama Client Wrapper
│   ├── parser.py                          # JSON Parser
│   ├── dispatcher.py                      # Dispatcher พร้อม Guardrails (Day 12)
│   ├── engine.py                          # ReAct Agent Engine
│   ├── ui.py                              # Rich Presentation Cockpit
│   ├── guardrails.py                      # Multi-Layer Safety Guardrails (Day 12)
│   └── tools/
│       ├── __init__.py
│       ├── file_reader.py                  # Tool 1: File Reader
│       ├── test_runner.py                  # Tool 2: Maven Test Runner
│       └── code_refactor.py                # Tool 3: Safe Refactor & Rollback (Day 10)
└── sample_maven_project/                  # [อัปเกรด Day 13] โปรเจกต์จำลองสถานการณ์จริง
   ├── pom.xml
   └── src/
       ├── main/java/
       │   ├── Calculator.java             # คลาสที่ 1: บั๊กเรื่องส่วนลด
       │   └── UserService.java            # [เพิ่มใหม่ Day 13] คลาสที่ 2: บั๊ก NullPointerException
       └── test/java/
           ├── CalculatorTest.java
           └── UserServiceTest.java        # [เพิ่มใหม่ Day 13] ชุดทดสอบที่จับบั๊กได้
📍 test_e2e_simulation.py ทำหน้าที่อะไร?

ทำหน้าที่เป็น End-to-End Test Harness ตั้งแต่เริ่มรีเซ็ตสถานะโค้ดที่มีบั๊ก ป้อนคำสั่งทดสอบเข้าสู่ ReActAgentEngine ติดตามการทำงานของโมดูลทั้งหมด (Memory + Dispatcher + Guardrails + Subprocess) และยืนยันว่าการแก้ไขสำเร็จ 100% โดยชุดทดสอบทั้งสองคลาสใน Maven ผ่านฉลุย

📍 UserService.java & UserServiceTest.java ทำหน้าที่อะไร?

ทำหน้าที่เป็น Real-World Bug Simulation Target โดยจำลองบั๊กยอดฮิตระดับองค์กรคือ NullPointerException เมื่อผู้ใช้ไม่ได้ระบุอีเมล ทำให้ Agent ต้องวิเคราะห์ Stack Trace และเพิ่ม Validation Guard Clause ป้องกันข้อผิดพลาด

🏛️ ส่วนที่ 3: สถาปัตยกรรม E2E Simulation Pipeline (Mental Model)
วงจรปฏิบัติการจริง: 5-Stage Autonomous Problem-Solving Workflow
1️⃣
Diagnose
`mvn test`

รันเทสรอบแรกเพื่อจับ Stack Trace

2️⃣
Inspect
`read_file`

เปิดส่องอ่านบรรทัดที่มีข้อผิดพลาด

3️⃣
Guard & Patch
`apply_patch`

ผ่าน Guardrail + Backup + Diff

4️⃣
Verify
`mvn test` ซ้ำ

พิสูจน์ว่าผลลัพธ์ BUILD SUCCESS

5️⃣
Conclude
`final_answer`

สรุปรายงานวิธีแก้ให้มนุษย์ฟัง

ทำไมการทำ E2E Simulation ถึงเป็นหมุดหมายที่ขาดไม่ได้ก่อนใช้งานจริง?
❌ ถ้าทดสอบแค่ Unit Test ทีละไฟล์ (Component-in-Isolation):

1. เราไม่รู้เลยว่าเมื่อ Ollama ได้รับผลเทสยาวๆ ข้อความจะหลุด Format หรือไม่
2. เราไม่รู้ว่า Guardrail จะเผลอไปบล็อกไฟล์ที่ถูกต้องเพราะพาทเพี้ยนหรือไม่
3. เสี่ยงที่ Agent จะแก้ไฟล์แรกผ่าน แต่เผลอทำให้อีกไฟล์พัง (Regression Error) โดยที่เราไม่รู้ตัว

✅ เมื่อผ่าน E2E Integration Simulation Harness:

1. พิสูจน์ว่าหน่วยความจำ Sliding Window, Guardrails และ Dispatcher เชื่อมต่อกัน 100% ไร้รอยต่อ
2. พิสูจน์ว่า AI สามารถแกะ Stack Trace จริง เจาะจงอ่านไฟล์ และส่ง Diff ที่แม่นยำ
3. ยืนยันว่าชุดทดสอบทั้งโปรเจกต์ผ่านทุกเคส การันตีความพร้อมในการใช้งานเป็นคู่หูวิศวกรส่วนตัว!

💻 ส่วนที่ 4: ซอร์สโค้ดจริง & คำอธิบายทีละบรรทัด (Line-by-Line Implementation)
📄 1. sample_maven_project/src/main/java/UserService.java คลาสจำลองที่มีบั๊ก NullPointerException
package com.example;

public class UserService {
    /**
     * แปลงโดเมนอีเมลให้เป็นตัวพิมพ์เล็ก
     * [บั๊กจำลอง]: ลืมเช็คกรณี email เป็นค่า null หรือว่างเปล่า
     * ทำให้เกิด NullPointerException เมื่อเรียก email.trim()
     */
    public String normalizeEmail(String email) {
        // บั๊ก: ไม่ได้ตรวจ if (email == null)
        return email.trim().toLowerCase();
    }

    public boolean isValidUser(String username, String email) {
        return username != null && !username.isEmpty() && email != null && email.contains("@");
    }
}
📄 2. sample_maven_project/src/test/java/UserServiceTest.java ชุดทดสอบ JUnit 5 ที่ตรวจพบบั๊ก
package com.example;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class UserServiceTest {

    @Test
    void testNormalizeEmail_Success() {
        UserService service = new UserService();
        assertEquals("[email protected]", service.normalizeEmail("  [email protected]  "));
    }

    @Test
    void testNormalizeEmail_NullSafe() {
        UserService service = new UserService();
        // คาดหวังว่าเมื่อส่งค่า null เข้าไป จะต้องได้สตริงว่าง "" กลับมาโดยไม่เกิด NullPointerException
        assertEquals("", service.normalizeEmail(null));
    }

    @Test
    void testIsValidUser() {
        UserService service = new UserService();
        assertTrue(service.isValidUser("alice", "[email protected]"));
        assertFalse(service.isValidUser("", "[email protected]"));
    }
}
📄 3. test_e2e_simulation.py (สคริปต์รัน E2E Test Harness) จำลองสถานการณ์จริง: ส่งคำสั่ง ➔ Agent แกะรอยแก้บั๊ก ➔ ยืนยันผลลัพธ์
import sys
import shutil
from pathlib import Path
from core import (
    OllamaLLMClient,
    ToolDispatcher,
    ReActAgentEngine,
    MaxIterationsReachedError
)
from core.tools import read_file, run_maven_test, apply_code_patch, rollback_file

SYSTEM_PROMPT = (
    "You are an Autonomous Software Engineering Agent running locally on Apple Silicon Mac.\n"
    "You operate in a strict ReAct loop (Reason, Act, Observe).\n"
    "You have access to tools to inspect local code, run Maven tests, and safely apply refactoring patches.\n\n"
    "Available Tools:\n"
    "1. read_file(filepath: string): Reads file content safely from workspace.\n"
    "2. run_maven_test(project_dir: string): Runs Maven unit tests for a Java project.\n"
    "3. apply_code_patch(filepath: string, new_code: string): Safely applies code patch with automatic backup and diff.\n"
    "4. rollback_file(filepath: string): Instantly restores original file from .bak backup.\n\n"
    "Response Rules:\n"
    "- When taking action, reply strictly with JSON:\n"
    "{\n"
    '  "thought": "Your reasoning why you take this step",\n'
    '  "tool": "tool_name",\n'
    '  "arguments": { ... }\n'
    "}\n\n"
    "- When task is completed, reply strictly with JSON:\n"
    "{\n"
    '  "thought": "Summary of achievements",\n'
    '  "final_answer": "Comprehensive conclusion and explanation for human developer"\n'
    "}\n\n"
    "Respond ONLY with valid JSON."
)

def run_simulation():
    print("=" * 70)
    print("🚀 เริ่มต้น Day 13: E2E Integration Testing & Real-World Simulation")
    print("=" * 70)

    project_root = Path("./sample_maven_project").resolve()
    if not (project_root / "pom.xml").exists():
        print(f"❌ ไม่พบโฟลเดอร์โปรเจกต์เป้าหมาย: {project_root}")
        sys.exit(1)

    # 1. ตรวจสอบการเชื่อมต่อโมเดล
    client = OllamaLLMClient(model_name="qwen2.5-coder:7b")
    if not client.check_health():
        print("❌ ไม่พบ Ollama Daemon หรือโมเดล qwen2.5-coder:7b!")
        sys.exit(1)

    # 2. ติดตั้ง Dispatcher พร้อมเชื่อมต่อ Tools ครบทั้ง 4 ชิ้น
    dispatcher = ToolDispatcher(workspace_root=str(Path.cwd()))
    dispatcher.register("read_file", read_file)
    dispatcher.register("run_maven_test", run_maven_test)
    dispatcher.register("apply_code_patch", apply_code_patch)
    dispatcher.register("rollback_file", rollback_file)

    # 3. สร้าง ReAct Agent Engine (จำกัดรอบสูงสุด 6 ขั้นตอน)
    engine = ReActAgentEngine(client=client, dispatcher=dispatcher, max_iterations=6, memory_window=6)

    # 4. โจทย์สถานการณ์จริง: สั่งให้ Agent ตรวจสอบและซ่อมแซมบั๊ก
    user_prompt = (
        "ในโปรเจกต์ sample_maven_project มีบั๊กทำให้ Unit Test ล้มเหลว "
        "ช่วยรันเทสเพื่อหาจุดพัง ตรวจสอบไฟล์โค้ดที่เกี่ยวข้อง แก้ไขให้ถูกต้อง และรันเทสยืนยันจนผ่านทั้งหมด 100%"
    )

    print(f"\n💬 คำสั่งที่ป้อนให้ Agent:\n\"{user_prompt}\"\n")
    print("-" * 70)

    try:
        # สั่งให้ Agent เริ่มปฏิบัติการอัตโนมัติ
        final_answer = engine.run(user_prompt=user_prompt, system_prompt=SYSTEM_PROMPT)

        print("\n" + "=" * 70)
        print("🎉 ผลการปฏิบัติงานสุดท้ายจาก Agent (Final Report):")
        print("=" * 70)
        print(final_answer)

        # 5. [AUTOMATED VERIFICATION HARNESS]: ยืนยันอิสระด้วยคำสั่ง Maven อีกครั้ง
        print("\n" + "=" * 70)
        print("🔍 ขั้นตอนตรวจสอบอิสระ (Verification Harness Assertion):")
        print("=" * 70)
        final_test_output = run_maven_test(project_dir="sample_maven_project")

        print(final_test_output)

        assert "BUILD SUCCESS" in final_test_output, "❌ การทดสอบไม่ผ่าน! โค้ดยังคงมีบั๊กตกค้าง"
        print("\n✅ การันตี 100%: Unit Test ทั้งหมดผ่านฉลุย ปราศจากบั๊กและไม่มี Regression!")
        print("🏆 สถาปัตยกรรม Local SE Agent ของคุณผ่านการทดสอบบูรณาการระดับองค์กรเรียบร้อยแล้ว!")

    except MaxIterationsReachedError as err:
        print(f"\n🛑 Guardrail Alert: {err}")
    except Exception as err:
        print(f"\n❌ ข้อผิดพลาดในการรัน Simulation: {err}")

if __name__ == "__main__":
    run_simulation()
ชำแหละไวยากรณ์สำคัญใน test_e2e_simulation.py
engine = ReActAgentEngine(..., max_iterations=6, memory_window=6)

Bounded Execution & Working Memory: ผูก ReAct Brain เข้ากับ Sliding Window Context เพื่อควบคุมไม่ให้ Token บวมพอง พร้อมตั้งขีดจำกัด 6 รอบ ป้องกันปัญหาลูปค้าง

dispatcher.register("apply_code_patch", apply_code_patch)

Mutation Privilege Delegation: มอบสิทธิ์ให้ Agent สามารถแก้ไขโค้ดจริงในดิสก์ได้ แต่ต้องอยู่ภายใต้การสกัดกั้นของ SafetyGuardrailManager จาก Day 12

assert "BUILD SUCCESS" in final_test_output

Harness Assertion: สคริปต์ทดสอบไม่เชื่อเพียงคำพูดใน final_answer ของ AI แต่สั่งรันคำสั่งระบบปฏิบัติการซ้ำอย่างเป็นกลาง เพื่อพิสูจน์ผลลัพธ์ว่าโค้ดได้รับการแก้ไขจริง

⚡ ส่วนที่ 5: ปฏิบัติการจริงบน Terminal Mac M3 (Step-by-Step Lab)

เปิด Terminal บน MacBook M3 แล้วทำตาม 5 ขั้นตอนนี้เพื่อติดตั้งโค้ดจำลองสถานการณ์จริงและสั่งรันการทดสอบบูรณาการทันที:

ขั้นตอนที่ 1: เข้าโฟลเดอร์โปรเจกต์และเปิด Virtual Environment
cd ~/se_agent
source .venv/bin/activate
ขั้นตอนที่ 2: สร้างไฟล์ใหม่สำหรับ Day 13
touch sample_maven_project/src/main/java/UserService.java
touch sample_maven_project/src/test/java/UserServiceTest.java
touch test_e2e_simulation.py
ขั้นตอนที่ 3: วางโค้ดลงในแต่ละไฟล์

- นำโค้ดใน ส่วนที่ 4 (ไฟล์ที่ 1) ไปวางใน sample_maven_project/src/main/java/UserService.java
- นำโค้ดใน ส่วนที่ 4 (ไฟล์ที่ 2) ไปวางใน sample_maven_project/src/test/java/UserServiceTest.java
- นำโค้ดใน ส่วนที่ 4 (ไฟล์ที่ 3) ไปวางใน test_e2e_simulation.py

ขั้นตอนที่ 4: สั่งรัน E2E Simulation Harness
python test_e2e_simulation.py

🎉 ผลลัพธ์: คุณจะเห็น Agent วิเคราะห์ลูปอัตโนมัติอย่างชาญฉลาด:
👉 Step 1: สั่ง run_maven_test ➔ ตรวจพบว่า testNormalizeEmail_NullSafe ล้มเหลวด้วย NullPointerException
👉 Step 2: สั่ง read_file อ่าน UserService.java
👉 Step 3: สั่ง apply_code_patch เพิ่ม if (email == null) return "";
👉 Step 4: สั่ง run_maven_test ซ้ำ ➔ ผลลัพธ์ BUILD SUCCESS ผ่าน 100%!
👉 Step 5: ส่ง final_answer สรุปงานเสร็จสมบูรณ์!

ขั้นตอนที่ 5 (Bonus): ทดลองสั่งงานผ่าน Rich Cockpit CLI จริง
python main.py -t "ช่วยรันเทสใน sample_maven_project แล้วสรุปสถานะล่าสุดให้ฟัง"

คุณจะเห็นหน้าจอ Cockpit รายงานผลลัพธ์ในกรอบสีเขียวอย่างสวยงาม ยืนยันว่าทุกชุดทดสอบในโปรเจกต์ผ่านฉลุย!

📝 ส่วนที่ 6: ชุดควิซประเมินความรู้เชิงวิศวกรรม 15 ข้อ (ตอบปุ๊บรู้ผลทันที)

ข้อที่ 1: วัตถุประสงค์หลักของการทำ "End-to-End Integration Testing & Real-World Simulation" ใน Day 13 คืออะไร?

ข้อที่ 2: ความแตกต่างสำคัญระหว่าง "Unit Testing ของโมดูลเดี่ยว" กับ "E2E Integration Testing ของ Agent" คืออะไร?

ข้อที่ 3: ในสถานการณ์จำลองของ Day 13 บั๊กที่จำลองขึ้นใน `UserService.java` เกิดจากสาเหตุใด?

ข้อที่ 4: เมื่อ Agent เริ่มประมวลผลโจทย์ใน `test_e2e_simulation.py` ขั้นตอนแรกที่มันควรตัดสินใจทำตามหลักวิศวกรรมคืออะไร?

ข้อที่ 5: ปรากฏการณ์ "Regression Bug" หมายถึงอะไร และเราป้องกันใน Day 13 อย่างไร?

ข้อที่ 6: ใน `test_e2e_simulation.py` ทำไมเราจึงต้องใส่คำสั่ง `assert "BUILD SUCCESS" in final_test_output` หลัง Agent ทำงานเสร็จ?

ข้อที่ 7: บทบาทของ `SafetyGuardrailManager` ที่เราสร้างใน Day 12 ช่วยอะไรในระหว่างการรัน E2E Simulation?

ข้อที่ 8: หาก Agent สั่ง Patch โค้ดแล้วทำให้เทสล้มเหลวมากกว่าเดิม สถาปัตยกรรมของเราเตรียมพร้อมรับมืออย่างไร?

ข้อที่ 9: บทบาทของ `SlidingWindowContext` (Day 8) ในระหว่างที่ Agent วนลูปแก้ปัญหา 4-5 ขั้นตอนคืออะไร?

ข้อที่ 10: ค่า `max_iterations = 6` ใน ReAct Engine มีความสำคัญเชิงวิศวกรรมความปลอดภัยอย่างไร?

ข้อที่ 11: การที่ระบบทั้งหมดรันบน MacBook M3 16GB แบบ Local 100% มีข้อได้เปรียบด้านความเร็วในการทำ E2E อย่างไร?

ข้อที่ 12: การออกแบบซอฟต์แวร์แบบ Clean Architecture ที่เราทำมาตลอด ส่งผลดีต่อการทำ Integration Testing อย่างไร?

ข้อที่ 13: เมื่อรัน `test_e2e_simulation.py` สำเร็จแล้ว ใน Day 14 (วันสุดท้ายของ Phase 1.5) เราจะทำสิ่งใด?

ข้อที่ 14: ทำไมการทดสอบ E2E ใน Day 13 ถึงพิสูจน์ว่าคุณไม่จำเป็นต้องจ่ายเงินซื้อ Cloud Copilot อีกต่อไป?

ข้อที่ 15: ในฐานะวิศวกรซอฟต์แวร์ เมื่อเห็นระบบ Agent ที่คุณสร้างกับมือสามารถแก้บั๊กและรันเทสผ่านฉลุยใน Day 13 คุณรู้สึกอย่างไร?

🏁 สรุปหมุดเชื่อมโยง Day 13 (Chapter Wrap-up)

ใน Day 13 — End-to-End Integration Testing & Real-World Simulation คุณได้พิสูจน์แล้วว่า สถาปัตยกรรมทั้งหมดที่คุณค่อยๆ ประกอบขึ้นมาทีละชิ้นตลอด 12 วัน สามารถทำงานประสานกันได้อย่างไร้รอยต่อ: สั่งรันเทสจับ Error ➔ อ่านไฟล์ ➔ สกัดกั้นความปลอดภัยด้วย Guardrail ➔ แก้ไขโค้ดด้วย Unified Diff ➔ และรันเทสซ้ำจนผ่านฉลุย 100% ตอนนี้ระบบของคุณพร้อมสำหรับการใช้งานจริงในชีวิตประจำวันแล้ว พร้อมก้าวเข้าสู่วันสุดท้ายของ Phase 1.5: Day 14 — Final Polish & Personal Developer Workspace เพื่อติดตั้งให้กลายเป็นคำสั่งประจำเครื่องของคุณแล้วครับ!