Danh sách bài viết

Bài 62: CLI --no-deps — Bỏ Qua Dependencies

--no-deps là flag CLI cho phép chạy một project mà không kéo theo các project dependencies đã khai báo trong config. Bài này phân tích khi nào flag này có giá trị thực tế, khi nào nó gây fail khó debug, và pattern workflow cụ thể cho dev local so với CI.

28/05/2026
0 lượt xem
1

Mục Tiêu Bài Học

Sau bài này bạn sẽ:

  • Hiểu rõ --no-deps bỏ qua cái gì và không bỏ qua cái gì.
  • Biết 3 use case thực tế trên dev local mà flag này tiết kiệm thời gian.
  • Nhận ra 3 tình huống risk: token expired, state stale, auth file chưa tồn tại.
  • Có pattern workflow rõ ràng: khi nào chạy với deps, khi nào skip.
  • Tránh 5 pitfall phổ biến khi dùng --no-deps sai ngữ cảnh.

Bài này tập trung vào khía cạnh khi nào và tại sao dùng --no-deps. Cú pháp cơ bản đã xuất hiện trong bài 57 (project dependencies) và bài 60 (CLI --project) — ở đây không lặp lại mà đi sâu vào behavior, risk và pattern cụ thể.

2

Default Behavior Khi Không Có --no-deps

Giả sử config sau:

// playwright.config.ts
export default defineConfig({
  projects: [
    {
      name: 'setup',
      testMatch: /.*\.setup\.ts/,
    },
    {
      name: 'main',
      use: {
        ...devices['Desktop Chrome'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },
  ],
});

Chạy không có --no-deps:

npx playwright test --project=main

Playwright tự resolve dependency chain trước khi chạy main:

Running 2 projects: setup, main
  [setup]  › auth.setup.ts:3:1 › authenticate (2.1s) ✓
  [main]   › checkout.spec.ts:5:5 › checkout flow (1.4s) ✓
  [main]   › dashboard.spec.ts:8:3 › show widget (0.9s) ✓

3 passed (4.5s)

Setup chạy trước mỗi lần, tạo lại auth.json với session token mới. Toàn bộ flow: login → lưu cookie/token → main test dùng state đó.

Với config phức tạp hơn (setup mất 10–30 giây, gọi external auth service, seed database), pattern này đảm bảo trạng thái luôn fresh nhưng mỗi lần iterate test phải chờ toàn bộ setup.

3

--no-deps Hoạt Động Thế Nào

Thêm --no-deps:

npx playwright test --project=main --no-deps

Playwright bỏ qua hoàn toàn bước resolve dependency — không chạy setup, không tạo lại auth.json:

Running 1 project: main
  [main]   › checkout.spec.ts:5:5 › checkout flow (1.4s) ✓
  [main]   › dashboard.spec.ts:8:3 › show widget (0.9s) ✓

2 passed (2.3s)

main vẫn đọc storageState: 'playwright/.auth/user.json' từ config — chỉ là file đó không được refresh lại trước khi chạy. Nếu file đang tồn tại và còn hợp lệ, test chạy bình thường. Nếu file cũ hoặc không tồn tại, test sẽ fail theo cách phụ thuộc vào app — thường là redirect về /login hoặc nhận 401.

Điểm quan trọng: --no-deps bỏ qua toàn bộ dependency chain — không có cách chọn partial (bỏ qua 1 dependency, giữ dependency khác). Nếu main có 3 dependency (setup-auth, setup-db, setup-config), cả 3 đều bị skip.

4

Use Case Hợp Lệ

Debug nhanh test đang fail

Dev đang fix 1 test bị fail — cần chạy lại nhiều lần để verify fix. Setup mất 15 giây mỗi run, nhưng auth token còn hợp lệ (session lifetime 1 giờ, dev mới login 5 phút trước):

# Không cần chờ setup mỗi lần
npx playwright test --project=main --no-deps --grep "checkout flow"

Tiết kiệm: 15 giây × N lần iterate = đáng kể khi N > 5.

Auth chưa expire, setup tốn thời gian

Setup gọi external auth provider (Auth0, Keycloak) mất 20–30 giây. Token session lifetime 8 giờ. Dev làm việc buổi sáng, chạy setup 1 lần lúc 9:00, sau đó iterate test đến 11:00 mà không cần re-run setup:

# Lần đầu buổi sáng
npx playwright test --project=main

# Các lần sau trong cùng session làm việc
npx playwright test --project=main --no-deps

Offline development

Setup gọi external API để tạo test data (Stripe test payment method, SendGrid test inbox). Dev đang làm việc trên tàu hoặc không có internet — setup sẽ fail ngay do không kết nối được. Nhưng test data đã tồn tại từ lần chạy cuối khi có mạng:

# Setup sẽ fail khi offline
npx playwright test --project=main          # KHÔNG làm thế này

# Skip setup, dùng state có sẵn
npx playwright test --project=main --no-deps  # OK nếu state còn dùng được
5

Risk Và Khi Nào Không Dùng

Risk 1: Token expired — fail không rõ nguyên nhân

Session token hết hạn sau 1 giờ, nhưng auth.json vẫn tồn tại trên disk. Playwright không có cách tự biết token đã expire — nó chỉ đọc file và set cookie/localStorage. Test chạy, gọi API authenticated, nhận 401 hoặc redirect về /login:

Error: expect(page).toHaveURL('/dashboard')
Received: http://localhost:3000/login?redirect=/dashboard

  at checkout.spec.ts:12:5

Error trỏ vào test logic, không phải auth setup — dev mất thời gian debug nhầm chỗ.

Risk 2: State stale — database seed cũ

Setup không chỉ xử lý auth mà còn seed database: tạo test user, sản phẩm, đơn hàng. Test main expect sản phẩm có id: 42 từ seed. Hôm qua chạy setup, seed tạo product id 42. Hôm nay dev khác thay đổi seed script — product id bây giờ là 45. Chạy --no-deps → test fail với "product not found" dù test logic đúng.

Risk 3: Auth file chưa tồn tại lần nào

Clone repo mới, chưa bao giờ chạy setup. Thư mục playwright/.auth/ không tồn tại:

npx playwright test --project=main --no-deps
Error: ENOENT: no such file or directory, open 'playwright/.auth/user.json'

Hoặc tệ hơn, nếu storageState optional và app không throw error khi thiếu auth — tất cả test chạy ở trạng thái unauthenticated, fail hàng loạt với error không liên quan tới setup.

6

Verify Auth State Trước Khi Dùng --no-deps

Cách đơn giản nhất: check file tồn tại và xem timestamp:

ls -la playwright/.auth/user.json
-rw-r--r-- 1 dev staff 2847 May 28 09:14 playwright/.auth/user.json

Nếu file được tạo lúc 09:14 và session lifetime là 1 giờ, đến 10:14 token sẽ expire. Chạy --no-deps lúc 09:30 là an toàn, lúc 10:20 sẽ fail.

Cách chắc chắn hơn: thêm guard trong test.beforeEach để verify auth còn hợp lệ trước khi test logic chạy:

// Trong file test hoặc global setup fixture
test.beforeEach(async ({ page }) => {
  await page.goto('/dashboard');
  // Nếu auth expired, app redirect về /login
  if (page.url().includes('/login')) {
    throw new Error(
      'Auth expired. Run: npx playwright test --project=main (without --no-deps)'
    );
  }
});

Error message rõ ràng hướng dev đến hành động đúng — thay vì debugs sai hướng.

Có thể đặt guard này vào fixture riêng để tất cả test trong project tự động check:

// fixtures/auth-guard.ts
import { test as base } from '@playwright/test';

export const test = base.extend({
  page: async ({ page }, use) => {
    await page.goto('/dashboard');
    if (page.url().includes('/login')) {
      throw new Error('Auth state invalid. Re-run setup project first.');
    }
    await use(page);
  },
});

export { expect } from '@playwright/test';
7

Workflow Pattern: Lần Đầu vs Iteration

Pattern rõ ràng nhất để tránh nhầm lẫn:

# 1. Lần đầu, hoặc sau khi auth expire / state thay đổi
#    → chạy đầy đủ, setup refresh state
npx playwright test --project=main

# 2. Các lần iterate sau trong cùng session dev
#    → skip setup, chạy nhanh
npx playwright test --project=main --no-deps --grep "checkout"

# 3. Debug 1 test cụ thể, headed + slowmo để quan sát
npx playwright test --project=main --no-deps --grep "@debug" --headed

Phân biệt quyết định:

  • Chạy lần đầu trong ngày → không dùng --no-deps.
  • Vừa sửa xong code app (state có thể thay đổi) → không dùng --no-deps.
  • Chỉ sửa test logic, app không đổi → có thể dùng --no-deps nếu auth còn hợp lệ.
  • Clone repo lần đầu → không dùng --no-deps.

Quy tắc ngón tay cái: nếu không chắc auth còn hợp lệ, đừng dùng --no-deps. Setup mất 15–30 giây, debug auth fail mất 15–30 phút.

8

Kết Hợp Với Các Flag Khác

--no-deps hoạt động độc lập với các filter flag khác — combine tự nhiên:

# Debug 1 test cụ thể, no deps, headed mode
npx playwright test --project=main --no-deps --grep "@debug" --headed --debug

# Chạy nhanh nhóm test checkout, không re-auth
npx playwright test --project=main --no-deps --grep "checkout"

# Chạy tất cả test của main, no deps, workers giảm để quan sát log
npx playwright test --project=main --no-deps --workers=1

Thứ tự flag không ảnh hưởng kết quả — Playwright parse tất cả flag trước khi bắt đầu:

# Hai lệnh này tương đương
npx playwright test --no-deps --project=main --grep "checkout"
npx playwright test --project=main --grep "checkout" --no-deps

Combine với --reporter:

# Chạy nhanh, chỉ cần biết pass/fail, không cần HTML report
npx playwright test --project=main --no-deps --reporter=line

Combine với --retries: nếu setup không chạy và auth fail → retry không giúp gì. Tránh --retries khi đang debug với --no-deps — fail nhanh còn hơn retry thêm lần nào vô ích.

Combine với --shard: --no-deps chỉ ảnh hưởng việc setup có chạy không — shard vẫn chia test bình thường trong phạm vi project đã chọn. Không có interaction đặc biệt.

9

--no-deps Trong Reporter

Khi dùng --no-deps, setup project không xuất hiện trong report — không phải "skipped", không phải "passed", hoàn toàn vắng mặt:

Running 2 tests using 2 workers

  ✓  [main] › checkout.spec.ts:5:5 › checkout flow (1.4s)
  ✓  [main] › dashboard.spec.ts:8:3 › show widget (0.9s)

2 passed (1.8s)

So sánh với run đầy đủ:

Running 3 tests using 2 workers

  ✓  [setup] › auth.setup.ts:3:1 › authenticate (2.1s)
  ✓  [main]  › checkout.spec.ts:5:5 › checkout flow (1.4s)
  ✓  [main]  › dashboard.spec.ts:8:3 › show widget (0.9s)

3 passed (3.9s)

HTML report cũng không có entry nào cho setup khi dùng --no-deps. Điều này có nghĩa: nếu lưu report từ --no-deps run và dùng để audit, sẽ không biết setup có chạy hay không — không nên lưu report từ --no-deps run như evidence chính thức.

10

--no-deps vs --list

Hai flag thường bị nhầm lẫn vì tên nghe giống nhau về mặt "bỏ qua thứ gì đó":

Flag Làm gì Test có chạy không
--list Liệt kê test sẽ match, không execute Không
--no-deps Skip dependency project, execute main
# --list: xem test nào sẽ chạy, không thực sự chạy
npx playwright test --project=main --list
# Output: Listing tests:
#   [main] › checkout.spec.ts:5:5 › checkout flow
#   [main] › dashboard.spec.ts:8:3 › show widget
# Total: 2 tests in 2 files

# --no-deps: chạy thật, chỉ skip setup
npx playwright test --project=main --no-deps
# Output: 2 passed

Combine cả hai:

npx playwright test --project=main --no-deps --list
# Liệt kê test của main mà không tính setup vào list

Thực tế --list không chạy gì nên --no-deps không có ý nghĩa gì khi combine — tuy nhiên không gây error. Dùng --list đơn thuần khi chỉ muốn xem danh sách.

11

CI Và --no-deps

Quy tắc: CI không dùng --no-deps trong run thông thường. CI là môi trường fresh — không có auth.json từ lần trước, không có state cũ. Dùng --no-deps trên CI = chạy test mà không có setup = fail toàn bộ.

# KHÔNG làm thế này trên CI
- run: npx playwright test --project=main --no-deps  # WRONG

# Làm thế này
- run: npx playwright test --project=main           # CORRECT

Trường hợp hợp lệ duy nhất trên CI: workflow có job riêng chạy setup, upload artifact, job sau download artifact rồi chạy test:

jobs:
  setup:
    runs-on: ubuntu-latest
    steps:
      - run: npx playwright test --project=setup
      - uses: actions/upload-artifact@v4
        with:
          name: auth-state
          path: playwright/.auth/

  test:
    needs: setup
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: ["1/3", "2/3", "3/3"]
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: auth-state
          path: playwright/.auth/
      # Setup đã chạy ở job trước, artifact đã download → có thể --no-deps
      - run: npx playwright test --project=main --no-deps --shard=${{ matrix.shard }}

Pattern này có giá trị khi: setup tốn nhiều thời gian (login + seed DB) và cần share state giữa nhiều shard job mà không re-run setup N lần.

12

5 Pitfalls

Pitfall 1: Dùng --no-deps lần đầu khi auth.json chưa tồn tại

Clone repo, chưa bao giờ chạy setup:

npx playwright test --project=main --no-deps
# → Error: ENOENT: no such file or directory 'playwright/.auth/user.json'
# Hoặc tất cả test fail vì unauthenticated

Fix: chạy 1 lần không có --no-deps trước.

Pitfall 2: Auth expired không nhận ra

Để máy qua đêm, sáng hôm sau mở terminal, chạy --no-deps mà quên token đã expire lúc nửa đêm. Mọi test fail với error trỏ vào test logic thay vì auth setup — debug sai hướng.

Fix: thêm auth guard trong beforeEach (xem bài này mục 6). Hoặc kiểm tra timestamp của auth.json trước khi chạy.

Pitfall 3: Dùng --no-deps trên CI (không phải artifact pattern)

Dev quen dùng --no-deps ở local, copy lệnh vào CI workflow:

# CI workflow — SAI
- run: npx playwright test --project=main --no-deps
# → Không có auth.json → fail toàn bộ

Fix: bỏ --no-deps trên CI. Chỉ dùng artifact pattern nếu cần share state giữa job.

Pitfall 4: State stale sau thay đổi schema / seed

Team cập nhật seed script, product ID thay đổi. Dev khác dùng --no-deps với state cũ → test fail với "product not found" trong khi test logic không có bug. Mất thời gian debug nhầm.

Fix: sau khi team thay đổi seed/schema, mọi người cần chạy lại setup (không có --no-deps) để refresh state.

Pitfall 5: Quên --no-deps khi muốn iterate nhanh

Dev đang sửa test logic, auth vẫn hợp lệ, nhưng mỗi lần chạy vẫn chờ setup 20 giây mà không biết có thể skip. Không phải bug, chỉ là không tối ưu — nhưng trải nghiệm dev chậm không cần thiết.

Fix: nhớ dùng --no-deps khi auth còn hợp lệ và chỉ sửa test logic.

13

Quiz + Bài Tiếp

Câu 1: Dùng --no-deps, setup project có xuất hiện trong HTML report là "skipped" không?

Đáp án

Không. Setup hoàn toàn vắng mặt khỏi report — không có entry nào, không phải "skipped", không phải "passed". Report chỉ chứa test của project đã chạy.

Câu 2: Config có 3 dependency: setup-auth, setup-db, setup-config. Dùng --no-deps thì Playwright skip bao nhiêu dependency?

Đáp án

Cả 3. --no-deps bỏ qua toàn bộ dependency chain — không có cách partial skip. Không có flag nào để chọn skip 1 dependency cụ thể.

Câu 3: CI workflow cần chạy setup 1 lần, sau đó share state cho 4 shard job song song. Cách đúng là gì?

Đáp án

Job setup chạy npx playwright test --project=setup, upload playwright/.auth/ lên artifact. Mỗi shard job download artifact xuống rồi chạy npx playwright test --project=main --no-deps --shard=X/4. Setup chỉ chạy 1 lần, state được share qua artifact.

Câu 4: Dev chạy --no-deps, mọi test fail với error "Expected URL: /dashboard, Received: /login". Nguyên nhân có thể là gì?

Đáp án

Auth state không còn hợp lệ — token expired hoặc auth.json không tồn tại. Setup không chạy nên state không được refresh. Fix: chạy lại không có --no-deps để setup tạo lại auth state.

Câu 5: Sự khác biệt giữa --no-deps--list là gì?

Đáp án

--list liệt kê test sẽ match mà không execute bất kỳ test nào. --no-deps skip dependency project nhưng vẫn execute main project. Hai flag không liên quan nhau về chức năng.


Bài tiếp theo: Bài 63: workers — Cấu Hình Số Workers — mở nhóm A.7 Parallel & Sharding.