Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Behat Api Extension Laravel Package

imbo/behat-api-extension

Behat 3 extension for testing JSON-based APIs. Simplifies making HTTP requests, asserting responses, and validating JSON payloads in your scenarios. Inspired by behat/web-api-extension and built for API testing workflows like Imbo.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev imbo/behat-api-extension
    

    Add to behat.yml:

    extensions:
        Imbo\BehatApiExtension\Extension: ~
    
  2. First Use Case: Test a simple GET request with assertions:

    Feature: API Test
      Scenario: Fetch user data
        Given I send a GET request to "/api/users/1"
        Then the response status code should be 200
        And the response should match JSON:
          """
          {
            "id": 1,
            "name": "John Doe"
          }
          """
    
  3. Key Files:

    • features/bootstrap/FeatureContext.php (default context)
    • behat.yml (configuration)
    • Official Docs (reference)

Implementation Patterns

Common Workflows

  1. Request-Response Cycles:

    Given I send a POST request to "/api/posts" with:
      """
      {
        "title": "Test Post",
        "body": "Content..."
      }
      """
    Then the response status code should be 201
    And the response should contain JSON path "$.id"
    
  2. Authentication:

    Given I send a GET request to "/api/protected" with headers:
      | Authorization | Bearer token123 |
    
  3. File Uploads:

    Given I send a POST request to "/api/upload" with multipart form data:
      | file | @path/to/file.jpg |
    
  4. Dynamic Data:

    // In FeatureContext.php
    public function setDynamicData($key, $value) {
        $this->dynamicData[$key] = $value;
    }
    
    Given I set dynamic data "userId" to 1
    And I send a GET request to "/api/users/{userId}"
    
  5. Hooks for Setup/Teardown:

    // In FeatureContext.php
    protected function getBaseUrl() {
        return getenv('API_BASE_URL') ?: 'http://localhost:8000';
    }
    

Integration Tips

  • Laravel API Testing: Combine with Laravel’s Http facade for pre-request logic:

    use Illuminate\Support\Facades\Http;
    
    public function beforeScenario(Scenario $scenario) {
        Http::fake([
            'api/users/*' => Http::response(['id' => 1], 200),
        ]);
    }
    
  • Environment-Specific Config:

    # behat.yml
    suites:
      default:
        contexts:
          - FeatureContext:
              base_url: "%env(API_URL)%"
    
  • Custom Matchers: Extend Imbo\BehatApiExtension\Context\JsonPathMatcher for domain-specific assertions.


Gotchas and Tips

Pitfalls

  1. PHP Version Mismatch:

    • Package requires PHP 8.3+ (v6.0.0+). Check composer.json constraints.
    • Downgrade to v5.x for PHP 8.1 or v3.x for PHP 7.4 if needed.
  2. JSON Path Syntax:

    • Use dot notation ($.user.name) or bracket notation ($['user']['name']).
    • Avoid wildcards (*) in paths—use exact matches or custom matchers.
  3. Multipart Form Data:

    • Do not mix multipart/form-data with JSON bodies. The extension auto-detects but may fail silently.
  4. Context Initialization:

    • Ensure FeatureContext extends Imbo\BehatApiExtension\Context\ApiContext:
      use Imbo\BehatApiExtension\Context\ApiContext;
      
      class FeatureContext extends ApiContext { ... }
      
  5. Caching Responses:

    • Disable caching in behat.yml if tests flake due to stale responses:
      extensions:
          Imbo\BehatApiExtension\Extension:
              cache: false
      

Debugging Tips

  • Enable Verbose Output:

    behat --verbose
    

    Or configure in behat.yml:

    default:
        suites:
            default:
                filters:
                    tags: ~
                extensions:
                    Behat\MinkExtension:
                        base_url: null
                        goutte: ~
                        selenium2: ~
                    Imbo\BehatApiExtension\Extension:
                        debug: true
    
  • Inspect Raw Responses:

    Then dump the response
    

    Outputs raw HTTP response (headers + body) to console.

  • Mock External APIs: Use Laravel’s Http::fake() or Mockery in beforeScenario() to isolate tests.

Extension Points

  1. Custom HTTP Clients: Override createClient() in ApiContext to use Guzzle with custom middleware:

    protected function createClient() {
        $client = new \GuzzleHttp\Client([
            'timeout' => 10,
            'headers' => ['X-Custom-Header' => 'value'],
        ]);
        return $client;
    }
    
  2. Dynamic Headers:

    Given I set header "Authorization" to "Bearer {token}"
    

    Combine with Laravel’s Str::random() or config() for dynamic values.

  3. Pre/Post-Request Hooks:

    public function beforeRequest(Request $request) {
        $request->setHeader('X-Test-ID', uniqid());
    }
    
  4. Custom Assertions: Extend JsonPathMatcher for domain-specific logic (e.g., date validation):

    class CustomMatcher extends \Imbo\BehatApiExtension\Context\JsonPathMatcher {
        public function matchDate($expected, $actual) {
            return strtotime($expected) === strtotime($actual);
        }
    }
    

    Register in behat.yml:

    extensions:
        Imbo\BehatApiExtension\Extension:
            matchers:
                date: CustomMatcher
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity