Product Management
Đăng nhập
ESC

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

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

Postman trong CI/CD — GitHub Actions

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

Hãy tưởng tượng bạn là QA của một startup fintech ở TP.HCM. Mỗi lần developer merge code mới, bạn phải mở Postman lên, chạy tay collection 120 request, mắt căng ra nhìn từng dấu tick xanh đỏ. Một lần bạn nghỉ phép, chẳng ai chạy hộ, và thế là một bug làm sai số dư ví lọt lên production đúng ngày lễ. Khách hàng phàn nàn ầm ĩ, đội trực phải xử lý sự cố lúc 11 giờ đêm.

Câu chuyện này lặp lại ở rất nhiều team Việt Nam, và nó có một điểm chung: bộ test API chỉ chạy khi con người nhớ ra để chạy. Đó chính là lý do bài học hôm nay tồn tại. Chúng ta sẽ biến bộ collection Postman của bạn thành một "người gác cổng tự động", chạy mỗi khi có commit hay pull request, ngay bên trong GitHub — nơi code của bạn đang sống. Đây là mảnh ghép biến API testing từ hoạt động thủ công thành một phần của quy trình phát triển liên tục (CI/CD).

Ở các bài trước bạn đã học Newman — công cụ chạy Postman collection trên command line. Bài này ta không dạy lại Newman từ đầu, mà tập trung riêng vào việc ghép Newman vào GitHub Actions để test chạy tự động trong pipeline. Nếu bạn dùng GitLab hay Jenkins, đó là chủ đề của bài kế tiếp; ở đây ta chỉ nói về GitHub Actions.

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

CI/CD và vị trí của API test trong pipeline

CI (Continuous Integration) là thói quen tích hợp code liên tục, mỗi lần tích hợp đều được kiểm tra tự động. CD (Continuous Delivery/Deployment) đưa code đã kiểm tra ra môi trường thật một cách tự động. API test của bạn nằm ở tầng "kiểm tra": sau khi code build xong, trước khi (hoặc ngay sau khi) deploy, ta gọi thật vào API để xác nhận nó vẫn hoạt động đúng như kỳ vọng. Nếu test đỏ, pipeline dừng lại, code không được merge hay deploy. Đây gọi là "quality gate" — cổng chất lượng.

GitHub Actions là gì

GitHub Actions là hệ thống CI/CD tích hợp sẵn trong GitHub. Bạn khai báo một workflow — một file YAML đặt trong thư mục .github/workflows/ của repo. Mỗi workflow gồm:

  • Trigger (on): sự kiện kích hoạt, ví dụ push, pull_request, hay theo lịch (schedule).
  • Jobs: các nhóm công việc, mỗi job chạy trên một máy ảo (gọi là runner, thường là ubuntu-latest).
  • Steps: các bước tuần tự trong một job, mỗi bước là một lệnh shell hoặc một action có sẵn.
Điều tuyệt vời: GitHub cấp máy ảo miễn phí cho repo public và một hạn mức phút miễn phí cho repo private (thường 2.000 phút/tháng với tài khoản Free). Với bộ API test nhẹ, con số đó là quá dư dả.

Cách Newman sống trong runner

Runner của GitHub Actions là một máy Linux trống. Để chạy Newman, bạn cần: cài Node.js, cài newman (và reporter nếu cần), rồi gọi newman run với file collection và environment. Toàn bộ những thứ này diễn ra trong vài chục giây. Collection và environment bạn có thể export ra file JSON và commit vào repo, hoặc kéo về từ Postman Cloud bằng API key — ta sẽ nói cả hai cách.

Exit code — linh hồn của quality gate

Điểm mấu chốt khiến pipeline biết "đậu hay rớt" là exit code. Khi mọi assertion pass, Newman trả về exit code 0; khi có bất kỳ test nào fail, nó trả về khác 0. GitHub Actions đọc exit code này: khác 0 nghĩa là step thất bại, job đỏ, và nếu bạn cấu hình đúng, pull request sẽ bị chặn merge. Bạn không phải viết thêm dòng logic nào — cơ chế Unix cổ điển này làm hết.

Tình huống thực tế

Ví dụ 1 — Startup giao đồ ăn chặn regression trước khi merge

Một startup giao đồ ăn ở Hà Nội, đội backend 8 người, mỗi ngày mở trung bình 15 pull request. Trước đây họ review code bằng mắt và thỉnh thoảng bug logic tính phí ship lọt qua. QA lead quyết định export collection "Order & Delivery API" (68 request, 210 assertion) ra JSON, commit vào repo, rồi viết một workflow chạy trên mọi pull_request nhắm vào nhánh develop.

Kết quả sau một tháng: 9 pull request bị pipeline chặn vì test đỏ — trong đó có 2 lỗi tính sai phí ship khi đơn hàng vượt 500.000đ (ngưỡng freeship). Những bug này lẽ ra đã lên staging và tốn công QA test tay để phát hiện. Bài học: khi test chạy tự động ngay tại pull request, developer nhận phản hồi trong vòng 90 giây, sửa ngay khi ngữ cảnh còn nóng, thay vì để QA phát hiện muộn hai ngày sau.

Ví dụ 2 — Công ty SaaS chạy smoke test sau mỗi lần deploy

Một công ty SaaS quản lý kho vận ở Đà Nẵng deploy lên production nhiều lần mỗi ngày. Họ tách bộ test thành hai collection: một collection "regression" đầy đủ chạy ở pull request, và một collection "smoke" chỉ 12 request quan trọng nhất (login, tạo đơn, tra cứu tồn kho) chạy sau khi deploy nhắm thẳng vào URL production.

Có lần một thay đổi biến môi trường (env var) khiến service không kết nối được database. Build xanh, deploy xanh, nhưng smoke test đỏ ngay lập tức vì endpoint login trả 500. GitHub Actions gửi thông báo về kênh Slack của team trong vòng 2 phút, đội trực rollback trước khi khách hàng kịp nhận ra. Bài học: test ở pull request bảo vệ bạn khỏi lỗi logic, còn smoke test sau deploy bảo vệ bạn khỏi lỗi cấu hình môi trường thật — hai lớp khác nhau, cần cả hai.

Ví dụ 3 — Sự cố secret lộ trên log

Một bạn QA mới vào nghề ở một agency phần mềm tại Cần Thơ hí hửng dựng pipeline đầu tiên. Bạn ấy nhét thẳng token API và mật khẩu tài khoản test vào file environment JSON rồi commit lên GitHub. Repo là private nên bạn ấy nghĩ không sao. Ba tuần sau công ty mở repo thành public để làm portfolio, và toàn bộ token nằm phơi trong lịch sử Git.

Cách đúng: những giá trị nhạy cảm (token, mật khẩu, base URL nội bộ) phải để trong GitHub Secrets — vào Settings > Secrets and variables > Actions của repo, thêm secret, rồi truyền vào Newman qua biến môi trường hoặc cờ --env-var. Trong log, GitHub tự động che (mask) giá trị secret thành . Bài học:* đừng bao giờ commit secret vào file collection/environment. Git nhớ mọi thứ, kể cả những gì bạn đã xóa.

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

Ta sẽ dựng một pipeline hoàn chỉnh chạy Newman trên GitHub Actions.

Bước 1 — Export collection và environment. Trong Postman, chọn collection cần chạy, bấm ba chấm > Export, chọn định dạng Collection v2.1, lưu thành collections/api-regression.json. Làm tương tự với environment (nhưng xóa hết giá trị nhạy cảm trước khi export). Commit các file này vào repo.

Bước 2 — Đưa secret vào GitHub. Vào repo trên GitHub > Settings > Secrets and variables > Actions > New repository secret. Thêm ví dụ API_BASE_URL, API_TOKEN. Đây là nơi lưu các giá trị mà bạn đã cố ý bỏ trống ở file environment.

Bước 3 — Tạo workflow. Tạo file .github/workflows/api-test.yml:

name: API Regression

on: push: branches: [main, develop] pull_request: branches: [main, develop]

jobs: newman: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4

- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'

- name: Install Newman run: npm install -g newman

- name: Run API tests run: | newman run collections/api-regression.json \ --environment environments/staging.json \ --env-var "base_url=${{ secrets.API_BASE_URL }}" \ --env-var "token=${{ secrets.API_TOKEN }}" \ --reporters cli

Bước 4 — Hiểu từng phần. on khai báo pipeline chạy khi push hoặc mở pull request vào main/develop. Job newman chạy trên Ubuntu. Bốn step: lấy code về, cài Node 20, cài Newman, rồi chạy test. Cờ --env-var ghi đè giá trị nhạy cảm bằng secret, nên file JSON trong repo luôn "sạch".

Bước 5 — Đẩy lên và quan sát. Commit, push, mở tab Actions trên GitHub. Bạn sẽ thấy workflow chạy realtime, log Newman hiện ra từng request. Nếu tất cả xanh, job xanh. Thử cố tình sửa một assertion cho fail, push lại, và xem job chuyển đỏ.

Bước 6 — Bật quality gate cho pull request. Vào Settings > Branches > Add branch protection rule cho main, tick "Require status checks to pass before merging" và chọn job newman. Từ giờ, không pull request nào được merge vào main nếu API test còn đỏ.

Bước 7 (tùy chọn) — Kéo collection từ Postman Cloud. Nếu không muốn commit file JSON, bạn có thể lưu Postman API Key vào secret rồi tải collection về lúc chạy:

      - name: Run tests from Postman Cloud
        run: |
          newman run "https://api.getpostman.com/collections/COLLECTION_UID?apikey=${{ secrets.POSTMAN_API_KEY }}"

Cách này giúp test luôn dùng phiên bản collection mới nhất trên Postman, nhưng đánh đổi bằng việc phụ thuộc vào Postman Cloud khi pipeline chạy.

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

Quên rằng runner chạy trên internet công cộng. Nếu API staging của bạn nằm sau VPN hay chỉ mở cho IP nội bộ công ty, runner của GitHub không gọi vào được và test sẽ timeout. Giải pháp: dùng self-hosted runner đặt trong mạng nội bộ, hoặc mở một endpoint staging riêng cho CI, hoặc dùng đường hầm (tunnel) có kiểm soát.

Không cache dependency nên pipeline chậm. Mỗi lần cài Newman lại từ đầu tốn 15–30 giây. Với actions/setup-node@v4, bật cache: 'npm' (khi có package.json) để tái sử dụng thư viện. Bộ test nhỏ thì không đáng lo, nhưng khi có nhiều reporter và plugin thì cache giúp giảm đáng kể thời gian.

Pipeline luôn xanh dù test đỏ. Nguyên nhân phổ biến: bạn thêm || true vào cuối lệnh Newman, hoặc dùng reporter theo cách nuốt mất exit code. Đừng làm thế — chính exit code khác 0 mới là thứ chặn merge. Nếu muốn pipeline không dừng ngay để còn upload báo cáo, dùng continue-on-error: true ở step test rồi kiểm tra kết quả ở step sau, chứ đừng che exit code.

Path sai. File collection phải đúng đường dẫn tính từ gốc repo. newman run collections/api.json khác với ./api.json. Nếu báo "file not found", chạy ls -R tạm trong một step để soi cấu trúc thư mục trên runner.

Mẹo — dùng ma trận để test nhiều môi trường. Với strategy.matrix, bạn có thể chạy cùng collection trên cả devstaging song song, mỗi môi trường một job. Rất tiện khi muốn xác nhận API nhất quán giữa các tầng.

Mẹo — đặt timeout hợp lý. Thêm timeout-minutes: 10 cho job để một request treo không làm pipeline chạy vô tận và đốt phút miễn phí của bạn.

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

  • Tạo một repo GitHub mới (public để dùng runner miễn phí thoải mái). Export một collection Postman đơn giản gọi vào một API công khai như https://reqres.in hoặc https://jsonplaceholder.typicode.com, kèm 3–4 assertion. Commit collection vào repo.
  • Viết file .github/workflows/api-test.yml chạy Newman trên mọi push. Push lên và xác nhận job xanh trong tab Actions.
  • Cố tình sửa một assertion cho sai (ví dụ kỳ vọng status 999). Push lại và quan sát job chuyển đỏ. Đọc kỹ log Newman xem nó chỉ ra assertion nào fail.
  • Tạo một GitHub Secret tên BASE_URL, sửa collection dùng biến {{base_url}}, rồi truyền secret vào Newman qua --env-var. Xác nhận trong log giá trị đã bị che thành *.
  • Thêm branch protection rule yêu cầu job Newman phải xanh mới được merge. Mở một pull request có test đỏ và tự kiểm chứng rằng nút Merge bị khóa.
  • (Nâng cao) Thêm trigger schedule chạy collection mỗi sáng 8 giờ (theo giờ UTC, nhớ trừ 7 tiếng cho giờ Việt Nam) để có một bản smoke test định kỳ độc lập với commit.

Tóm tắt

Bài này biến bộ Postman collection của bạn thành một quality gate tự động sống trong GitHub. Những điểm cần khắc cốt ghi tâm:

  • GitHub Actions dùng file YAML trong .github/workflows/, gồm trigger (on), jobs và steps chạy trên runner Ubuntu miễn phí.
  • Newman chạy trong runner qua bốn bước quen thuộc: checkout, cài Node, cài Newman, chạy test.
  • Exit code là linh hồn của quality gate: Newman trả khác 0 khi có test fail, GitHub tự động chuyển job sang đỏ và chặn merge — bạn không cần viết thêm logic.
  • Chạy test ở pull_request chặn lỗi logic sớm; chạy smoke test sau deploy chặn lỗi cấu hình môi trường thật. Hai lớp bổ trợ nhau.
  • Mọi giá trị nhạy cảm phải nằm trong GitHub Secrets, không bao giờ commit vào file collection/environment — vì Git nhớ tất cả.
Khi pipeline này chạy trơn tru, bạn không còn phải mở Postman bấm tay mỗi lần merge nữa. Bộ test làm việc thay bạn, kể cả lúc bạn đang nghỉ phép — đúng như tinh thần CI/CD.

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