@tooniez

Published

- 9 min read

Agile Test Strategy for Workato Automation

img of Agile Test Strategy for Workato Automation

Agile Test Strategy for Workato

This guide outlines an agile test strategy for Workato automation workflows and integrations.

1. Objectives of Testing

  • Ensure recipe correctness and reliable execution for automation workflows
  • Validate connector functionality and API integrations
  • Test recipe configurations and error handling
  • Verify Workbot commands and responses
  • Ensure data mapping and transformation accuracy

2. Key Testing Activities Across the Agile Lifecycle

Planning and Design

  • Unit Testing for Connectors

    • Use RSpec-based tests to validate actions, triggers, and lambda functions
    • Generate test scaffolds using workato generate test for consistent setup
    • Learn more about connector testing
  • Mock APIs

    • Create test fixtures for API input/output simulation
    • Validate responses without external dependencies
  • Configuration Testing

    • Validate connector dialog configurations and recipe input/output schemas
    • Test dialog validation rules and error handling
    • Verify dialog field mappings between recipes
    • Ensure dialog form fields match command input parameters
    • Test trigger mappings (e.g., post-command triggers for Slack commands)

Development Phase

  • TDD and BDD Practices

    • Use RSpec for executable specifications
    • Test actions like execute, input_fields, and output_fields
    • Validate functional and non-functional requirements
    • Handle edge cases and malformed inputs
    • Use VCR to record and replay HTTP requests

    Example RSpec tests:

       # Test a Workato connector action
    RSpec.describe "MyConnector" do
      describe "actions" do
        let(:connector) { MyConnector.new }
        
        it "creates a record successfully" do
          input = {
            "name" => "Test Record",
            "email" => "test@example.com"
          }
          
          result = connector.execute("create_record", input)
          expect(result["id"]).not_to be_nil
          expect(result["status"]).to eq("success")
        end
    
        it "validates required input fields" do
          fields = connector.input_fields("create_record")
          expect(fields).to include(
            {
              "name" => "name",
              "type" => "string", 
              "required" => true
            }
          )
        end
    
        it "handles malformed input gracefully" do
          input = { "email" => "invalid-email" }
          expect {
            connector.execute("create_record", input)
          }.to raise_error(WorkatoValidationError)
        end
      end
    
      describe "triggers" do
        it "processes webhook payload correctly" do
          payload = {
            "event" => "new_order",
            "data" => { "order_id" => "123" }
          }
          
          result = connector.process_trigger("webhook", payload)
          expect(result["processed"]).to be true
          expect(result["output"]).to include("order_id")
        end
      end
    end
    
  • Integration Testing with Postman

    • End-to-end tests combining multiple connectors

    • Test boundary conditions with third-party services

    • Use Postman collections to validate Workato API endpoints:

         // Prescript to return workato access token
      pm.sendRequest({
          url: "https://api.workato.com/v1/access_tokens",
          method: "POST",
          body: {
              "client_id": "YOUR_CLIENT_ID",
              "client_secret": "YOUR_CLIENT_SECRET"
          }
      });
      
      // Test recipe execution status
      pm.test("Recipe execution successful", function() {
          pm.expect(pm.response.json().status).to.equal("completed");
          pm.expect(pm.response.json().recipe_id).to.exist;
          pm.expect(pm.response.json().job_id).to.exist;
          pm.expect(pm.response.json().job_status).to.be.oneOf(['queued', 'running', 'completed']);
          pm.expect(pm.response.json().started_at).to.exist;
          pm.expect(pm.response.json().completed_at).to.exist;
      });
      
      // Validate job details 
      pm.test("Job details are valid", function() {
          const job = pm.response.json().job;
          pm.expect(job.status).to.be.oneOf(['queued', 'running', 'completed']);
          pm.expect(job.started_at).to.exist;
          pm.expect(job.completed_at).to.exist;
          pm.expect(job.recipe_id).to.exist;
          pm.expect(job.recipe_name).to.exist;
          pm.expect(job.recipe_version).to.exist;
      
      });
      
    • Common Workato test scenarios:

      • Recipe trigger validation
         pm.test("Recipe trigger payload is valid", function() {
          const triggerData = pm.request.body.raw;
          pm.expect(triggerData).to.have.property('event_type');
          pm.expect(triggerData.data).to.not.be.empty;
          pm.expect(triggerData.data).to.be.an('object');
          pm.expect(triggerData.data).to.have.property('order_id');
      });
      
      • Connection testing
         pm.test("Connection is authenticated", function() {
          pm.expect(pm.response.json().connection_status).to.equal("connected");
          pm.expect(pm.response.json().access_token).to.exist;
      });
      
      • Workbot command testing
         pm.test("Workbot command executed correctly", function() {
          const response = pm.response.json();
          pm.expect(response.command).to.exist;
          pm.expect(response.response_type).to.be.oneOf(['in_channel', 'ephemeral']);
      });
      
      • Workato Connector contract testing schema validation
         const expectedSchema = {
          "type": "object",
          "required": ["connection_status", "access_token", "web_properties"],
          "properties": {
              "connection_status": { 
                  "type": "string",
                  "enum": ["connected", "disconnected"]
              },
              "access_token": { "type": "string" },
              "web_properties": {
                  "type": "array",
                  "items": {
                      "type": "object",
                      "required": ["id", "name", "url", "created_at"],
                      "properties": {
                          "id": { "type": "string" },
                          "name": { "type": "string" },
                          "url": { "type": "string", "format": "uri" },
                          "created_at": { "type": "string", "format": "date-time" },
                          "tracking_id": { "type": "string" },
                          "timezone": { "type": "string" }
                      }
                  }
              }
          }
      };
      
      pm.test('Verify Locations response matches expected JSON schema', () => {
          pm.response.to.have.jsonSchema(expectedSchema)
      });
      
      • Workato Recipe contract testing schema validation
         const expectedSchema = {
      "type": "object",
      "required": ["recipe_id", "name", "status", "created_at", "updated_at", "steps"],
      "properties": {
          "recipe_id": { "type": "string" },
          "name": { "type": "string" },
          "status": {
              "type": "string",
              "enum": ["active", "inactive", "draft"]
          },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" },
          "steps": {
              "type": "array",
              "items": {
                  "type": "object",
                  "required": ["step_id", "type", "config"],
                  "properties": {
                      "step_id": { "type": "string" },
                      "type": {
                          "type": "string",
                          "enum": ["trigger", "action", "condition", "loop"]
                      },
                      "config": {
                          "type": "object",
                          "properties": {
                              "app": { "type": "string" },
                              "action": { "type": "string" },
                              "input": { "type": "object" },
                              "output": { "type": "object" }
                          }
                      }
                  }
              }
          }
      };
      
      pm.test('Verify Recipe response matches expected JSON schema', () => {
          pm.response.to.have.jsonSchema(expectedSchema)
      });
      
      • Workato Recipe step output validation
         const expectedOutput = {
      "step_id": "create_opportunity",
      "type": "action",
      "config": {
          "app": "salesforce",
          "action": "create_opportunity",
          "output": {
              "id": { "type": "string" },
              "name": { "type": "string" },
              "stage": {
                  "type": "string",
                  "enum": ["Prospecting", "Qualification", "Proposal", "Negotiation", "Closed Won", "Closed Lost"]
              },
              "amount": { "type": "number" },
              "close_date": { "type": "string", "format": "date" },
              "account_id": { "type": "string" },
              "owner_id": { "type": "string" },
              "created_date": { "type": "string", "format": "date-time" },
              "last_modified_date": { "type": "string", "format": "date-time" },
              "probability": { "type": "number", "minimum": 0, "maximum": 100 },
              "type": {
                  "type": "string",
                  "enum": ["New Business", "Existing Business", "Add-On Business"]
              }
          }
      };
      
      pm.test('Verify Recipe step output matches expected output', () => {
          pm.response.to.have.json(expectedOutput)
      });
      
      • Workato Recipe step input validation
         const expectedInput = {
      "step_id": "create_opportunity",
      "type": "action", 
      "config": {
          "app": "salesforce",
          "action": "create_opportunity",
          "input": {
              "name": { "type": "string", "required": true },
              "stage": {
                  "type": "string",
                  "enum": ["Prospecting", "Qualification", "Proposal", "Negotiation", "Closed Won", "Closed Lost"],
                  "required": true
              },
              "amount": { "type": "number", "required": true },
              "close_date": { "type": "string", "format": "date", "required": true },
              "account_id": { "type": "string", "required": true },
              "owner_id": { "type": "string", "required": true },
              "type": {
                  "type": "string", 
                  "enum": ["New Business", "Existing Business", "Add-On Business"],
                  "required": true
              },
              "probability": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100,
                  "required": false
              },
              "description": {
                  "type": "string",
                  "required": false
              }
          }
      };
      
      pm.test('Verify Recipe step input matches expected input', () => {
          pm.response.to.have.json(expectedInput)
      });
      

Release and Deployment

  • Performance Testing

    • Assess workflow scalability under stress conditions using Test Automation
    • Simulate high volume data processing with mock data
    • Monitor memory usage and optimize performance
    • Follow performance best practices for handling large datasets
  • Regression Testing

    • Create comprehensive test cases in Test Automation
    • Run automated checks to validate step outputs
    • Maintain test coverage across recipe versions
    • Use test case management to organize scenarios
    • Prevent regressions with automated validation
  • Continuous Testing

    • Integrate Test Automation APIs into CI/CD pipelines
    • Run tests automatically on recipe changes
    • Get instant feedback on recipe functionality
    • Leverage test automation APIs for automated validation
    • Catch errors early with automated checks
    • Scale testing across multiple recipes and environments

Test Automation with Curl Commands

Recipe Testing

   # Get recipe details
curl -X GET "https://www.workato.com/api/recipes/{recipe_id}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Start recipe test
curl -X POST "https://www.workato.com/api/recipes/{recipe_id}/test" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "field1": "value1",
      "field2": "value2"
    }
  }'

# Get test job status
curl -X GET "https://www.workato.com/api/jobs/{job_id}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Workato CLI Commands

   # Test recipe execution
workato recipe test <recipe_id>

# Validate connector
workato connector validate

# Run recipe tests
workato recipe test-suite run

Connection Testing

   # Test connection
curl -X POST "https://www.workato.com/api/connections/{connection_id}/test" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Get connection details
curl -X GET "https://www.workato.com/api/connections/{connection_id}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Folder Management

   # List all test folders
curl -X GET "https://www.workato.com/api/folders" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Create test folder
curl -X POST "https://www.workato.com/api/folders" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test Folder",
    "description": "Folder for automated tests"
  }'

Test Suite Management

   # Create test suite
curl -X POST "https://www.workato.com/api/test_suites" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API Integration Tests",
    "folder_id": "folder_id",
    "description": "End-to-end API tests"
  }'

# Run test suite
curl -X POST "https://www.workato.com/api/test_suites/{suite_id}/run" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Get test suite results
curl -X GET "https://www.workato.com/api/test_suites/{suite_id}/results" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Test Case Management

   # Create test case
curl -X POST "https://www.workato.com/api/test_cases" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Create Order Test",
    "suite_id": "suite_id",
    "recipe_id": "recipe_id",
    "input": {
      "order_details": {
        "product": "Test Product",
        "quantity": 1
      }
    },
    "expected_output": {
      "status": "success",
      "order_id": "regex:\\d+"
    }
  }'

# Run specific test case
curl -X POST "https://www.workato.com/api/test_cases/{test_case_id}/run" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Get test case results
curl -X GET "https://www.workato.com/api/test_cases/{test_case_id}/results" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Test Environment Management

   # List environments
curl -X GET "https://www.workato.com/api/environments" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Create test environment
curl -X POST "https://www.workato.com/api/environments" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "QA Environment",
    "description": "Environment for QA testing"
  }'

# Update environment variables
curl -X PUT "https://www.workato.com/api/environments/{environment_id}/variables" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "variables": {
      "API_ENDPOINT": "https://qa-api.example.com",
      "API_KEY": "test-api-key"
    }
  }'

Test Data Management

   # Upload test data
curl -X POST "https://www.workato.com/api/test_data" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sample Orders",
    "data": [
      {
        "order_id": "ORD001",
        "customer": "Test Customer",
        "amount": 100.00
      }
    ]
  }'

# Get test data
curl -X GET "https://www.workato.com/api/test_data/{data_id}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

3. Test Tools and Approaches

Workato Test Features

  • Recipe testing interface
  • Test mode execution
  • Debug logging
  • Recipe version control
  • Test data management

External Testing Tools

  • Postman for API testing

  • RSpec for connector testing

  • CI/CD integration tools

  • Workato SDK Testing

    • Leverage SDK test utilities
    • Use RSpec.describe blocks for validation
  • Postman API Testing

    • Use Postman collections to validate Workato API endpoints
    • End-to-end tests combining multiple connectors
    • Test boundary conditions with third-party services
  • VCR

    • Record and replay HTTP requests
    • Handle external API dependencies
  • RSpec

    • Use RSpec for executable specifications
    • Test actions like execute, input_fields, and output_fields
    • Validate functional and non-functional requirements
    • Handle edge cases and malformed inputs
  • BDD

    • Use BDD for behavior-driven development
    • Define expected outcomes in plain text
    • Validate functional and non-functional requirements
    • Handle edge cases and malformed inputs
  • Workato CLI

   ruby -v
gem install workato-connector-sdk
gem install eventmachine # Dependency for workato-connector-sdk on mac osx

workato --help
Commands:
  workato edit <PATH>            # Edit encrypted file, e.g. settings.yaml.enc
  workato exec <PATH>            # Execute connector defined block
  workato generate <SUBCOMMAND>  # Generates code from template
  workato help [COMMAND]         # Describe available commands or one specific command
  workato new <CONNECTOR_PATH>   # Inits new connector folder
  workato oauth2                 # Implements OAuth Authorization Code flow
  workato push                   # Upload and release connector's code
  workato version                # Shows gem version

Options:
  [--verbose], [--no-verbose], [--skip-verbose]
  • Generate test scaffolds using workato generate test for consistent setup

  • Generate expected outputs via CLI

  • Gather test results via CLI

  • Example: workato exec for response data

  • Example: workato generate expected_output for expected output data

  • Version Control

    • Store tests in version control
    • Enable team collaboration and review
  • Test Data Management

    • Use fixtures for sample data
    • Generate expected outputs via CLI
    • Example: workato exec for response data
  • Code Coverage

    • Track test coverage metrics
    • Ensure comprehensive testing

4. Best Practices

Recipe Testing

  • Test each trigger condition
  • Validate all data mappings
  • Test error handling scenarios
  • Use test mode for verification
  • Document test cases

Connector Testing

  • Test authentication flows
  • Validate input/output schemas
  • Test rate limiting handling
  • Verify error responses
  • Test data transformations

API Testing

  • Validate endpoint responses
  • Test authentication
  • Verify payload formats
  • Test error scenarios
  • Monitor performance

Configuration Testing

  • Validate connector dialog configurations and recipe input/output schemas
  • Test dialog validation rules and error handling
  • Verify dialog field mappings between recipes
  • Ensure dialog form fields match command input parameters
  • Test trigger mappings (e.g., post-command triggers for Slack commands)

Form Testing

  • Validate form field mappings and validation rules
  • Test form submission and error handling
  • Ensure form data matches expected output

5. Collaboration and Communication

  • Share test recipes across environments
  • Maintain up-to-date documentation
  • Use shared repositories for real-time updates
  • Foster open feedback channels

Additional Resources