Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

JMeter — Recording với HTTP(S) Test Script Recorder

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn được giao nhiệm vụ load test cho luồng đặt hàng của một sàn thương mại điện tử: người dùng vào trang chủ, tìm kiếm sản phẩm, xem chi tiết, thêm vào giỏ, đăng nhập, nhập địa chỉ, chọn phương thức thanh toán, rồi bấm "Đặt hàng". Nếu bạn ngồi dựng từng HTTP Request thủ công trong JMeter, bạn sẽ phải mở DevTools của trình duyệt, soi từng request, copy URL, copy header, copy body, dán vào từng Sampler... Một luồng như trên có thể sinh ra 40–60 request (bao gồm cả API gọi ngầm, tracking, ảnh, JS). Làm tay vừa lâu vừa dễ sót, và chỉ cần frontend đổi một endpoint là bạn phải dò lại từ đầu.

Đây chính là lúc HTTP(S) Test Script Recorder cứu bạn. Recorder biến JMeter thành một proxy trung gian: bạn cho trình duyệt (hoặc app mobile) đi qua proxy này, thao tác đúng luồng nghiệp vụ như một người dùng thật, và JMeter tự động ghi lại toàn bộ request thành các Sampler sẵn sàng để chạy lại. Từ 30 phút cặm cụi copy-paste, bạn rút xuống còn 2 phút "diễn" luồng nghiệp vụ.

Ở các bài trước bạn đã biết cách tự tay dựng Thread Group, Sampler, Listener (Bài 8), dùng Variables và Extractor (Bài 9). Bài này tập trung riêng vào kỹ thuật recording — cách bắt request tự động, và quan trọng hơn: cách "dọn dẹp" bản ghi thô thành một test script sạch, đáng tin cậy. Vì recording không phải phép màu — nó cho bạn nguyên liệu thô, còn biến nó thành script tốt vẫn là kỹ năng của bạn.

Khái niệm cốt lõi

Recorder hoạt động như thế nào

HTTP(S) Test Script Recorder là một proxy server chạy bên trong JMeter, mặc định lắng nghe ở cổng 8888. Cơ chế rất đơn giản:

  • Bạn cấu hình trình duyệt trỏ proxy về localhost:8888.
  • Mọi request trình duyệt gửi đi sẽ đi qua JMeter trước.
  • JMeter ghi lại request đó thành một HTTP Request Sampler, rồi chuyển tiếp đến server thật và trả kết quả về cho trình duyệt.
Vì đứng ở giữa, JMeter thấy được toàn bộ nội dung request: method, URL, query string, header, body. Với HTTPS, vì lưu lượng được mã hóa, JMeter phải "giả danh" server bằng một certificate tự ký (file ApacheJMeterTemporaryRootCA.crt do JMeter sinh ra). Đây là kiểu man-in-the-middle hợp pháp — bạn tự bắt lưu lượng của chính mình, không phải của người khác.

Ba thành phần bạn sẽ đụng tới

  • HTTP(S) Test Script Recorder (Non-Test Element): bản thân proxy. Nơi bạn bấm Start/Stop và cấu hình cổng, bộ lọc.
  • Recording Controller: nơi chứa các Sampler được ghi. Bạn đặt nó bên trong Thread Group để các request ghi được rơi đúng chỗ, sẵn sàng chạy trong test.
  • Bộ lọc (Include/Exclude patterns): dùng regex để loại bỏ request "rác" — ảnh, font, CSS, JS, request tracking — chỉ giữ lại API và trang HTML mà bạn thực sự quan tâm.

Recording không thay thế được tư duy test

Một hiểu lầm phổ biến: "cứ record là xong". Không. Bản ghi thô có ba vấn đề cố hữu mà bạn bắt buộc phải xử lý:

  • Dữ liệu cứng (hardcoded values): session token, CSRF token, product ID, order ID... đều bị ghi cố định theo lần bạn diễn. Chạy lại lần sau với token cũ là fail. Bạn phải thay bằng biến động, dùng Extractor (Bài 9) để bắt token từ response trước và tiêm vào request sau.
  • Nhiễu (noise): hàng chục request tài nguyên tĩnh, analytics (Google Analytics, Facebook Pixel), chat widget... không phản ánh tải lên backend của bạn.
  • Thiếu tính tham số hóa: mọi virtual user sẽ tìm cùng một từ khóa, mua cùng một sản phẩm. Bạn cần CSV Data Set để mỗi user hành xử khác nhau (Bài 9).
Nói cách khác: recording lo phần "bắt đúng request", còn bạn lo phần "làm cho nó chạy được ở quy mô".

Tình huống thực tế

Tình huống 1 — Tiki và luồng checkout 52 request

Một team QA giả định tại Tiki cần load test luồng mua hàng dịp sale. Ban đầu bạn (kỹ sư mới) định dựng tay. Sau khi dựng được 8 Sampler trong 40 phút, bạn nhận ra luồng checkout thật gọi tới 52 request, gồm nhiều API GraphQL ẩn mà DevTools phải xem kỹ mới thấy.

Bạn chuyển sang Recorder. Cấu hình proxy, bật recording, rồi mở trình duyệt "diễn" đúng luồng: trang chủ → tìm "tai nghe" → click sản phẩm → thêm giỏ → đăng nhập → thanh toán COD. Trong 90 giây, JMeter ghi được đủ 52 request. Nhưng khi chạy lại 100 user, toàn bộ fail ở bước "thêm giỏ".

Diễn giải: Nguyên nhân là API thêm giỏ yêu cầu một x-csrf-token được trả về từ response của trang sản phẩm. Bản ghi giữ token cứng của lần bạn diễn — token đó hết hạn sau vài phút. Bạn thêm một Regular Expression Extractor ở Sampler trang sản phẩm để bắt token, lưu vào biến ${csrfToken}, rồi sửa header của Sampler thêm giỏ để dùng biến này. Sau đó test chạy thông.

Bài học: Recorder tiết kiệm cho bạn công bắt request, nhưng token động luôn là "cạm bẫy số một". Ghi xong việc đầu tiên phải làm là rà mọi giá trị nghi ngờ là session/CSRF/nonce.

Tình huống 2 — Ngân hàng số và cơn ác mộng HTTPS + noise

Một fintech ở TP.HCM cần test cổng đăng nhập Internet Banking (HTTPS hoàn toàn). Kỹ sư bật Recorder nhưng trình duyệt báo "Kết nối không an toàn" và không có gì được ghi. Lý do: chưa cài certificate của JMeter vào trình duyệt, nên trình duyệt từ chối cho JMeter giải mã HTTPS.

Sau khi import file ApacheJMeterTemporaryRootCA.crt vào trust store, recording chạy được — nhưng Recording Controller phình lên hơn 300 Sampler cho một lần đăng nhập, vì trang tải đầy font, icon, ảnh banner, và ba loại tracking script.

Diễn giải: Kỹ sư dùng bộ lọc URL Patterns to Exclude với regex .\.(bmp|css|js|gif|ico|jpe?g|png|svg|swf|woff2?|ttf|eot), đồng thời exclude thêm .google-analytics..facebook.*. Kết quả rớt xuống còn 11 Sampler thực sự có ý nghĩa: các API xác thực, sinh OTP, verify. Test giờ vừa nhẹ vừa phản ánh đúng tải lên hệ thống core.

Bài học: Với HTTPS luôn nhớ hai việc — cài certificate trước, và lọc noise ngay khi ghi bằng exclude patterns. Đừng để 96% Sampler của bạn là ảnh và font.

Tình huống 3 — Grab và recording app mobile

Team performance của một ứng dụng gọi xe (giả định kiểu Grab) cần test API đặt chuyến từ app Android, không phải web. Không có DevTools cho app, dựng tay gần như bất khả thi vì họ không biết chính xác app gọi endpoint nào.

Diễn giải: Họ dùng Recorder như một proxy mạng: cấu hình Wi-Fi trên điện thoại trỏ proxy về IP máy chạy JMeter, cổng 8888, và cài certificate JMeter lên điện thoại. Sau đó thao tác đặt chuyến ngay trên app. JMeter ghi lại toàn bộ REST API mà app gọi ngầm — kể cả những endpoint nội bộ không hề công bố tài liệu. Từ đó họ dựng được kịch bản test cho luồng đặt xe mà trước đó tưởng không thể chạm tới.

Bài học: Recorder không chỉ dành cho web. Bất cứ client nào cho phép cấu hình proxy — app mobile, desktop app, thiết bị IoT — đều có thể "soi" được. Đây là cách nhanh nhất để khám phá API ẩn của một hệ thống bạn không có tài liệu.

Hướng dẫn từng bước

Bước 1 — Tạo Recorder và Recording Controller

  • Chuột phải vào Test Plan → Add → Non-Test Elements → HTTP(S) Test Script Recorder.
  • Trong Thread Group, chuột phải Add → Logic Controller → Recording Controller. Đây là nơi các Sampler ghi được sẽ rơi vào.
  • Ở Recorder, mục Target Controller, chọn đúng Recording Controller vừa tạo (dạng Test Plan > Thread Group > Recording Controller). Nếu để "Use Recording Controller", JMeter sẽ tự tìm controller đầu tiên tên như vậy.

Bước 2 — Cấu hình cổng và HTTP Sampler settings

  • Xác nhận Port = 8888 (đổi nếu cổng đang bận).
  • Ở tab HTTP Sampler settings, đặt Type: HTTPS Java hoặc để mặc định. Bật "Add assertions" nếu muốn tự thêm Response Assertion. Đặt "Naming scheme" dạng "Transaction name" để Sampler có tên dễ đọc thay vì chuỗi số khó hiểu.

Bước 3 — Đặt bộ lọc để cắt noise ngay từ đầu

Trong tab Requests Filtering, thêm vào URL Patterns to Exclude một dòng regex:

.\.(bmp|css|js|gif|ico|jpe?g|png|svg|swf|woff2?|ttf|eot|otf|map)(\?.)?

Thêm dòng riêng cho tracking nếu cần: .(google-analytics|googletagmanager|facebook|hotjar|gtm).. Lọc lúc ghi luôn tốt hơn xóa tay sau này.

Bước 4 — Cấu hình proxy trên trình duyệt

Cách sạch nhất là dùng một profile trình duyệt riêng hoặc extension như FoxyProxy, trỏ HTTP và HTTPS proxy về localhost:8888. Đừng đổi proxy toàn hệ điều hành nếu tránh được, vì sẽ bắt luôn lưu lượng của mọi app khác gây nhiễu.

Bước 5 — Cài certificate cho HTTPS

  • Bấm Start ở Recorder một lần để JMeter sinh file ApacheJMeterTemporaryRootCA.crt trong thư mục bin.
  • Import certificate này vào trust store của trình duyệt (hoặc hệ điều hành / thiết bị mobile) dưới dạng "Trusted Root Certification Authority".
  • Lưu ý: certificate này chỉ có hiệu lực 7 ngày, hết hạn thì xóa file cũ và để JMeter sinh lại.

Bước 6 — Ghi luồng nghiệp vụ

  • Bấm Start. JMeter hiện popup Recorder (dùng nút "Transaction name" để đặt tên nhóm request cho từng bước, ví dụ "01_TrangChu", "02_TimKiem").
  • Thao tác trên trình duyệt đúng luồng người dùng thật, chậm rãi và đúng thứ tự. Sau mỗi hành động, đổi Transaction name trước khi làm bước tiếp theo.
  • Bấm Stop khi xong.

Bước 7 — Dọn dẹp bản ghi

  • Xóa các Sampler rác còn sót (favicon, request thừa).
  • Thêm Extractor để bắt token/ID động và thay các giá trị hardcode bằng biến.
  • Thêm HTTP Cookie ManagerHTTP Cache Manager để mô phỏng trình duyệt thật.
  • Thêm CSV Data Set để tham số hóa dữ liệu (username, từ khóa, sản phẩm).
  • Chạy thử 1 user, xem Listener "View Results Tree" để chắc mọi Sampler trả 200 trước khi tăng tải.

Lỗi thường gặp & mẹo

  • Không ghi được request HTTPS, trình duyệt báo lỗi bảo mật. Bạn chưa cài certificate của JMeter, hoặc dùng certificate đã hết hạn (quá 7 ngày). Xóa file .crt cũ trong bin, Start lại để sinh mới, rồi import lại.
  • Chrome/Firefox đời mới bỏ qua proxy hoặc dùng QUIC/HTTP3. Một số request đi qua giao thức HTTP/3 (UDP) mà JMeter proxy không bắt được. Tắt QUIC trong cấu hình trình duyệt, hoặc dùng profile riêng buộc đi HTTP/1.1–HTTP/2.
  • Recording Controller trống trơn dù đã thao tác. Kiểm tra Target Controller có trỏ đúng không, và cổng proxy trình duyệt có khớp cổng Recorder (8888) không. Có khi bạn đang chạy hai Recorder cùng lúc tranh cổng.
  • Chạy lại 1 user thì OK, chạy nhiều user thì fail hàng loạt. Gần như chắc chắn do token/session cứng. Dùng Extractor để làm động chúng — đây là phản xạ bắt buộc sau mỗi lần record.
  • Sampler có tên khó đọc kiểu /api/v2/xhr?_=163.... Dùng "Transaction name" trong lúc ghi để nhóm và đặt tên bước có nghĩa. Test dễ đọc là test dễ bảo trì.
  • Mẹo dùng Transaction Controller: sau khi ghi, gom các Sampler cùng một bước nghiệp vụ vào Transaction Controller để đo thời gian của cả bước "Đăng nhập" như một đơn vị, sát với trải nghiệm người dùng hơn.
  • Mẹo tránh nhiễu app khác: luôn dùng profile trình duyệt riêng cho việc recording, đừng bật proxy toàn hệ thống — nếu không bạn sẽ ghi luôn cả request của Slack, mail, cập nhật phần mềm nền.

Bài tập thực hành

  • Ghi luồng cơ bản: Tạo Recorder + Recording Controller. Cấu hình proxy trình duyệt và ghi lại luồng: mở một trang tin tức bất kỳ → tìm kiếm một từ khóa → mở một bài viết. Đếm số Sampler ghi được.
  • Cắt noise: Thêm exclude pattern cho tài nguyên tĩnh và tracking. Ghi lại luồng đó lần nữa và so sánh số Sampler trước/sau khi lọc. Ghi lại tỉ lệ giảm.
  • Xử lý HTTPS + token động: Chọn một site có đăng nhập (dùng tài khoản test của chính bạn). Cài certificate, ghi luồng đăng nhập, rồi tìm và làm động ít nhất một token/CSRF bằng Regular Expression Extractor. Chạy lại 1 user và xác nhận đăng nhập thành công.
  • Đặt tên & gom nhóm: Dùng Transaction name để đặt tên các bước có nghĩa, sau đó gom Sampler vào Transaction Controller theo từng bước nghiệp vụ. Chạy và quan sát thời gian từng transaction trong View Results Tree.

Tóm tắt

HTTP(S) Test Script Recorder giúp bạn "diễn" một luồng nghiệp vụ trên trình duyệt hoặc app và để JMeter tự động ghi lại thành các HTTP Request Sampler — nhanh hơn nhiều so với dựng tay, đặc biệt với các luồng dài và các API ẩn không có tài liệu. Về bản chất, Recorder là một proxy đứng giữa; với HTTPS bạn phải cài certificate tự ký của JMeter để nó giải mã được lưu lượng của chính bạn.

Nhưng bản ghi thô chỉ là nguyên liệu: bạn phải cắt noise bằng exclude patterns, làm động các token/session/CSRF bằng Extractor, thêm Cookie/Cache Manager, và tham số hóa dữ liệu bằng CSV. Ba tình huống Tiki, ngân hàng số và app gọi xe cho thấy cùng một bài học: Recorder cho bạn tốc độ, nhưng chất lượng script vẫn đến từ khâu dọn dẹp. Ghi xong đừng vội tăng tải — chạy thử 1 user, xác nhận mọi Sampler xanh, rồi mới nghĩ tới hàng nghìn virtual user.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi