تخطَّ إلى المحتوى

Step CI Cheat Sheet

Overview

Step CI is an open-source API testing and monitoring framework that uses declarative YAML workflows to define API tests. It supports REST, GraphQL, gRPC, tRPC, and SOAP APIs, with built-in assertions, data capture, performance testing, and CI/CD integration. Step CI focuses on simplicity, requiring no code to write comprehensive API test suites.

Step CI provides features like environment variables, reusable components, request chaining with captured values, schema validation, load testing, and multiple output formats. It can run locally, in CI/CD pipelines, or as a monitoring solution, making it versatile for API quality assurance workflows.

Installation

# npm (global)
npm install -g stepci

# npx (no install)
npx stepci run workflow.yml

# Docker
docker run ghcr.io/stepci/stepci run workflow.yml

# Homebrew
brew install stepci

# Verify installation
stepci --version

Core Commands

CommandDescription
stepci run workflow.ymlRun a workflow file
stepci run workflow.yml --env env.ymlRun with environment file
stepci run workflow.yml --secret key=valPass secrets
stepci run workflow.yml -lLoad test mode
stepci generate URLGenerate workflow from OpenAPI spec
stepci initCreate a starter workflow

Basic Workflow

# workflow.yml
version: "1.1"
name: API Tests
env:
  host: https://api.example.com
  token: Bearer mytoken

tests:
  health:
    steps:
      - name: Health check
        http:
          url: ${{env.host}}/health
          method: GET
          check:
            status: 200
            jsonpath:
              $.status: ok

  users:
    steps:
      - name: List users
        http:
          url: ${{env.host}}/users
          method: GET
          headers:
            Authorization: ${{env.token}}
          check:
            status: 200
            jsonpath:
              $.data: 
                - isArray: true
            headers:
              Content-Type: application/json

Request Types

GET Request

steps:
  - name: Get user
    http:
      url: https://api.example.com/users/123
      method: GET
      headers:
        Accept: application/json
        Authorization: Bearer token123
      check:
        status: 200

POST Request with JSON

steps:
  - name: Create user
    http:
      url: https://api.example.com/users
      method: POST
      headers:
        Content-Type: application/json
      json:
        name: John Doe
        email: john@example.com
        role: admin
      check:
        status: 201
        jsonpath:
          $.id:
            - isNumber: true

PUT and DELETE

steps:
  - name: Update user
    http:
      url: https://api.example.com/users/123
      method: PUT
      headers:
        Content-Type: application/json
      json:
        name: Jane Doe
      check:
        status: 200

  - name: Delete user
    http:
      url: https://api.example.com/users/123
      method: DELETE
      check:
        status: 204

Form Data and File Upload

steps:
  - name: Upload file
    http:
      url: https://api.example.com/upload
      method: POST
      formData:
        file:
          file: ./avatar.png
        description: Profile photo
      check:
        status: 200

Assertions (Checks)

steps:
  - name: Comprehensive assertions
    http:
      url: https://api.example.com/users/123
      method: GET
      check:
        # Status code
        status: 200

        # Response time
        performance:
          total:
            - lte: 500

        # Headers
        headers:
          Content-Type: application/json
          Cache-Control:
            - contains: no-cache

        # JSON body assertions
        jsonpath:
          $.id:
            - eq: 123
          $.name:
            - eq: "John Doe"
          $.email:
            - matches: "^[\\w.]+@[\\w.]+$"
          $.active:
            - eq: true
          $.roles:
            - isArray: true
            - length: 3
          $.balance:
            - gte: 0
            - lte: 10000
          $.created_at:
            - isString: true

        # Body content checks
        body:
          - contains: John
          - notContains: error

        # Schema validation
        schema:
          type: object
          required: [id, name, email]
          properties:
            id:
              type: integer
            name:
              type: string
            email:
              type: string
              format: email

Capturing Values

tests:
  auth_flow:
    steps:
      - name: Login
        http:
          url: ${{env.host}}/auth/login
          method: POST
          json:
            username: admin
            password: secret
          check:
            status: 200
          captures:
            auth_token:
              jsonpath: $.token
            user_id:
              jsonpath: $.user.id

      - name: Get profile
        http:
          url: ${{env.host}}/users/${{captures.user_id}}
          method: GET
          headers:
            Authorization: Bearer ${{captures.auth_token}}
          check:
            status: 200
            jsonpath:
              $.id:
                - eq: ${{captures.user_id}}

GraphQL Testing

steps:
  - name: GraphQL query
    http:
      url: https://api.example.com/graphql
      method: POST
      graphql:
        query: |
          query GetUser($id: ID!) {
            user(id: $id) {
              id
              name
              email
            }
          }
        variables:
          id: "123"
      check:
        status: 200
        jsonpath:
          $.data.user.name: "John Doe"

Load Testing

version: "1.1"
name: Load Test
env:
  host: https://api.example.com

tests:
  load:
    steps:
      - name: Health endpoint load
        http:
          url: ${{env.host}}/health
          method: GET
          check:
            status: 200
            performance:
              total:
                - lte: 200
# Run with load testing enabled
stepci run workflow.yml -l --concurrency 50 --duration 60s

# Custom load profile
stepci run workflow.yml -l --concurrency 100 --iterations 10000

Environment Configuration

# env.yml
host: https://api.example.com
token: Bearer production-token
admin_email: admin@example.com
# Run with environment file
stepci run workflow.yml --env env.yml

# Override with secrets
stepci run workflow.yml --env env.yml --secret token="Bearer new-token"

Advanced Usage

Conditional Steps

steps:
  - name: Create user
    http:
      url: ${{env.host}}/users
      method: POST
      json:
        name: Test User
      check:
        status: 201
    captures:
      user_id:
        jsonpath: $.id
    if: ${{env.create_user}} == "true"

Reusable Components

version: "1.1"
name: API Tests

components:
  headers:
    auth:
      Authorization: Bearer ${{env.token}}
      Accept: application/json

tests:
  users:
    steps:
      - name: List users
        http:
          url: ${{env.host}}/users
          method: GET
          headers:
            $ref: "#/components/headers/auth"
          check:
            status: 200

CI/CD Integration

# GitHub Actions
name: API Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm install -g stepci
      - run: stepci run workflow.yml --env env.ci.yml

Generate from OpenAPI

# Generate test workflow from OpenAPI spec
stepci generate https://api.example.com/openapi.json > workflow.yml

# From local file
stepci generate ./openapi.yaml > workflow.yml

Troubleshooting

IssueSolution
Variable not resolvedCheck syntax: ${{env.name}} for env, ${{captures.name}} for captures
SSL errorUse --no-tls-verify for self-signed certificates
TimeoutIncrease request timeout in workflow options
JSONPath not matchingVerify path using a JSONPath evaluator; check response body
Schema validation failsEnsure JSON Schema draft version is compatible
Load test OOMReduce concurrency; increase system limits
Captures emptyEnsure the preceding step succeeds before using captured values
GraphQL errorsVerify query syntax; check variables match schema