🗺️ Roadmap 📚 Test Types 🔄 Lifecycle 🛠️ Tools ✅ Practices 🤖 Examples 🔍 Locators 📖 Glossary

QA Automate · Knowledge Base

เรียนรู้ Automated Testing
ให้ได้ผลจริง

ระบบที่ทดสอบด้วยมือทุกครั้งก่อน Deploy เสียเวลา เสียงบ และยังพลาด Bug — นี่คือปัญหาที่ Automated Testing ถูกสร้างมาเพื่อแก้

8
Topics
4
Lifecycle Phases
6+
RF Libraries
15+
Best Practices

ควรรู้อะไรก่อนเริ่มเรียน Automate?

Automated Testing ไม่ใช่จุดเริ่มต้น — แต่คือขั้นถัดไปของคนที่มีพื้นฐานเหล่านี้มาแล้ว รู้ก่อนยิ่งเรียนได้เร็วขึ้นมาก

🧠
✦ จำเป็นมาก
QA Mindset
มองในมุมของผู้ใช้งานจริง — ตั้งคำถามว่า "ถ้า User ทำแบบนี้ ระบบจะรับมือได้ไหม?" หน้าที่ของ QA คือค้นหาปัญหาก่อนที่ User จะเจอ ไม่ใช่แค่ยืนยันว่าของใช้งานได้ ต้องรู้จัก Manual Testing เบื้องต้นก่อน เพราะ Automate คือการทำสิ่งที่เคย Test มือให้ทำงานซ้ำได้เอง
Manual Testing Test Case Bug Report Test Life Cycle Edge Case
bug report · ตัวอย่าง
Title    : ปุ่ม Login ไม่ตอบสนอง เมื่อ Email ว่างเปล่า
Priority : High  |  Environment : Chrome 124 / Staging

Steps to Reproduce:
  1. เปิดหน้า /login
  2. ปล่อย Email ว่าง ใส่ Password ถูกต้อง
  3. คลิก "เข้าสู่ระบบ"

Expected : แสดง validation "กรุณากรอก Email"
Actual   : ปุ่มไม่ตอบสนอง ไม่มี message ใดปรากฏ ไม่มี network call
💻
✦ จำเป็นมาก
Programming เบื้องต้น
อย่างน้อย 1 ภาษา — Variable, Loop, Condition, Function Robot Framework ใช้ง่ายมาก แต่ถ้าไม่เข้าใจ Logic พื้นฐานจะ Debug ไม่ได้ Python แนะนำที่สุดเพราะ RF ใช้ Python เป็นฐาน
Variable Loop Condition Function Python
python · พื้นฐานที่ใช้บ่อยใน RF
# Variable & Data Type
name     = "สมชาย"
age      = 25
is_admin = True

# Condition
if age >= 18:
    print("ผู้ใหญ่")
else:
    print("เด็ก")

# Loop
for i in range(3):
    print(f"รอบที่ {i+1}")

# Function
def get_login_payload(email, password):
    return {"email": email, "password": password}
📦
✦ จำเป็นมาก
Data Knowledge
อ่านและเขียน JSON ได้ — nested object, array, null เข้าใจ Data Type: "1" กับ 1 ต่างกัน — Assert ผิด Type ทำให้ Test ผ่านทั้งที่ Bug ซ่อนอยู่ รู้จัก Date/Time format, XML, CSV เบื้องต้น
JSON Data Types Null vs Empty Date Format XML CSV
json · ตัวอย่าง response จาก api
{
  "user": {
    "id":       42,            ← Number (ไม่ใช่ String)
    "name":     "สมชาย",
    "is_admin": true,          ← Boolean
    "score":    98.5,
    "address":  null,          ← Null ≠ "" (empty string)
    "tags":     ["admin", "qa"]  ← Array
  },
  "created_at": "2026-04-27T10:30:00Z"  ← ISO 8601
}

⚠ Type ต่างกัน → Assert ให้ผลต่าง
"100"100      # String vs Number
null""        # Null vs Empty String
false"false"   # Boolean vs String
🌐
✦ จำเป็นมาก
Web & HTTP Basics
รู้จัก HTML Structure, DOM, ID/Class (สำหรับ Web Test) เข้าใจ HTTP Method — GET POST PUT DELETE รู้จัก Status Code — 200, 400, 401, 404, 500 และ Request / Response Structure พร้อม Header, Body, Auth
HTML / DOM HTTP Method Status Code Request / Response Authorization
http · request & response
── Request ──────────────────────────────────────────
POST /api/auth/login HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

{ "email": "user@test.com", "password": "secret" }

── Response ─────────────────────────────────────────
HTTP/1.1 200 OK
Content-Type: application/json

{ "token": "abc123", "status": "success" }

── Status Code ที่ต้อง Test ──────────────────────────
200 OK          401 Unauthorized    404 Not Found
201 Created     403 Forbidden        500 Server Error
400 Bad Request  422 Unprocessable
🛠️
✧ มีก็ดี
Tools & Environment
Command Line — รัน command ได้, รู้จัก path Git — commit, push, pull เป็น เพื่อดูแล Test Script ร่วมกับทีม Browser DevTools — inspect element, ดู Network tab ได้
Command Line Git VS Code DevTools
terminal · command ที่ใช้บ่อย
# ติดตั้งและรัน Robot Framework
pip install robotframework
pip install robotframework-seleniumlibrary
robot --outputdir results tests/

# Git — จัดการ Test Script
git init
git add tests/login_test.robot
git commit -m "add: login test cases"
git push origin main

# ดู log และ diff
git log --oneline
git diff HEAD~1 tests/
💬
○ เสริม
Soft Skills
อ่าน Requirements / User Story แล้วแปลงเป็น Test Case ได้ เขียน Bug Report ที่ชัดเจน — Steps to Reproduce, Expected vs Actual สื่อสารกับ Developer ได้เมื่อ Test Fail
User Story Acceptance Criteria Bug Report Communication
user story → test case
── User Story ───────────────────────────────────────
As a      registered user
I want to login with email and password
So that   I can access my dashboard

Acceptance Criteria:
   แสดง dashboard เมื่อ credential ถูกต้อง
   แสดง error เมื่อ password ผิด
   Lock account หลัง fail 5 ครั้ง

── แปลงเป็น Test Cases ──────────────────────────────
ควร Login สำเร็จเมื่อ Credential ถูกต้อง
ควรแสดง Error เมื่อ Password ผิด
ควร Lock Account หลัง Login ผิด 5 ครั้งติดกัน

ประเภทของ Automated Test

แต่ละประเภทมีจุดประสงค์ต่างกัน — เข้าใจความแตกต่างช่วยให้เลือกใช้ได้ถูกที่ และจัดสัดส่วน Test Suite ได้อย่างมีประสิทธิภาพตาม Testing Pyramid

Unit Test

Unit Test

ทดสอบหน่วยย่อยที่สุดของ Code เช่น Function หรือ Method เดียว แยกออกจากระบบภายนอกด้วย Mock/Stub ให้ผลลัพธ์รวดเร็วและชี้จุด Bug ได้แม่นยำ

⚡ เร็วมาก (< 1s) 📦 แยก dependency
Jest Pytest JUnit Robot Framework
Integration Test

Integration Test

ทดสอบว่า Component หลายตัวทำงานร่วมกันได้ถูกต้อง เช่น Service + Database หรือ API + External Service ตรวจจับปัญหาที่ Unit Test มองไม่เห็น

⏱ ปานกลาง (1–10s) 🔗 เชื่อม component
RequestsLibrary Database Pytest
E2E Test

End-to-End Test

จำลอง User Journey จริงตั้งแต่ต้นจนจบผ่าน UI ทดสอบว่าระบบทั้งหมดทำงานร่วมกัน ได้ถูกต้องในสภาพแวดล้อมที่เหมือน Production

🐢 ช้า (10s–5min) 🌐 Full stack
Browser Library SeleniumLibrary Playwright
API Test

API Test

ทดสอบ REST/GraphQL API โดยตรง ไม่ผ่าน UI ตรวจสอบ Status Code, Response Body, Headers และ Business Logic ที่ Logic Layer

⚡ เร็ว (1–5s) 🔌 ไม่ต้องการ UI
RequestsLibrary REST GraphQL
Mobile Test

Mobile App Test

Automate การทดสอบบน iOS และ Android ทั้ง Native, Hybrid และ Web App ด้วย AppiumLibrary ที่ Robot Framework รองรับ

📱 iOS & Android 🔁 Simulator/Device
AppiumLibrary iOS Android
Event Test

Event / Message Test

ทดสอบระบบ Event-Driven เช่น Kafka, RabbitMQ ตรวจสอบว่า Event ถูก Publish และ Consume ได้ถูกต้อง รองรับ Async ด้วย Wait Until

🔀 Async 📨 Message Queue
KafkaLibrary RabbitMQ Event-Driven
ชั้น Pyramid สัดส่วน ความเร็ว ค่าใช้จ่าย Robot Framework Library
Unit Test (ฐาน) ~70% ms ต่ำ Built-in / Custom Keywords
Integration Test ~20% 1–10s ปานกลาง RequestsLibrary, DatabaseLibrary
E2E Test (ยอด) ~10% นาที สูง Browser Library, SeleniumLibrary

ทุก Framework ใช้โครงสร้างเดียวกัน

ไม่ว่าจะเป็น Robot Framework, Jest, Pytest หรือ JUnit — ทุก Test ล้วนมี 4 Phase เหมือนกัน ต่างกันเพียง Syntax เท่านั้น เมื่อเข้าใจ Pattern นี้ การเรียน Framework ใหม่ใช้เวลาน้อยลงมาก

PHASE 01
⚙️

PreStep

เตรียมสภาพแวดล้อม ข้อมูล และ Dependencies ก่อน Test จะทำงาน เทียบได้กับ Arrange ใน AAA Pattern

[Setup] / Suite Setup
PHASE 02
▶️

Main Execute

ดำเนินการ Action ที่ต้องการทดสอบจริง เรียก Function, API หรือ Interact กับ UI เทียบได้กับ Act ใน AAA Pattern

Test Case body
PHASE 03
🔍

Verify Result

เปรียบเทียบผลลัพธ์จริงกับสิ่งที่คาดหวัง ถ้าไม่ตรงกัน Test จะ Fail เทียบได้กับ Assert ใน AAA Pattern

Should Be Equal / Should Contain
PHASE 04
🧹

PostStep

ทำความสะอาดและคืนสภาพแวดล้อมสู่สถานะเดิม ลบ Test Data ปิด Connection ทำงานแม้ Test จะ Fail

[Teardown] / Suite Teardown
Phase Robot Framework Jest / Vitest Pytest JUnit 5
PreStep [Setup] / Suite Setup beforeEach / beforeAll @pytest.fixture @BeforeEach / @BeforeAll
Main Execute Test Case body it() / test() body def test_*() body @Test method body
Verify Result Should Be Equal / Should Contain expect().toBe() / toEqual() assert / pytest.approx Assertions.assertEquals()
PostStep [Teardown] / Suite Teardown afterEach / afterAll yield fixture @AfterEach / @AfterAll

Robot Framework Ecosystem

Robot Framework เป็น Keyword-Driven Framework ที่ขยายความสามารถด้วย Library ทำให้ Automate ได้ทุกอย่างตั้งแต่ Web, API, Mobile จนถึง Message Queue

Robot Framework

Keyword-Driven Test Automation
Python Core Framework All Layers

Framework หลักที่ใช้ Keyword-Driven Syntax อ่านเข้าใจได้แม้ไม่ใช่นักพัฒนา รองรับทุก Test Type ผ่าน Library และมี Ecosystem กว้างขวาง

✦ แนะนำสำหรับ QA ทุกระดับ

Browser Library

Powered by Playwright
Web E2E Modern Auto-Wait

RF Library สำหรับ Web Automation ที่ใช้ Playwright เป็น Engine มี Auto-Wait ในตัว รองรับ Chrome, Firefox, Safari และ Trace Viewer

✦ แนะนำสำหรับ Web E2E ใหม่

RequestsLibrary

HTTP API Testing
REST API GraphQL Integration

Library สำหรับทดสอบ REST API และ HTTP Requests ครอบคลุม GET/POST/PUT/DELETE พร้อม Assert Response Status, Body และ Headers

✦ แนะนำสำหรับ API Testing

AppiumLibrary

Mobile App Automation
iOS Android Native & Hybrid

Library สำหรับ Automate Mobile App บน iOS และ Android รองรับทั้ง Native App, Hybrid App และ Mobile Web ผ่าน Appium Server

✦ แนะนำสำหรับ Mobile Testing

KafkaLibrary

Event Streaming Testing
Kafka Event-Driven Async

Custom Library สำหรับทดสอบ Kafka Event Streaming ตรวจสอบ Publish, Consume และ Message Content ด้วย Wait Until Keyword สำหรับ Async Flow

✦ สำหรับ Event-Driven Architecture

DatabaseLibrary

Database Verification
MySQL PostgreSQL MongoDB

Library สำหรับเชื่อมต่อและ Query Database โดยตรง ใช้ Verify ว่าข้อมูล ถูก Insert/Update ถูกต้องหลัง API Call หรือ Business Flow ทำงานครบ

✦ สำหรับ Integration & E2E Verification
ความต้องการ Library ที่แนะนำ Test Layer
ทดสอบ Web UI (Modern) Browser Library (Playwright) E2E
ทดสอบ REST API RequestsLibrary Integration / API
ทดสอบ Mobile App AppiumLibrary E2E
ทดสอบ Kafka / Event KafkaLibrary (custom) Integration
Verify ข้อมูลใน DB DatabaseLibrary Integration
ทดสอบ Web UI (Legacy) SeleniumLibrary E2E

เขียน Test ให้ดูแลได้ระยะยาว

Test ที่ดีไม่ใช่แค่ผ่าน — แต่ต้องอ่านรู้เรื่อง แก้ได้ง่าย และเชื่อถือได้เมื่อ Fail

01

ตั้งชื่อ Test ให้อ่านแล้วเข้าใจทันที

ชื่อ Test Case คือ Documentation ที่มีชีวิต — เมื่อ Test Fail ชื่อที่ดีบอกทันทีว่าเกิดอะไร ใน Robot Framework เขียนชื่อเหมือนประโยค Requirement

Pattern: ควร [Action] เมื่อ [เงื่อนไข] → [ผลลัพธ์]
robot framework · test naming
# ❌ ชื่อที่ไม่ดี — ไม่รู้ว่าทดสอบอะไร
Test1
Login Test
TC_001

# ✅ ชื่อที่ดี — อ่านแล้วรู้ทันที
ควร Login สำเร็จเมื่อ Email และ Password ถูกต้อง
ควรแสดง Error เมื่อ Password ผิด
ควร Lock Account หลัง Login ผิด 5 ครั้งติดกัน
02

Test หนึ่งตัวทดสอบ Behavior เดียว

Test ที่ตรวจหลาย Behavior พร้อมกัน เมื่อ Fail จะรู้แค่ว่า "มีอะไรผิด" แต่ไม่รู้อะไร แยก Test ออกตาม Behavior ทำให้ Root Cause Analysis เร็วขึ้นและ Verify Result Phase มีความหมายชัดเจน

หลัก: Single Responsibility per Test Case
robot framework · single responsibility
# ❌ แบบที่ไม่ดี — ทดสอบหลาย Behavior ในตัวเดียว
# เมื่อ Fail จะรู้แค่ว่า "User Flow พัง" ไม่รู้ว่าพังตรงไหน
User Flow ทั้งหมด
    Login    user@test.com    secret
    ${profile}=    Get Profile
    Should Be Equal    ${profile}[name]    สมชาย
    Update Profile     name=สมหญิง
    Logout
    Element Should Be Visible    id=login-page

# ✅ แบบที่ดี — แยกแต่ละ Behavior ออกจากกัน
# Fail ที่ Test ไหน รู้ทันทีว่าพัง Behavior อะไร
ควร Login สำเร็จเมื่อ Credential ถูกต้อง
    ...
ควรแสดงชื่อ User ใน Profile หลัง Login
    ...
ควร Redirect กลับ Login Page หลัง Logout
    ...
03

ทำให้ Test เป็นอิสระต่อกัน

PreStep ที่ดีคือหัวใจของ Test Independence — แต่ละ Test สร้างและทำความสะอาด State ของตัวเองเสมอ อย่าให้ Test B อิง State ที่ Test A ทิ้งไว้ เพราะรันเดี่ยว Test B จะ Fail ทันที

ใช้ Test Setup: Reset And Seed Database ก่อนทุก Test
robot framework · test independence
*** Settings ***
Test Setup       Reset And Seed Database
Test Teardown    Clean Up Test Data

*** Keywords ***
Reset And Seed Database
    Delete All Users
    Insert User    email=user@test.com    password=hashed123

# ✅ ทุก Test เริ่มต้นจากสถานะเดิมเสมอ
# รันทีละ Test หรือรันทั้งหมดก็ได้ผลเหมือนกัน
04

หลีกเลี่ยง Flaky Test ด้วย Event-Driven Wait

Flaky Test เกิดจาก Main Execute Phase ที่มี Timing Dependency — แทน Sleep 3s ให้ใช้ Wait Until ที่ Framework มีให้ Framework จะรอจนเงื่อนไขพร้อมเองโดยอัตโนมัติ

❌ Sleep 3s → ✅ Wait Until Element Is Visible timeout=10s
robot framework · flaky test fix
# ❌ แบบที่ทำให้ Flaky — ขึ้นกับ network speed
Click Element    id=btn-submit
Sleep            3s
Element Should Be Visible    id=success-msg

# ✅ แบบที่ถูกต้อง — รอจน element พร้อมเอง
Click Element                id=btn-submit
Wait Until Element Is Visible    id=success-msg    timeout=10s

# ✅ API — รอจน status เปลี่ยน
Wait Until Keyword Succeeds    10x    1s    Verify Order Status    COMPLETED
05

รัน Test ใน CI/CD ทุก Pull Request

Test ที่รันแค่บนเครื่อง Dev ไม่ให้ความมั่นใจเพียงพอ CI/CD Pipeline คือ PreStep ระดับ Organization — รันใน Environment สะอาดทุกครั้ง ตรวจจับ Regression ก่อนถึง Production

robot tests/ ใน GitHub Actions ทุก push และ pull_request
github actions · .github/workflows/test.yml
name: Robot Framework Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        run: pip install robotframework robotframework-requests
      - name: Run tests
        run: robot --outputdir results tests/
      - name: Upload report
        uses: actions/upload-artifact@v4
        with:
          name: robot-report
          path: results/
Do vs Don't
✓ Do
  • ตั้งชื่อ Test เป็นประโยคอ่านรู้เรื่อง
  • ใช้ Test Setup / Teardown ทำความสะอาด State
  • ใช้ Wait Until แทน Sleep
  • Mock External Service ที่ไม่เสถียร
  • รัน Test ใน CI/CD ทุก Pull Request
  • อัปเดต Test เมื่อ Requirement เปลี่ยน
✗ Don't
  • ตั้งชื่อ Test1, TestLogin, TestAll
  • แชร์ State หรือ Data ระหว่าง Test
  • ใช้ Sleep แบบ Hardcode
  • ทดสอบหลาย Behavior ในตัวเดียว
  • ปล่อย Flaky Test ค้างไว้โดยไม่แก้
  • Skip Test แทนที่จะ Fix Root Cause

Robot Framework ตัวอย่างจริง

ตัวอย่าง Code ที่ใช้งานได้จริงพร้อม Comment ชี้ให้เห็น 4 Phase ในแต่ละ Test

robot framework · api test
*** Settings ***
Library    RequestsLibrary
Library    Collections

*** Variables ***
${BASE_URL}    https://api.example.com
${TOKEN}      Bearer test-token-123

*** Test Cases ***
ควร Login สำเร็จเมื่อ Credential ถูกต้อง
    # ── PreStep ────────────────────────────────────────
    Create Session    myapi    ${BASE_URL}    verify=True

    # ── Main Execute ───────────────────────────────────
    ${resp}=    POST On Session    myapi    /auth/login
    ...    json={"email": "user@example.com", "password": "secret"}

    # ── Verify Result ──────────────────────────────────
    Should Be Equal As Integers    ${resp.status_code}    200
    ${body}=    Set Variable    ${resp.json()}
    Should Not Be Empty    ${body}[token]
    Should Be Equal    ${body}[status]    "success"

    # ── PostStep ───────────────────────────────────────
    Delete All Sessions

ควรได้รับ 401 เมื่อ Password ผิด
    Create Session    myapi    ${BASE_URL}
    ${resp}=    POST On Session    myapi    /auth/login
    ...    json={"email": "user@example.com", "password": "wrong"}
    ...    expected_status=401
    ${body}=    Set Variable    ${resp.json()}
    Should Be Equal    ${body}[error]    "invalid_credentials"
    [Teardown]    Delete All Sessions
robot framework · web e2e (browser library)
*** Settings ***
Library    Browser
Suite Setup      Open Browser And Navigate
Suite Teardown   Close Browser

*** Variables ***
${BASE_URL}    https://app.example.com

*** Test Cases ***
ควร Login สำเร็จและ Redirect ไป Dashboard
    # ── PreStep ────────────────────────────────────────
    New Page    ${BASE_URL}/login

    # ── Main Execute ───────────────────────────────────
    Fill Text    id=email       user@example.com
    Fill Text    id=password    secret123
    Click        id=login-btn

    # ── Verify Result ──────────────────────────────────
    Wait For Navigation
    Get Url    ==    ${BASE_URL}/dashboard
    Get Text    h1    ==    ยินดีต้อนรับ

    # ── PostStep ───────────────────────────────────────
    [Teardown]    Close Page

ควรแสดง Error เมื่อ Password ผิด
    New Page    ${BASE_URL}/login
    Fill Text    id=email       user@example.com
    Fill Text    id=password    wrong-password
    Click        id=login-btn
    Wait For Elements State    .error-msg    visible    timeout=5s
    Get Text    .error-msg    ==    Email หรือ Password ไม่ถูกต้อง
    [Teardown]    Close Page

*** Keywords ***
Open Browser And Navigate
    New Browser    chromium    headless=False
    New Context    viewport={width: 1280, height: 720}
robot framework · mobile (appiumlibrary)
*** Settings ***
Library    AppiumLibrary

*** Variables ***
${REMOTE_URL}    http://localhost:4723/wd/hub
&{CAPS}
...    platformName=Android
...    deviceName=emulator-5554
...    appPackage=com.example.app
...    appActivity=.MainActivity
...    automationName=UiAutomator2

*** Test Cases ***
ควรเพิ่มสินค้าลงตะกร้าได้สำเร็จ
    # ── PreStep ────────────────────────────────────────
    Open Application    ${REMOTE_URL}    &{CAPS}
    Login To App    user@example.com    secret

    # ── Main Execute ───────────────────────────────────
    Click Element    id=product-001
    Click Element    id=add-to-cart-btn

    # ── Verify Result ──────────────────────────────────
    Wait Until Element Is Visible    id=cart-badge    timeout=5s
    Element Text Should Be    id=cart-count    1
    Element Should Be Visible    id=cart-success-toast

    # ── PostStep ───────────────────────────────────────
    [Teardown]    Close Application

*** Keywords ***
Login To App
    [Arguments]    ${email}    ${password}
    Input Text    id=email-input     ${email}
    Input Text    id=pass-input      ${password}
    Click Element    id=login-button
    Wait Until Element Is Visible    id=home-screen    timeout=10s
robot framework · kafka event test
*** Settings ***
Library    KafkaLibrary
Library    RequestsLibrary
Library    Collections

*** Variables ***
${KAFKA_BROKER}    localhost:9092
${API_URL}        http://localhost:8080
${TOPIC}          order.created

*** Test Cases ***
ควร Publish order.created Event เมื่อสร้าง Order สำเร็จ
    # ── PreStep ────────────────────────────────────────
    Connect Kafka Consumer    ${KAFKA_BROKER}    ${TOPIC}
    Create Session    api    ${API_URL}

    # ── Main Execute ───────────────────────────────────
    ${resp}=    POST On Session    api    /orders
    ...    json={"product_id": "P001", "quantity": 2}
    ${order_id}=    Set Variable    ${resp.json()}[order_id]

    # ── Verify Result ──────────────────────────────────
    Should Be Equal As Integers    ${resp.status_code}    201
    ${event}=    Wait Until Kafka Message    topic=${TOPIC}
    ...    key=${order_id}    timeout=10s
    Should Be Equal    ${event}[event_type]    order.created
    Should Be Equal    ${event}[product_id]    P001

    # ── PostStep ───────────────────────────────────────
    [Teardown]    Run Keywords
    ...    Delete Order Via API    ${order_id}
    ...    AND    Disconnect Kafka Consumer
    ...    AND    Delete All Sessions

*** Keywords ***
Delete Order Via API
    [Arguments]    ${order_id}
    DELETE On Session    api    /orders/${order_id}

Locator Strategy

วิธีระบุ Element ที่ถูกต้องคือหัวใจของ Web & Mobile Test — เลือก Locator ที่เสถียรทำให้ Test ไม่พังเมื่อ UI เปลี่ยน

ID
✦ ดีที่สุด
ใช้ attribute id ของ element — เร็วที่สุด เสถียรที่สุด ควรใช้ก่อนเสมอถ้า Dev ใส่ id ไว้
✅ ใช้เมื่อ: element มี id ที่ unique และไม่ dynamic
robot framework · id locator
# ใช้ id= prefix
Click Element    id=btn-login
Input Text       id=username    admin@test.com
Element Should Be Visible    id=success-msg
data-testid
✦ ดีที่สุด
Attribute พิเศษที่ Dev ใส่ไว้เพื่อ Testing โดยเฉพาะ ไม่ถูกกระทบเมื่อ เปลี่ยน class หรือ style — เป็น Best Practice สมัยใหม่
✅ ใช้เมื่อ: ทีมตกลงกันว่าจะใส่ data-testid ใน Codebase
robot framework · data-testid locator
# ใช้ css= กับ attribute selector
Click Element    css=[data-testid="btn-submit"]
Input Text       css=[data-testid="input-email"]    user@test.com
Element Should Be Visible    css=[data-testid="error-msg"]
CSS Selector
✧ ดี
ยืดหยุ่นสูง อ่านง่ายกว่า XPath เหมาะสำหรับ element ที่ไม่มี id รองรับ class, attribute, pseudo-selector และ combinator
✅ ใช้เมื่อ: ไม่มี id แต่มี class หรือ attribute ที่ unique
robot framework · css selector
# by class
Click Element    css=button.btn-primary

# by attribute
Input Text       css=input[type="email"]    user@test.com

# child combinator
Click Element    css=#form-login > button[type="submit"]

# nth-child
Click Element    css=.product-list .card:nth-child(2)
XPath
⚠ ระวัง
มีพลังสูงสุด — traverse ขึ้น Parent, หา Sibling, ค้นด้วย text ได้ แต่ XPath แบบ Absolute เปราะมาก ใช้เฉพาะเมื่อจำเป็นจริงๆ
⚠ หลีกเลี่ยง: /html/body/div[3]/... — พัง ทันทีที่ UI เปลี่ยน
robot framework · xpath (relative เท่านั้น)
# ✅ relative xpath — ค้นด้วย attribute
Click Element    xpath=//button[@id="btn-login"]
Click Element    xpath=//button[contains(text(),"Login")]

# ✅ traverse — หา input ที่อยู่ถัด label
Input Text    xpath=//label[text()="Email"]/following-sibling::input    user@test.com

# ✅ nth element
Click Element    xpath=(//div[@class="card"])[2]

# ❌ absolute xpath — อย่าใช้
# xpath=/html/body/div/main/div[3]/form/button
Accessibility ID
✦ ดีที่สุด
ใช้ได้ทั้ง iOS และ Android — เทียบเท่า id ของ Web Android ใช้ content-desc / iOS ใช้ accessibilityIdentifier ควรขอให้ Dev ใส่ไว้เสมอ
✅ ใช้เมื่อ: Dev ตั้ง Accessibility label ให้ element
robot framework · appium · accessibility id
# ใช้ได้ทั้ง iOS และ Android
Click Element    accessibility_id=login-button
Input Text       accessibility_id=email-field    user@test.com
Input Text       accessibility_id=password-field    secret123
Click Element    accessibility_id=submit-btn
Resource ID (Android)
✧ ดี
ใช้ resource-id ของ Android — รูปแบบ com.package.name:id/element_id ดู resource-id ได้จาก Android Studio หรือ uiautomatorviewer
✅ ใช้เมื่อ: ทดสอบ Android และรู้ package name ของ app
robot framework · appium · android resource-id
# Android resource-id
Click Element    id=com.myapp.android:id/btn_login
Input Text       id=com.myapp.android:id/et_email    user@test.com

# UiAutomator2 — ค้นด้วย text
Click Element    android=new UiSelector().text("เข้าสู่ระบบ")
Click Element    android=new UiSelector().textContains("Login")
Predicate String (iOS)
✧ ดี
iOS-only — ค้นหา element ด้วย attribute เช่น label, name, value อ่านง่าย เสถียรกว่า XPath สำหรับ iOS
✅ ใช้เมื่อ: ทดสอบ iOS และต้องการค้นด้วย label หรือ type
robot framework · appium · ios predicate string
# iOS Predicate String
Click Element    predicate string=label == "Login"
Click Element    predicate string=name == "btn_submit"
Click Element    predicate string=type == "XCUIElementTypeButton" AND label CONTAINS "Login"

# Class Chain — traverse แบบ iOS XPath
Click Element    chain=**/XCUIElementTypeButton[`label == "Login"`]
XPath (Mobile)
⚠ ระวัง
ใช้ได้ทั้ง iOS และ Android แต่ช้ากว่า locator ประเภทอื่นมาก เพราะต้อง scan tree ทั้งหมด — ใช้เป็น last resort เท่านั้น
⚠ ใช้เมื่อ: ไม่มีทางเลือกอื่น เช่น element ไม่มี accessibility label
robot framework · appium · xpath mobile
# Android XPath
Click Element    xpath=//android.widget.Button[@text="Login"]
Click Element    xpath=//android.widget.EditText[@resource-id="et_email"]

# iOS XPath
Click Element    xpath=//XCUIElementTypeButton[@label="Login"]

# ❌ Absolute xpath บน Mobile ช้ามาก อย่าใช้
# xpath=//hierarchy/android.widget.FrameLayout/...

คำศัพท์ที่ควรรู้

คำศัพท์หลักใน Automated Testing, Robot Framework, Locator Strategy และ HTTP

Test Case
หน่วยของการทดสอบที่ระบุเงื่อนไข การกระทำ และผลลัพธ์ที่คาดหวังไว้อย่างชัดเจน
Robot Framework
Keyword
ฟังก์ชันใน Robot Framework ที่สร้างจาก Python หรือ Keyword อื่นๆ ใช้เป็น Building Block ของ Test
Robot Framework
Test Suite
กลุ่มของ Test Case ที่จัดอยู่ในไฟล์หรือ Directory เดียวกัน มี Suite Setup/Teardown ร่วมกันได้
Robot Framework
Mock / Stub
การจำลอง External Dependency เช่น API หรือ Database เพื่อให้ Unit Test รันเร็วและเสถียร
Unit Testing
Assertion
การตรวจสอบว่าผลลัพธ์จริงตรงกับสิ่งที่คาดหวัง ถ้าไม่ตรงจะทำให้ Test Fail ทันที
Testing Concept
Test Fixture
สภาพแวดล้อมและข้อมูลที่เตรียมไว้สำหรับ Test ใน PreStep เพื่อให้ Test ทำงานได้อย่างถูกต้อง
Testing Concept
Regression Test
การทดสอบเพื่อยืนยันว่าการเปลี่ยนแปลง Code ใหม่ไม่ทำให้ Feature เดิมพังหรือเปลี่ยนพฤติกรรม
Testing Strategy
Flaky Test
Test ที่ผลลัพธ์ไม่แน่นอน Pass บ้าง Fail บ้าง โดยไม่มีการเปลี่ยนแปลง Code มักเกิดจาก Timing
Anti-Pattern
CI/CD Pipeline
ระบบอัตโนมัติที่รัน Test, Build และ Deploy ทุกครั้งที่มีการเปลี่ยนแปลง Code
DevOps
Test Coverage
เปอร์เซ็นต์ของ Code ที่ถูก Test ครอบคลุม เป้าหมายที่ดีคือ 80%+ สำหรับ Business Logic
Metrics
Headless Browser
Browser ที่ทำงานโดยไม่แสดง UI ใช้ใน CI/CD เพื่อรัน Web E2E Test บน Server
Web Testing
Test Data Management
การจัดการข้อมูลที่ใช้ใน Test ให้ Isolated, Reproducible และไม่กระทบ Production
Testing Concept
Locator
วิธีระบุ Element บน UI ที่ต้องการ Interact เช่น id, CSS Selector, XPath ใช้ใน Web และ Mobile Test
Locator Strategy
XPath
ภาษา Query สำหรับนำทางใน XML/HTML Document ใช้หา Element ได้ยืดหยุ่นสูง แต่ช้าและเปราะถ้าใช้แบบ Absolute
Locator Strategy
CSS Selector
รูปแบบการเลือก Element ด้วย class, id, attribute หรือ combinator อ่านง่ายกว่า XPath เหมาะสำหรับ Web Test
Locator Strategy
Accessibility ID
Locator มาตรฐานสำหรับ Mobile (Appium) ใช้ได้ทั้ง iOS และ Android เสถียรที่สุดสำหรับ Mobile Test
Locator Strategy
data-testid
Custom HTML attribute ที่ Dev ใส่ไว้เพื่อ Testing โดยเฉพาะ ไม่ถูกกระทบเมื่อเปลี่ยน class หรือ style
Locator Strategy