DEV Community

Cover image for Specmatic là gì
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Specmatic là gì

Nếu bạn đang giữ một tệp OpenAPI nhưng service đang chạy dần lệch khỏi đặc tả đó, Specmatic là công cụ giúp biến đặc tả thành hợp đồng có thể thực thi. Nó dùng cùng một spec để kiểm thử service thật và chạy stub cho consumer. Bài viết này hướng dẫn cách Specmatic hoạt động, khi nào nên dùng, cách chạy bằng CLI/Docker, và cách đặt nó trong workflow kiểm thử hợp đồng API, kèm so sánh ngắn với cách tiếp cận nền tảng rộng hơn như kiểm thử hợp đồng API của Apidog. Nền tảng bên dưới là OpenAPI Specification, nguồn sự thật mà Specmatic đọc để tạo kiểm thử và stub.

Dùng thử Apidog hôm nay

Specmatic là gì

Specmatic là công cụ mã nguồn mở cho phát triển dựa trên hợp đồng. Ý tưởng chính: đặc tả API là hợp đồng, và Specmatic làm cho hợp đồng đó có thể chạy được.

Với một tệp OpenAPI, Specmatic có thể làm hai việc:

Specmatic

  • Chạy đặc tả như bộ kiểm thử đối với service thật.
  • Chạy đặc tả như stub server để consumer phát triển trước khi provider hoàn thiện.

Cả hai tác vụ đều đọc cùng một tệp spec. Bạn không phải duy trì riêng “định nghĩa kiểm thử” và “đặc tả API”.

Specmatic không chỉ hỗ trợ OpenAPI. Phiên bản 2.0 đã thêm GraphQL và gRPC. Công cụ này cũng hỗ trợ AsyncAPI cho hợp đồng sự kiện kiểu Kafka, cùng các định dạng như WSDL và Avro. Tuy vậy, điểm bắt đầu phổ biến nhất vẫn là một tệp OpenAPI YAML hoặc JSON.

Bạn có thể chạy Specmatic bằng CLI hoặc Docker image, nên việc đưa vào CI tương đối đơn giản. Phần công cụ hợp đồng cốt lõi là miễn phí và mã nguồn mở; các tiện ích thương mại là phần bổ sung riêng.

Kiểm thử hợp đồng so với kiểm thử dựa trên ví dụ

Kiểm thử dựa trên ví dụ là cách quen thuộc trong nhiều API client:

  1. Viết một request cụ thể.
  2. Gửi request đến API.
  3. Assert status code và một vài field trong response.

Ví dụ:

expect(response.status).toBe(200)
expect(response.body.id).toBeDefined()
expect(response.body.email).toContain("@")
Enter fullscreen mode Exit fullscreen mode

Cách này hữu ích, nhưng mỗi test chỉ bao phủ một ví dụ cụ thể. Nếu API có 40 endpoint, bạn phải tự viết và duy trì rất nhiều request/assertion. Những phần không được viết test sẽ dễ bị bỏ sót.

Kiểm thử hợp đồng đảo ngược mô hình đó. Thay vì viết từng assertion thủ công, bạn khai báo hợp đồng trong OpenAPI, rồi để Specmatic tạo kiểm thử từ schema.

Specmatic kiểm tra các điểm như:

  • Response có đúng schema đã khai báo không.
  • Field bắt buộc có tồn tại không.
  • Kiểu dữ liệu có khớp không.
  • Status code có nằm trong hợp đồng không.
  • Request không hợp lệ có bị từ chối theo cách mà spec ngụ ý không.

Nói ngắn gọn: đặc tả chính là assertion.

Khía cạnh Kiểm thử dựa trên ví dụ Kiểm thử hợp đồng với Specmatic
Nguồn sự thật Test case viết tay Chính đặc tả OpenAPI
Thứ cần duy trì Từng request và assertion Đặc tả API
Độ bao phủ Chỉ những gì bạn nhớ viết Các operation được khai báo trong spec
Phát hiện độ lệch Thủ công Tự động khi spec/service lệch nhau
Lỗi điển hình Một ví dụ cụ thể bị fail Service không còn khớp hợp đồng

Cũng cần phân biệt Specmatic với kiểm thử hợp đồng hướng consumer kiểu Pact. Pact cho phép consumer công bố kỳ vọng lên broker, sau đó provider xác minh dựa trên các kỳ vọng đó.

Specmatic đi theo hướng contract-driven: đặc tả là hợp đồng chung duy nhất. Specmatic xác thực provider dựa trên spec và tạo provider stub cho consumer. Nó không phải Pact broker và không quản lý pact do consumer công bố.

Nếu bạn muốn xem bức tranh rộng hơn, tham khảo tổng quan về các công cụ kiểm thử hợp đồng và mock API.

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

Bạn có thể cài CLI trực tiếp hoặc dùng Docker. Trong CI, Docker thường tiện hơn vì không cần cấu hình runtime trên máy build.

1. Chạy kiểm thử hợp đồng

Giả sử bạn có:

  • Spec: api.yaml
  • Service đang chạy tại: http://localhost:8080

Chạy bằng native CLI:

specmatic test api.yaml --testBaseURL=http://localhost:8080
Enter fullscreen mode Exit fullscreen mode

Chạy bằng Docker:

docker run -v "$(pwd):/usr/src/app" specmatic/specmatic \
  test api.yaml --testBaseURL=http://host.docker.internal:8080
Enter fullscreen mode Exit fullscreen mode

Luồng xử lý:

  1. Specmatic đọc api.yaml.
  2. Tạo request cho các operation được mô tả trong spec.
  3. Gửi request đến testBaseURL.
  4. Validate response theo schema.
  5. Báo lỗi nếu service không còn khớp hợp đồng.

Nếu test fail, bạn có hai lựa chọn:

  • Sửa service để khớp spec.
  • Cập nhật spec nếu hành vi mới là chủ đích.

Điểm quan trọng là không để service và hợp đồng lệch nhau trong im lặng.

2. Đưa kiểm thử hợp đồng vào CI

Một bước CI tối thiểu có thể trông như sau:

contract-test:
  stage: test
  script:
    - docker run -v "$PWD:/usr/src/app" specmatic/specmatic \
        test api.yaml --testBaseURL=http://api-under-test:8080
Enter fullscreen mode Exit fullscreen mode

Trong workflow thực tế, bạn thường chạy service trước, chờ health check pass, rồi chạy Specmatic:

./start-service.sh

until curl -f http://localhost:8080/health; do
  sleep 2
done

specmatic test api.yaml --testBaseURL=http://localhost:8080
Enter fullscreen mode Exit fullscreen mode

Nếu hợp đồng bị phá vỡ, build fail trước khi thay đổi được merge hoặc deploy.

3. Chạy đặc tả như stub server

Stub server là nửa còn lại của workflow. Consumer có thể phát triển dựa trên API giả lập nhưng vẫn khớp hợp đồng.

specmatic stub api.yaml --port=9000
Enter fullscreen mode Exit fullscreen mode

Sau đó client có thể gọi:

curl http://localhost:9000/orders/123
Enter fullscreen mode Exit fullscreen mode

Theo mặc định, Specmatic tạo response hợp lệ theo schema. Bạn cũng có thể đặt ví dụ cụ thể trong thư mục _examples cạnh spec để stub trả về dữ liệu kiểm soát được khi request khớp.

Cấu trúc thư mục có thể như sau:

.
├── api.yaml
└── _examples
    └── get_order_success.json
Enter fullscreen mode Exit fullscreen mode

Cách này hữu ích khi frontend hoặc service downstream cần dữ liệu ổn định mà chưa muốn phụ thuộc backend thật.

Nếu bạn đang so sánh các lựa chọn stub/mock, bài viết về kiểm thử hợp đồng và máy chủ mock đặt Specmatic vào đúng ngữ cảnh.

4. Tạo spec từ service hiện có

Specmatic cũng có thể hỗ trợ khi bạn có service trước nhưng chưa có đặc tả chính thức. Nó có thể chạy như proxy trước service hiện có, ghi lại request/response thực tế và tạo tài liệu OpenAPI cùng các tệp ví dụ từ traffic quan sát được.

Use case phù hợp:

  • Service đã tồn tại nhưng tài liệu lỗi thời.
  • Bạn muốn bootstrap OpenAPI ban đầu.
  • Bạn muốn tạo example thực tế từ traffic thay vì viết tay hoàn toàn.

Mô hình đặc tả-như-hợp-đồng và stub

Điểm mạnh của Specmatic là cùng một spec được dùng cho cả provider và consumer.

Provider chạy:

specmatic test api.yaml --testBaseURL=http://localhost:8080
Enter fullscreen mode Exit fullscreen mode

Consumer chạy:

specmatic stub api.yaml --port=9000
Enter fullscreen mode Exit fullscreen mode

Kết quả:

  • Provider biết service thật có khớp hợp đồng không.
  • Consumer có stub phản hồi theo đúng hợp đồng.
  • Hai phía không phải đồng bộ hai nguồn định nghĩa khác nhau.

Một workflow đơn giản:

  1. Team thống nhất thay đổi trong api.yaml.
  2. Consumer dùng specmatic stub để phát triển trước.
  3. Provider triển khai endpoint thật.
  4. CI của provider chạy specmatic test.
  5. Nếu service lệch spec, build fail.

Đây là lý do đặc tả trở thành “thỏa thuận sống”, thay vì tài liệu tĩnh không ai tin tưởng.

Khác biệt giữa stub và mock cũng đáng hiểu trước khi thiết kế workflow. Bạn có thể xem thêm về stubbing API so với mocking.

Kiểm tra khả năng tương thích ngược

Specmatic hỗ trợ kiểm tra backward compatibility bằng lệnh backward-compatibility-check.

Ý tưởng:

  1. Dùng phiên bản mới của spec để khởi động stub.
  2. Dùng phiên bản cũ của spec để tạo test.
  3. Chạy test cũ trên stub mới.
  4. Nếu hành vi từng hoạt động nay bị phá vỡ, kiểm tra fail.

Điều này đặc biệt hữu ích với microservice triển khai độc lập. Bạn có thể phát hiện breaking change trước khi deploy.

Ví dụ workflow:

specmatic backward-compatibility-check old-api.yaml new-api.yaml
Enter fullscreen mode Exit fullscreen mode

Nếu thay đổi mới loại bỏ field bắt buộc với consumer cũ, thay đổi status code, hoặc làm endpoint cũ không còn hợp lệ, bạn sẽ biết sớm.

Đây là một biến thể của ý tưởng rộng hơn trong kiểm thử hợp đồng hai chiều.

Khi nào nên dùng Specmatic

Specmatic phù hợp nếu nhóm của bạn có các đặc điểm sau:

  • Bạn duy trì OpenAPI, AsyncAPI, GraphQL hoặc gRPC spec tương đối hoàn chỉnh.
  • Provider và consumer là các team/service riêng.
  • Bạn muốn spec drift làm fail build tự động.
  • Bạn ưu tiên workflow CLI và CI.
  • Bạn muốn dùng cùng một spec cho cả test và stub.

Một checklist triển khai thực tế:

[ ] Có OpenAPI spec làm nguồn sự thật
[ ] Spec được version trong Git
[ ] CI có bước khởi động service
[ ] CI chạy specmatic test
[ ] Consumer có thể chạy specmatic stub cục bộ
[ ] Breaking change được kiểm tra trước khi merge
Enter fullscreen mode Exit fullscreen mode

Specmatic ít phù hợp hơn nếu:

  • Bạn chưa duy trì spec chính thức.
  • Bạn cần workspace trực quan để thiết kế, debug và cộng tác API.
  • Bạn muốn một công cụ duy nhất cho thiết kế, kiểm thử thủ công, mock, tài liệu và chia sẻ nội bộ.

Specmatic tập trung vào contract tooling, và nó làm tốt phần đó.

Specmatic và Apidog khác nhau ở đâu

Specmatic là công cụ hợp đồng sắc bén, native CLI. Nó phù hợp với team muốn đưa contract testing và stub vào pipeline kỹ thuật.

Apidog có phạm vi rộng hơn. Apidog cũng đi theo hướng schema-driven: đọc đặc tả OpenAPI, xác thực response dựa trên schema và tạo máy chủ mock từ schema OpenAPI của bạn mà không cần code.

Khác biệt chính là phạm vi sử dụng:

  • Specmatic tập trung vào CLI, CI, contract test và stub.
  • Apidog gói thiết kế API, kiểm thử, mocking và tài liệu vào một workspace trực quan.
  • Cả hai đều không phải Pact broker hướng consumer kiểu Pact.

Nếu bạn cần tạo test có thể chạy trực tiếp từ spec trong một workspace trực quan, xem cách Apidog xử lý tạo bộ sưu tập kiểm thử API từ các đặc tả OpenAPI.

Câu hỏi thường gặp

Specmatic có miễn phí không?

Có. Công cụ hợp đồng cốt lõi là mã nguồn mở và miễn phí sử dụng qua CLI hoặc Docker. Có các dịch vụ thương mại xung quanh nó, nhưng bạn có thể chạy contract test và stub server từ OpenAPI spec mà không phải trả phí. Kiểm tra website chính thức và GitHub để biết thông tin hiện tại về các gói trả phí.

Specmatic có chỉ hoạt động với OpenAPI không?

Không. OpenAPI là điểm bắt đầu phổ biến nhất, nhưng Specmatic cũng hỗ trợ AsyncAPI cho hợp đồng hướng sự kiện, GraphQL và gRPC kể từ phiên bản 2.0, cùng các định dạng như WSDL và Avro.

Mô hình vẫn giống nhau: đặc tả là hợp đồng có thể thực thi.

Nếu bạn mới bắt đầu với định dạng này, xem hướng dẫn OpenAPI Specification.

Specmatic có giống Pact không?

Không hẳn.

Pact là consumer-driven contract testing: consumer công bố kỳ vọng lên broker, provider xác minh dựa trên kỳ vọng đó.

Specmatic là contract-driven: đặc tả là hợp đồng chia sẻ duy nhất. Specmatic dùng spec để xác thực provider và tạo provider stub cho consumer.

Cả hai đều giúp giảm lỗi tích hợp, nhưng tổ chức hợp đồng theo hai cách khác nhau.

Specmatic có thể tạo OpenAPI spec cho tôi không?

Có. Specmatic có thể chạy như proxy trước service hiện có, ghi lại request/response thực tế, rồi tạo tài liệu OpenAPI cùng các tệp ví dụ. Cách này hữu ích khi service đã chạy nhưng chưa có spec chính thức để kiểm thử.

Kết luận

Specmatic giải quyết một vấn đề cụ thể: giữ service thật khớp với OpenAPI spec mà nó cam kết tuân theo. Bằng cách làm cho đặc tả có thể thực thi, Specmatic cung cấp contract test, stub server và kiểm tra tương thích ngược từ cùng một tệp.

Nếu team của bạn làm việc nhiều với terminal, CI và duy trì spec nghiêm túc, Specmatic là lựa chọn phù hợp.

Nếu bạn muốn hợp đồng, test, mock và tài liệu cùng nằm trong một workspace trực quan đọc cùng một tệp OpenAPI, hãy thử Apidog. Apidog xác thực response dựa trên schema, mock endpoint không cần code và biến spec thành test collection có thể chạy. Tải xuống Apidog để trỏ nó đến spec của bạn và quản lý quy trình từ thiết kế đến kiểm thử ở một nơi.

Top comments (0)