Mở đầu — vì sao bài này quan trọng
Cho tới lúc này, bạn đã làm chủ Postman như một công cụ giao diện (UI): mở app lên, click "Send", nhìn response, viết vài dòng test trong tab Tests rồi bấm chạy. Nhưng có một sự thật phũ phàng mà mọi QA engineer sớm muộn cũng gặp: giao diện Postman không tồn tại trên server CI/CD. Trên một máy chủ Jenkins ở data center, hay một runner GitHub Actions chạy trong container Ubuntu, không có màn hình, không có chuột, không ai ngồi đó bấm "Send". Vậy làm sao để bộ 200 test API của bạn tự động chạy mỗi khi lập trình viên push code?
Câu trả lời là Newman — chính là Postman, nhưng ở dạng dòng lệnh (command line).
Hãy hình dung thế này. Đội QA của một công ty fintech ở Quận 1, TP.HCM đã bỏ ra ba tuần xây dựng một collection Postman gồm 150 request kiểm thử API thanh toán. Nhưng mỗi lần backend deploy phiên bản mới, một bạn QA phải mở Postman, chọn collection, chọn environment staging, bấm Run Collection, rồi ngồi chờ 4 phút, chụp màn hình kết quả gửi vào group. Ngày deploy 5 lần thì bạn ấy mất gần nửa buổi chỉ để "bấm nút". Đây chính là kiểu công việc thủ công mà tự động hóa sinh ra để xóa bỏ. Newman biến toàn bộ quy trình đó thành đúng một dòng lệnh — và dòng lệnh thì máy tính chạy được, lặp lại được, đưa vào pipeline được.
Bài học này tập trung hẹp và sâu vào Newman như một công cụ dòng lệnh độc lập: cài đặt, chạy collection, truyền tham số, đọc kết quả và điều khiển hành vi của nó. Chúng ta chưa đụng tới việc nhúng Newman vào Jenkins hay GitHub Actions (đó là chuyện của các bài sau), cũng chưa bàn sâu về reporter đẹp mắt hay Docker. Ở đây, mục tiêu là bạn gõ được lệnh Newman một cách tự tin, hiểu từng option nghĩa là gì, và biết nhìn vào output để phán đoán "pass hay fail".
Khái niệm cốt lõi
Newman là gì
Newman là một command-line runner cho Postman collection, được viết bằng Node.js và phân phối qua npm. Điểm mấu chốt cần nắm: Newman dùng chung engine chạy request và chạy script với Postman app. Nghĩa là mọi pm.test(...), pm.expect(...), pre-request script, biến environment... mà bạn viết trong Postman sẽ chạy y hệt khi được Newman thực thi. Bạn không phải viết lại test bằng ngôn ngữ khác. Đây là lời hứa quan trọng nhất của Newman: "cái gì chạy được trong Postman thì chạy được ngoài command line".
Tên "Newman" là một câu đùa nội bộ của Postman — Newman là nhân vật đối thủ trong sitcom Seinfeld, và "Postman" (người đưa thư) gặp "Newman"... nhưng bạn không cần nhớ điều đó để dùng công cụ.
Cài đặt Newman
Newman là một package Node.js, nên điều kiện tiên quyết là máy bạn phải có Node.js (kèm theo npm). Bạn kiểm tra bằng:
node --version # nên là v18 trở lên
npm --version
Sau đó cài Newman toàn cục (global) để dùng ở bất kỳ thư mục nào:
npm install -g newman
newman --version # kỳ vọng ra 6.x
Cờ -g (global) khiến newman trở thành một lệnh chạy được ở mọi nơi trong terminal. Trên môi trường CI, người ta thường không cài global mà cài cục bộ trong project (npm install newman --save-dev) rồi gọi qua npx newman, để khóa cứng phiên bản — nhưng để học và chạy tay trên máy mình, cài global là nhanh gọn nhất.
Xuất collection để Newman đọc được
Newman không "nhìn thấy" collection đang mở trong Postman app. Nó đọc một file JSON — chính là định dạng collection của Postman. Có hai cách để Newman lấy collection:
- Export ra file: Trong Postman, chuột phải vào collection → Export → chọn định dạng Collection v2.1 → lưu thành file, ví dụ
payment-api.postman_collection.json. - Dùng URL public/API link: Nếu collection được lưu trên Postman cloud, bạn có thể truyền thẳng một URL. Nhưng cách này phụ thuộc mạng và quyền truy cập, nên trong CI người ta ưu tiên file JSON được commit vào repo.
staging.postman_environment.json.Lệnh chạy cơ bản
Cú pháp nền tảng bạn sẽ gõ đi gõ lại:
newman run payment-api.postman_collection.json
Chỉ vậy thôi. Newman sẽ chạy tuần tự từng request trong collection, thực thi mọi test script, rồi in một bảng tóm tắt ra terminal. Nếu collection cần biến môi trường, bạn thêm cờ -e:
newman run payment-api.postman_collection.json \
-e staging.postman_environment.json
Exit code — trái tim của tự động hóa
Đây là khái niệm mà nhiều bạn mới bỏ qua nhưng lại quan trọng bậc nhất. Sau khi chạy xong, Newman trả về một exit code (mã thoát) cho hệ điều hành:
- Exit code 0 = tất cả test pass, không có request nào lỗi.
- Exit code khác 0 (thường là 1) = có ít nhất một test fail hoặc một request lỗi.
newman run payment-api.postman_collection.json; echo "Exit code: $?"
Biến $? trong shell chứa exit code của lệnh vừa chạy.
Các option thường dùng nhất
Newman có hàng chục cờ, nhưng bạn chỉ cần thuộc nằm lòng một nhóm nhỏ:
-e <file>— chỉ định environment.-g <file>— chỉ định globals (biến toàn cục).--env-var "key=value"— ghi đè hoặc thêm một biến ngay trên dòng lệnh, cực hữu ích để truyền secret mà không muốn ghi vào file.-n <số>— chạy collection lặp lại N lần (iterations).--timeout-request <ms>— timeout cho mỗi request, ví dụ--timeout-request 5000là 5 giây.--delay-request <ms>— chèn độ trễ giữa các request, hữu ích khi API có rate limit.--bail— dừng ngay lập tức khi gặp test fail đầu tiên, thay vì chạy hết.--reporters <tên>— chọn kiểu báo cáo (mặc định làcli).--folder <tên>— chỉ chạy một folder con trong collection thay vì toàn bộ.
Tình huống thực tế
Tình huống 1 — Đội QA fintech và cú "smoke test" 90 giây
Quay lại công ty fintech ở Quận 1. Sau khi biết đến Newman, bạn QA trưởng quyết định tách collection 150 request thành hai phần: một folder tên Smoke gồm 12 request kiểm tra các luồng sống còn (đăng nhập, tạo giao dịch, kiểm tra số dư), và phần còn lại là regression đầy đủ.
Mỗi lần backend báo "đã deploy staging", thay vì mở Postman, bạn ấy chỉ gõ:
newman run payment-api.postman_collection.json \
-e staging.postman_environment.json \
--folder "Smoke" \
--bail
Cờ --folder "Smoke" giới hạn chạy đúng 12 request quan trọng, --bail khiến Newman dừng ngay nếu request đầu tiên đã hỏng (không cần chờ hết). Kết quả: từ 4 phút chờ đợi thủ công xuống còn 90 giây và không cần rời khỏi terminal. Nếu exit code là 0, bạn ấy nhắn "smoke pass, tiếp tục regression"; nếu là 1, bạn ấy báo dev "có luồng chết, khoan test tiếp".
Bài học rút ra: Newman không phải "cứ chạy hết tất cả". Việc chia folder và dùng --folder cho phép bạn tạo ra nhiều "chế độ chạy" từ cùng một collection — smoke nhanh, regression đầy đủ — chỉ bằng cách đổi option.
Tình huống 2 — Truyền secret mà không lộ trong file
Một startup thương mại điện tử ở Hà Nội có API cần một API_KEY để xác thực. Ban đầu, bạn dev đưa thẳng key vào file environment JSON rồi commit lên Git — và một tuần sau, key đó bị lộ trong lịch sử commit công khai, phải xoay vòng lại toàn bộ. Một bài học đắt giá.
Giải pháp bằng Newman: không ghi secret vào file. File environment chỉ chứa biến rỗng API_KEY = "", còn giá trị thật được truyền lúc chạy qua --env-var:
newman run shop-api.postman_collection.json \
-e production.postman_environment.json \
--env-var "API_KEY=$SHOP_API_KEY"
Ở đây $SHOP_API_KEY là một biến môi trường của shell, được nạp từ nơi an toàn (secret manager của CI, hoặc file .env không commit). Newman nhận giá trị thật vào lúc chạy, còn trong repo tuyệt nhiên không có dấu vết của key.
Bài học rút ra: --env-var là cách chuẩn để đưa dữ liệu nhạy cảm hoặc dữ liệu thay đổi theo môi trường vào Newman mà không "đóng băng" chúng trong file. Đây là thói quen bảo mật tối thiểu mọi QA phải có.
Tình huống 3 — Chạy lặp để bắt lỗi "chập chờn"
Một đội API ở Đà Nẵng gặp hiện tượng khó chịu: có một endpoint tạo đơn hàng, cứ khoảng 20 lần gọi thì sai một lần (trả về 500), nghi ngờ do race condition trong tầng database. Chạy tay trong Postman thì hên xui, khó tái hiện.
Với Newman, họ dùng cờ -n để lặp và --delay-request để mô phỏng tần suất thực tế:
newman run order-api.postman_collection.json \
-e staging.postman_environment.json \
--folder "CreateOrder" \
-n 50 \
--delay-request 200
Lệnh này chạy folder tạo đơn 50 lần liên tiếp, cách nhau 200ms. Sau khi chạy, bảng tóm tắt của Newman hiện rõ: 50 request, 3 lần fail assertion "status là 201", kèm số iteration cụ thể bị hỏng. Đội dev có ngay bằng chứng tái hiện được để mở phiếu bug với backend.
Bài học rút ra: -n (iterations) biến Newman thành công cụ hữu hiệu để phát hiện lỗi không ổn định (flaky/intermittent) — thứ mà chạy tay một lần rất khó thấy. Con số lặp và output tóm tắt cho bạn dữ liệu định lượng thay vì cảm tính "hình như thỉnh thoảng lỗi".
Hướng dẫn từng bước
Hãy thực hành trọn vẹn một lượt từ đầu tới cuối.
Bước 1 — Kiểm tra Node.js. Mở terminal, gõ node --version. Nếu báo "command not found", cài Node.js LTS từ nodejs.org trước đã.
Bước 2 — Cài Newman. Chạy npm install -g newman, sau đó xác nhận newman --version ra khoảng 6.x. Nếu lệnh newman không nhận, thường là do thư mục npm global chưa nằm trong biến PATH — xử lý ở mục lỗi thường gặp bên dưới.
Bước 3 — Chuẩn bị file. Trong Postman, export collection của bạn ra định dạng Collection v2.1, và export environment ra file riêng. Đặt cả hai vào một thư mục, ví dụ ~/api-tests/.
Bước 4 — Chạy lần đầu. Di chuyển terminal vào thư mục đó và gõ:
newman run my-api.postman_collection.json -e staging.postman_environment.json
Bước 5 — Đọc output. Newman in một bảng cho từng request (tên, status code, thời gian) rồi một bảng tổng kết cuối cùng gồm các cột: số request, số test scripts, số assertions, và cột failed cho từng loại. Hãy nhìn thẳng vào cột failed: nếu tất cả là 0, bạn ổn.
Bước 6 — Kiểm tra exit code. Gõ echo $? ngay sau đó. Số 0 nghĩa là thành công. Đây chính là tín hiệu mà sau này CI sẽ đọc.
Bước 7 — Tinh chỉnh. Thử thêm --bail để dừng sớm khi fail, hoặc --folder "TênFolder" để chạy một phần. Mỗi lần đổi option, quan sát output thay đổi ra sao để cảm nhận tác dụng của từng cờ.
Lỗi thường gặp & mẹo
"command not found: newman" sau khi đã cài. Nguyên nhân gần như luôn là thư mục bin của npm global chưa có trong PATH. Chạy npm config get prefix để biết thư mục, rồi thêm .../bin của nó vào PATH trong file ~/.zshrc (macOS) hoặc ~/.bashrc (Linux). Cách né tránh nhanh: dùng npx newman run ....
Quên cờ -e nên biến rỗng. Triệu chứng kinh điển: request gọi tới {{base_url}}/login nhưng Newman báo lỗi "invalid URL" hoặc gọi nhầm sang một địa chỉ trống. Lý do là bạn quên truyền environment, nên {{base_url}} không có giá trị. Luôn kiểm tra đã có -e đúng file chưa.
Export nhầm định dạng v2.0 hoặc collection cũ. Newman 6.x hoạt động tốt nhất với Collection Format v2.1. Nếu export nhầm định dạng cũ, một số tính năng script có thể chạy sai. Khi export, luôn chọn v2.1.
Nhầm tưởng exit code 0 nghĩa là "không có gì fail". Cẩn thận: nếu collection của bạn không có test script nào, Newman vẫn trả về 0 dù API trả sai. "Không có test thất bại" khác với "API đúng". Hãy đảm bảo mỗi request quan trọng đều có pm.test(...) kiểm tra thật sự.
Mẹo — dùng --verbose khi debug. Khi một request fail mà không hiểu vì sao, thêm --verbose để Newman in cả request headers, body gửi đi và response đầy đủ. Đừng bật cờ này trong CI (output quá dài), nhưng lúc điều tra trên máy thì vô giá.
Mẹo — khóa phiên bản trong dự án thật. Trên máy học thì cài global cho tiện, nhưng trong dự án thực, hãy npm install newman --save-dev để version được ghi vào package.json. Điều này đảm bảo mọi người trong đội và server CI đều chạy cùng một Newman, tránh cảnh "trên máy tôi chạy được".
Mẹo — --timeout-request để chống treo. Nếu API staging đôi khi phản hồi chậm hoặc treo, một request có thể làm cả lệnh Newman đứng vô thời hạn. Đặt --timeout-request 10000 (10 giây) để Newman tự bỏ cuộc và báo fail thay vì treo mãi.
Bài tập thực hành
- Cài và kiểm chứng. Cài Newman global trên máy bạn, chạy
newman --versionvà xác nhận nó ra dòng 6.x. Nếu gặp lỗi PATH, tự khắc phục và ghi lại cách bạn đã làm.
- Chạy một collection có sẵn. Lấy bất kỳ collection nào bạn đã tạo ở các bài trước (kèm environment), export ra file, rồi chạy bằng Newman. Chụp lại bảng tổng kết và chỉ ra: có bao nhiêu request, bao nhiêu assertion, bao nhiêu cái fail.
- Đọc exit code. Chạy collection đó rồi gõ
echo $?. Sau đó, cố tình sửa một test cho nó fail (ví dụ đổipm.expect(pm.response.code).to.eql(200)thành201sai lệch), export lại và chạy — quan sát exit code đổi từ 0 sang 1.
- Thử ba option. Chạy lại collection với
--folder, với-n 3, và với--bail. Với mỗi lần, viết một câu mô tả output khác nhau ở điểm nào so với lần chạy gốc.
- Truyền biến động. Tạo một biến trong environment rồi để trống giá trị, sau đó truyền giá trị thật qua
--env-var "key=value"lúc chạy. Xác nhận request dùng đúng giá trị bạn truyền vào (có thể log biến trong test script để kiểm tra).
Tóm tắt
Newman là Postman ở dạng dòng lệnh — cùng engine chạy request và script, nên mọi test bạn đã viết trong app chạy y nguyên ngoài terminal. Nó được cài qua npm (npm install -g newman, kỳ vọng bản 6.x), và cần Node.js làm nền. Bạn export collection (định dạng v2.1) và environment ra file JSON, rồi chạy bằng newman run <collection> -e <environment>.
Khái niệm sống còn cần nhớ là exit code: 0 nghĩa là mọi thứ pass, khác 0 nghĩa là có fail — và đây chính là tín hiệu mà mọi hệ thống tự động dựa vào để quyết định build đậu hay rớt. Nhóm option bạn nên thuộc gồm -e (environment), --env-var (truyền biến/secret an toàn lúc chạy), -n (lặp để bắt lỗi chập chờn), --folder (chạy một phần), --bail (dừng sớm khi fail) và --timeout-request (chống treo).
Ba tình huống thực tế cho thấy giá trị của Newman ở dạng thuần dòng lệnh: rút ngắn smoke test từ 4 phút thủ công xuống 90 giây, giữ secret an toàn khỏi repo, và định lượng được lỗi race condition bằng cách chạy lặp. Khi bạn đã gõ được lệnh Newman một cách tự tin và biết nhìn exit code để phán đoán, bạn đã sẵn sàng cho bước tiếp theo — đưa Newman vào các reporter đẹp mắt và các pipeline CI/CD tự động, những chủ đề sẽ được khai thác ở các bài sau.