AI sudah mengubah cara kita menulis test. Yang lebih revolusioner: sistem yang menguji dirinya sendiri secara otonom, dan AI yang memahami "mengapa" sistem harus reliable — bukan hanya "apakah" ia reliable.
Revolusi Industri 1.0 menggantikan tenaga manusia dengan mesin uap. Revolusi QA yang kita masuki sekarang menggantikan perhatian manual tester dengan kecerdasan mesin. Tapi seperti Revolusi Industri tidak menghilangkan manusia — ia menciptakan pekerjaan baru yang sebelumnya tidak ada — revolusi QA ini menciptakan peran baru: AI QA Engineer, Prompt Test Engineer, Reliability Architect.
LLM sebagai Copilot (sekarang): Seperti junior engineer yang duduk di sebelah Anda. Anda memberi konteks, ia menghasilkan draft test, Anda mereview dan menyempurnakan. Sangat berguna, tapi masih butuh supervisi konstan.
LLM sebagai Agent (masa depan dekat): Seperti senior engineer yang bisa diberi task secara otonom — "Pastikan semua endpoint API ini ditest sebelum deadline". Ia akan menjelajahi codebase, membuat plan, menulis tests, menjalankannya, memperbaiki yang gagal, dan melaporkan hasilnya.
LLM membaca user story, acceptance criteria, dan domain knowledge. Mengidentifikasi ambiguitas, edge case yang tidak disebutkan, dan dependency antar fitur yang perlu ditest.
Dari requirements yang dipahami, LLM menghasilkan test case terstruktur: happy path, negative cases, BVA, dan security considerations. Output bisa langsung dalam format pytest, JUnit, atau Gherkin (BDD).
LLM mereview kode baru: mendeteksi potensi bug logika, pelanggaran coding standards, masalah performa, dan kerentanan keamanan — sebelum code review manual oleh tim.
Ketika test gagal, LLM menganalisis stack trace, log, dan kode yang relevan, lalu menjelaskan dalam bahasa manusia: "Test ini gagal karena fungsi X tidak menangani kasus Y, kemungkinan disebabkan oleh perubahan di commit Z".
LLM tidak hanya menjelaskan masalah — ia mengusulkan patch kode yang spesifik. Developer mereview dan meng-approve, tidak perlu menulis dari nol. GitHub Copilot Autofix sudah melakukan ini.
login(email, password) di file auth.py. Fungsi ini menggunakan bcrypt, return JWT token jika berhasil, raise AuthError jika gagal. Sertakan: happy path, email tidak terdaftar, password salah, email format invalid, dan SQL injection attempt."Testing konvensional: Seperti mengemudi manual — driver (tester) harus selalu ada, memberi input terus-menerus, mengambil keputusan setiap belokan.
Autonomous testing: Seperti mobil self-driving — sistem memahami tujuan (memastikan aplikasi berfungsi sesuai spec), menjelajahi jalur sendiri (test cases), menangani situasi tak terduga (edge cases yang tidak pernah ditulis manusia), dan melaporkan anomali. Manusia hanya mengawasi dari jauh dan mengambil alih di kondisi kritis.
📌 State of the Art 2024–2025: SWE-bench adalah benchmark untuk mengukur kemampuan LLM menyelesaikan real GitHub issues. Sistem terbaik saat ini (Claude 3.5, GPT-4o) mencapai ~50% success rate — artinya AI sudah bisa menyelesaikan separuh dari bug reports nyata secara otonom. Ini angka yang naik pesat dari 4% di tahun 2023.
Pilot tidak belajar menerbangkan Boeing 747 langsung di pesawat sungguhan dengan penumpang. Mereka berlatih di flight simulator yang mereplikasi semua kondisi — termasuk skenario ekstrem seperti engine failure saat takeoff. Digital Twin adalah flight simulator untuk sistem software: kita bisa mensimulasikan kondisi ekstrem (traffic 100x normal, satu data center mati, serangan DDoS) tanpa risiko terhadap sistem produksi sungguhan.
Jika seorang hakim menggunakan sistem AI untuk membantu memutuskan vonis, dan sistem AI tersebut bias terhadap kelompok tertentu — siapa yang bertanggung jawab atas keputusan yang salah? Hakim? Developer AI? Vendor? Pertanyaan yang sama berlaku untuk AI QA: jika sistem AI meloloskan kode berbahaya ke production karena model AI-nya bias atau tidak akurat, siapa yang bertanggung jawab atas kerugian pengguna?
# ================================================================
# S11409 - Sesi 14: Tren Masa Depan QA
# Simulasi AI QA Agent (tanpa API key — berbasis pattern)
# Dosen: Riadi Marta Dinata, S.Ti., M.Kom. | ISTN Jakarta
# ================================================================
import ast, re
from dataclasses import dataclass, field
from typing import List, Dict, Optional
# ── SIMULASI LLM RESPONSE (dalam praktik panggil API Claude/GPT) ──
def simulate_llm_analyze(code_snippet: str) -> Dict:
"""
Simulasi respons LLM untuk analisis kode.
Dalam produksi: ganti dengan call ke Anthropic/OpenAI API.
"""
issues = []
suggestions = []
# Pattern: deteksi anti-patterns umum
patterns = [
(r'except\s*:', "Bare except — tangkap exception spesifik",
"Ganti dengan: except (ValueError, TypeError) as e:"),
(r'print\s*\(', "Gunakan logging bukan print di production",
"Ganti dengan: logger.info() atau logger.debug()"),
(r'time\.sleep\(\d+\)', "Hard-coded sleep — flaky test risk",
"Ganti dengan explicit wait atau event-based synchronization"),
(r'assert\s+\w+\s*==\s*True', "assert x == True tidak idiomatis",
"Ganti dengan: assert x (lebih Pythonic)"),
(r'def test_\w+\(self\):\s*\n\s*pass', "Test stub kosong tidak berguna",
"Implementasikan test logic atau tandai @pytest.mark.skip"),
]
for pattern, issue, suggestion in patterns:
if re.search(pattern, code_snippet):
issues.append(issue)
suggestions.append(suggestion)
# Analisis kompleksitas sederhana
lines = [l for l in code_snippet.split('\n') if l.strip()]
nested_depth = max((len(l) - len(l.lstrip())) // 4 for l in lines) if lines else 0
if nested_depth > 3:
issues.append(f"Nesting terlalu dalam (depth={nested_depth}) — sulit di-test")
suggestions.append("Ekstrak nested logic ke fungsi terpisah")
return {
"issues_found": len(issues),
"issues": issues,
"suggestions": suggestions,
"testability_score": max(0, 10 - len(issues) * 2 - (nested_depth // 2)),
"verdict": "NEEDS_IMPROVEMENT" if issues else "GOOD"
}
@dataclass
class AIQAAgent:
"""
Simulasi AI QA Agent dengan kemampuan:
1. Analisis kode untuk testability
2. Generasi test case dari function signature
3. Prioritisasi area testing berdasarkan risk
"""
name: str = "QA-Agent-v1"
history: List[dict] = field(default_factory=list)
def analyze_code(self, code: str, filename: str = "") -> dict:
"""Analisis kode dan berikan rekomendasi QA"""
result = simulate_llm_analyze(code)
result["filename"] = filename
self.history.append({"action": "analyze", "file": filename, "result": result})
return result
def generate_test_cases(self, func_signature: str, description: str) -> List[str]:
"""
Generate test cases dari function signature dan deskripsi.
Simulasi output LLM yang terstruktur.
"""
# Parse function name dan parameters
match = re.search(r'def\s+(\w+)\s*\(([^)]*)\)', func_signature)
if not match:
return ["# Error: tidak bisa parse function signature"]
func_name = match.group(1)
params_raw = match.group(2)
params = [p.strip().split(':')[0].strip()
for p in params_raw.split(',') if p.strip() and p.strip() != 'self']
# Template test cases yang di-generate AI
test_cases = [
f"def test_{func_name}_happy_path():",
f" # TODO: Test skenario normal sesuai {description}",
f" result = {func_name}({', '.join(['valid_' + p for p in params])})",
f" assert result is not None",
"",
]
# Generate edge case tests berdasarkan tipe parameter
for param in params:
if any(kw in param for kw in ['amount', 'nilai', 'score', 'harga']):
test_cases += [
f"def test_{func_name}_{param}_zero():",
f" # BVA: nilai nol",
f" with pytest.raises((ValueError, AssertionError)):",
f" {func_name}(**{{'{param}': 0}})",
"",
f"def test_{func_name}_{param}_negative():",
f" # BVA: nilai negatif",
f" with pytest.raises((ValueError, AssertionError)):",
f" {func_name}(**{{'{param}': -1}})",
"",
]
if any(kw in param for kw in ['email', 'username', 'nama', 'name']):
test_cases += [
f"def test_{func_name}_{param}_empty():",
f" # Edge case: string kosong",
f" with pytest.raises((ValueError, AssertionError)):",
f" {func_name}(**{{'{param}': ''}})",
"",
f"def test_{func_name}_{param}_sql_injection():",
f" # Security: injection attempt",
f" with pytest.raises((ValueError, Exception)):",
f" {func_name}(**{{'{param}': \"'; DROP TABLE users;--\"}})",
"",
]
# General edge cases
test_cases += [
f"def test_{func_name}_none_input():",
f" # Edge case: None input",
f" with pytest.raises((TypeError, ValueError)):",
f" {func_name}({', '.join(['None' for _ in params])})",
"",
]
self.history.append({"action": "generate_tests", "func": func_name,
"count": test_cases.count("def test_")})
return test_cases
def prioritize_testing(self, modules: List[Dict]) -> List[Dict]:
"""
Prioritisasi modul berdasarkan risk score.
Kriteria: complexity + change frequency + criticality
"""
def risk_score(m):
return (m.get('complexity', 1) * 0.4 +
m.get('change_freq', 1) * 0.35 +
m.get('criticality', 1) * 0.25)
scored = [{**m, 'risk_score': round(risk_score(m), 2)}
for m in modules]
ranked = sorted(scored, key=lambda x: x['risk_score'], reverse=True)
self.history.append({"action": "prioritize", "modules": len(modules)})
return ranked
def report(self):
print(f"\n {self.name} Activity Report")
print(f" Total actions: {len(self.history)}")
for i, h in enumerate(self.history, 1):
print(f" [{i}] {h['action'].upper()}: {list(h.items())[1]}")
# ── MAIN DEMO ─────────────────────────────────────────────────
print("=" * 60)
print(" AI QA AGENT SIMULATION")
print(" S11409 ISTN Jakarta | Sesi 14")
print("=" * 60)
agent = AIQAAgent("ISTN-QA-Agent")
# Demo 1: Analisis kode
sample_code = '''
def proses_pembayaran(amount, user_id):
try:
if amount > 0:
if user_id is not None:
if len(str(user_id)) > 3:
if True: # placeholder
print(f"Processing {amount} for {user_id}")
time.sleep(2)
return True
except:
return False
'''
print("\n[1] Code Analysis:")
result = agent.analyze_code(sample_code, "pembayaran.py")
print(f" Testability Score: {result['testability_score']}/10")
print(f" Verdict: {result['verdict']}")
for i, (issue, sug) in enumerate(zip(result['issues'], result['suggestions']), 1):
print(f" Issue {i}: {issue}")
print(f" Fix: {sug}")
# Demo 2: Generate test cases
print("\n[2] AI-Generated Test Cases:")
sig = "def hitung_ipk(self, nilai_list: list, sks_list: list) -> float:"
tests = agent.generate_test_cases(sig, "menghitung IPK mahasiswa weighted average")
for line in tests[:20]: # tampilkan 20 baris pertama
print(f" {line}")
# Demo 3: Testing prioritization
print("[3] Module Risk Prioritization:")
modules = [
{"name": "auth_service.py", "complexity": 8, "change_freq": 9, "criticality": 10},
{"name": "laporan_nilai.py", "complexity": 5, "change_freq": 3, "criticality": 7},
{"name": "krs_service.py", "complexity": 7, "change_freq": 8, "criticality": 9},
{"name": "utils_string.py", "complexity": 2, "change_freq": 1, "criticality": 2},
{"name": "payment_gateway.py", "complexity": 9, "change_freq": 6, "criticality": 10},
]
ranked = agent.prioritize_testing(modules)
print(f" {'Module':<25} {'Risk Score':>10} {'Priority'}")
print(f" {'-'*25} {'-'*10} {'-'*10}")
for i, m in enumerate(ranked, 1):
priority = ["CRITICAL","HIGH","HIGH","MEDIUM","LOW"][i-1]
print(f" {m['name']:<25} {m['risk_score']:>10.2f} {priority}")
agent.report()
print("\nDone! Ini adalah dasar dari AI QA Agent modern.")
Anda adalah QA Engineer di startup fintech. Jelaskan bagaimana Anda akan mengintegrasikan LLM (Claude atau GPT-4) ke dalam workflow QA harian: (a) di tahap mana LLM paling berguna, (b) bagaimana cara memastikan output LLM akurat dan tidak halusinasi, (c) apa yang TIDAK boleh diserahkan sepenuhnya ke LLM dan mengapa?
Bandingkan skenario berikut: (a) QA Engineer menulis 200 test case manual per sprint, (b) AI Agent menulis 500 test case per sprint tapi tanpa review manusia. Mana yang lebih baik dan mengapa? Rancang model hybrid yang optimal antara kecepatan AI dan judgment manusia.
SIAKAD ISTN ingin membangun Digital Twin untuk persiapan UTS/UAS yang biasanya mengalami lonjakan traffic 10x. (a) Data apa yang harus direplikasi ke twin? (b) Eksperimen apa yang akan Anda jalankan di twin sebelum periode ujian? (c) Bagaimana mengukur apakah twin cukup akurat merepresentasikan production?
Model defect prediction dilatih menggunakan kode dari tim engineering senior. Tim baru dengan background berbeda join perusahaan dan kode mereka secara konsisten di-flagging sebagai "high risk" oleh model — padahal tidak ada defect nyata. (a) Apa masalah yang terjadi? (b) Bagaimana cara mendeteksi dan mengukur bias ini? (c) Langkah apa yang harus diambil untuk memperbaikinya?
Kembangkan AIQAAgent di atas: (a) tambahkan method generate_bdd_scenarios() yang menghasilkan Given/When/Then dari function signature, (b) tambahkan tracking metrics: coverage_score, estimated_test_time, dan ai_confidence, (c) implementasikan simple_memory() yang menghindari generate test case duplikat untuk fungsi yang sudah pernah dianalisis.
LLM for QA bukan hanya pengganti menulis test — ia mengubah seluruh workflow: dari requirements analysis, code review, hingga failure explanation
Prompt engineering adalah skill kritis QA engineer masa depan — prompt yang baik menghasilkan test yang kontekstual, spesifik, dan langsung berguna
Autonomous testing agent bergerak dari tool ke entitas yang punya perception, reasoning, action, dan memory — mendekati junior QA engineer digital
Digital Twin memungkinkan zero-risk chaos engineering dan load testing pada skala produksi — akan menjadi standar enterprise dalam 3 tahun ke depan
EU AI Act membawa konsekuensi hukum nyata — AI QA di sektor kritis wajib transparan, dapat diaudit, dan memiliki human oversight yang terverifikasi
Peran QA Engineer tidak hilang — ia berevolusi dari "penulis test" menjadi "arsitek kualitas" yang mendefinisikan strategi, mengevaluasi AI, dan membuat keputusan kritis