# คู่มืออ้างอิงด่วนสำหรับ Week 13: คำสั่ง k6 และเครื่องมือ

---

## ลิงก์ด่วน

- [การติดตั้ง k6](#k6-installation)
- [เทมเพลตพื้นฐาน](#basic-test-template)
- [รูปแบบโหลด](#load-patterns)
- [เกณฑ์และตัวเลือก](#thresholds--options)
- [HTTP Checks](#http-checks)
- [การรันของ Tests](#running-tests)
- [การวิเคราะห์ผลลัพธ์](#analyzing-results)

---

## k6 INSTALLATION

### Windows (Chocolatey)

```bash
choco install k6
```

### macOS

```bash
brew install k6
```

### Linux (Ubuntu/Debian)

```bash
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
```

### Verify Installation

```bash
k6 version
# Expected: k6 v0.47.0 (or newer)
```

---

## BASIC TEST TEMPLATE

```javascript
import http from "k6/http";
import { check, sleep } from "k6";

// Configuration
export const options = {
  vus: 10, // 10 virtual users
  duration: "30s", // Run for 30 seconds

  thresholds: {
    http_req_duration: ["p(95)<500"], // 95% under 500ms
    http_req_failed: ["rate<0.01"], // Error rate < 1%
  },
};

// Test function (runs for each VU)
export default function () {
  // Make request
  const res = http.get("http://localhost:8080/index.php");

  // Check response
  check(res, {
    "status is 200": (r) => r.status === 200,
    "response time < 500ms": (r) => r.timings.duration < 500,
  });

  // Think time (user reading)
  sleep(1);
}
```

**Run it:**

```bash
k6 run script.js
```

---

## LOAD PATTERNS

### 1. Constant Load (simplest)

```javascript
export const options = {
  vus: 50, // 50 concurrent users
  duration: "5m", // For 5 minutes
};
```

---

### 2. Ramping Load (stages)

```javascript
export const options = {
  stages: [
    { duration: "1m", target: 20 }, // Ramp to 20
    { duration: "3m", target: 20 }, // Stay at 20
    { duration: "1m", target: 50 }, // Ramp to 50
    { duration: "2m", target: 50 }, // Stay at 50
    { duration: "1m", target: 0 }, // Ramp down
  ],
};
```

---

### 3. Spike Test

```javascript
export const options = {
  stages: [
    { duration: "10s", target: 100 }, // Ramp up fast
    { duration: "30s", target: 100 }, // Stay
    { duration: "10s", target: 0 }, // Ramp down fast
  ],
};
```

---

### 4. Stress Test (find breaking point)

```javascript
export const options = {
  stages: [
    { duration: "2m", target: 100 },
    { duration: "2m", target: 200 },
    { duration: "2m", target: 500 },
    { duration: "2m", target: 1000 },
    { duration: "1m", target: 0 },
  ],
};
```

---

## THRESHOLDS & OPTIONS

### Common Thresholds

```javascript
thresholds: {
  // Response time thresholds
  http_req_duration: [
    'p(50)<200',    // Median < 200ms
    'p(95)<500',    // 95th percentile < 500ms
    'p(99)<1000',   // 99th percentile < 1 second
  ],

  // Error rate threshold
  http_req_failed: [
    'rate<0.01',    // Error rate < 1%
  ],

  // Custom metrics
  checks: ['rate>0.95'],  // >95% of checks pass
}
```

### Common Options

```javascript
export const options = {
  vus: 10, // Virtual users
  duration: "30s", // Total duration
  rps: 100, // Requests per second limit

  // How to handle VU ramp-down
  gracefulRampDown: "30s", // Wait 30s before stopping

  // How to handle errors
  insecureSkipTLSVerify: true, // Skip HTTPS cert validation

  // Timeout
  batch: 10, // Batch size
  batchPerHost: 6, // Per host
};
```

---

## HTTP CHECKS

### Basic Checks

```javascript
check(response, {
  "status is 200": (r) => r.status === 200,
  "body is not empty": (r) => r.body.length > 0,
  "response time < 1s": (r) => r.timings.duration < 1000,
  "has header": (r) => r.headers["content-type"] !== undefined,
});
```

### Advanced Checks

```javascript
check(res, {
  "status is 200 or 201": (r) => r.status === 200 || r.status === 201,
  "body contains text": (r) => r.body.includes("expected text"),
  "response time reasonable": (r) => r.timings.duration < 2000,
});
```

---

## RUNNING TESTS

### Basic Command

```bash
k6 run script.js
```

### With Output File

```bash
k6 run script.js -o json=results.json
```

### Set Environment Variable

```bash
k6 run -e TARGET_URL=http://localhost:8080 script.js
```

### Run with Custom Summary

```bash
k6 run script.js --summary-export=summary.json
```

---

## ANALYZING RESULTS

### Key Metrics to Look For

```
✓ http_req_duration .........: p(95)=450ms   ← Response time
✓ http_req_failed ...........: 0.00%        ← Error rate
  http_reqs ..................: 1200  40/s   ← Throughput
  iterations .................: 200   6.6/s
  vus ........................: 10
  vus_max ....................: 10
```

### What Each Metric Means

| Metric              | What it Means             | What's Good     |
| ------------------- | ------------------------- | --------------- |
| `http_req_duration` | Response time             | P95 < 500ms     |
| `http_req_failed`   | Error rate %              | < 1%            |
| `http_reqs`         | Throughput (requests/sec) | Higher = better |
| `vus`               | Current virtual users     | Shows ramp up   |
| Check results       | % of checks passed        | 100% = ideal    |

---

## ความผิดพลาดทั่วไป

❌ **ผู้ใช้ VU มากเกินไปตั้งแต่เริ่มต้น**

```bash
# ไม่ดี: เปิด 1000 VU แบบเดียว ระบบอาจเสียหาย
{ duration: '1s', target: 1000 }

# ดี: เพิ่มระยะเวลาของการทดสอบอย่างค่อยเป็นค่อยไป
{ duration: '5m', target: 1000 }
```

---

❌ **เกณฑ์ควรชัดเจน**

```bash
# ไม่ดี: ไม่มีเกณฑ์อ้างอิงหรือกำหนดช่วงข้อมูลสำหรับการประเมิน

# ดี: กำหนดเกณฑ์ที่ชัดเจนว่าการทดสอบผ่านหรือไม่
thresholds: {
  'http_req_duration': ['p(95)<500'],
  'http_req_failed': ['rate<0.01']
}
```

---

❌ **ห้ามลืมเวลาหยุด (sleep/think time)**

```javascript
// ไม่ดี: ส่ง HTTP request ต่อเนื่องโดยไม่มีเวลาหยุด (ไม่สมจริง)

export default function () {
  http.get('...');
  http.get('...');
  http.get('...');
}

// ดี: เพิ่มเวลาหยุดระหว่าง request เหมือนกับพฤติกรรมผู้ใช้จริง

export default function () {
  http.get('...');
  sleep(2);
  http.get('...');
  sleep(1);
}
```

---

## QUICK RECIPES

### Load Test (most common)

```javascript
export const options = {
  stages: [
    { duration: "2m", target: 50 }, // Ramp up
    { duration: "5m", target: 50 }, // Steady
    { duration: "2m", target: 0 }, // Ramp down
  ],
  thresholds: {
    http_req_duration: ["p(95)<500"],
    http_req_failed: ["rate<0.01"],
  },
};

export default function () {
  const res = http.get("http://localhost:8080/books.php");
  check(res, { "status 200": (r) => r.status === 200 });
  sleep(2);
}
```

### Stress Test

```javascript
export const options = {
  stages: [
    { duration: "1m", target: 100 },
    { duration: "1m", target: 200 },
    { duration: "1m", target: 500 },
    { duration: "1m", target: 0 },
  ],
};

// (use same default function)
```

### Spike Test

```javascript
export const options = {
  stages: [
    { duration: "30s", target: 100 },
    { duration: "1m", target: 500 }, // Spike!
    { duration: "30s", target: 100 },
  ],
};

// (use same default function)
```

---

## REPORTING RESULTS

### Key Metrics to Report

When writing report, include:

```
Performance Test Results
━━━━━━━━━━━━━━━━━━━━━━━━━
Test Duration: 10 minutes
Peak Load: 100 concurrent users

Response Time:
 - P50 (Median): 200ms
 - P95: 450ms          ← Most important!
 - P99: 800ms

Throughput:
 - Average: 40 RPS
 - Peak: 50 RPS

Error Rate:
 - Overall: 0.00%
 - Peak Load: 0.05%

Result: ✅ PASS (All thresholds met)
```

---

## GETTING HELP

**Test won't run:**

```bash
# Check syntax
k6 run --lint script.js

# See error details
k6 run -v script.js    # Verbose
```

**Thresholds not clear:**

- Check Week 13 lecture notes
- Ask instructor to explain percentiles
- p(95) is most important (95% of users)

**Results surprising:**

- Do VU ramp gradually
- Add think time (sleep)
- Check for errors in checks
- Run test twice to verify

---

## QUICK METRICS REFERENCE

| Metric       | Good     | Acceptable | Bad     |
| ------------ | -------- | ---------- | ------- |
| P95 Response | <200ms   | 200-500ms  | >1000ms |
| Error Rate   | <0.1%    | 0.1-1%     | >1%     |
| Throughput   | >100 RPS | 50-100 RPS | <50 RPS |
| Max VUs      | 100+     | 50-100     | <50     |

---

## คำแนะนำที่นิยม

1. **เริ่มที่ง่าย:** โหลดคงที่ก่อนปัญหาที่ซับซ้อน
2. **Ramp gradually:** ไม่กำหนด VU จาก 0 เป็น 1000 แบบทันที
3. **เพิ่ม think time:** `sleep(1)` ภายหลังคำขอ
4. **เก็บผลลัพธ์:** บันทึก k6 output ให้ชัดเจน ถ่ายภาพหน้าจออย่างน้อยก่อนและหลังการทดสอบ
5. **ลองทดสอบซ้ำ:** ทดสอบสองครั้งเพื่อตรวจสอบความสม่ำเสมอของผลลัพธ์
6. **ขอช่วยเหลือ:** หากไม่เข้าใจผลลัพธ์ ถามผู้สอนหรืออ่านคู่มือ k6

---

**Remember:** You're testing HOW FAST it works, not if it works. The "if it works" part was Week 11 + Week 12!

---
