Skip to main content

CI/CD Integration with Version Control

When integration tests depend on real APIs, failures are often unrelated to your code. Rate limits, network issues, or unstable environments make results unreliable. A better approach is to control those dependencies using mock behavior that is consistent across runs.

Beeceptor’s V2 APIs allow you to manage mock rules programmatically. You can export them as JSON, store them in Git, and apply them during CI runs. This makes your API simulations reproducible and easy to review.

Keep Beeceptor configuration in Git

Create a single JSON file that contains all rules for an endpoint:

/mocks/api-service-rules.json

This file represents your API behavior. It includes routes, conditions, responses, delays, and state logic.

Keeping everything in one file makes code reviews easier. A pull request shows exactly what changed line by line. You can see if new mock rule was added, removed, conditions are changed, or reordered.

A typical review looks like this:

  • A QA/developer updates mock behavior in the JSON file
  • The change goes through code review
  • The same file is used in CI to configure Beeceptor

There is no need to manually sync changes from the dashboard. The file in Git stays the source of truth and you update in Beeceptor on need basis, or on next CI run.

Reset behavior when CI starts

Mock Rules - Reset

Beeceptor provides an API to replace all rules for an endpoint in one go. The following CURL command picks a JSON file, and overwrites any existing rules configuration.

curl -X PUT 'https://api.beeceptor.com/api/v2/endpoints/api-service/rules' \
-H 'Content-Type: application/json' \
-H 'Authorization: <Authorization>' \
-d @mocks/api-service-rules.json

In CI, this step should run before your tests start. It ensures the endpoint always begins with the expected behavior. If a previous run someone edited rules manually from the UI, or new mock rules are created, this call resets everything. The steps are as follows:

If you skipping this 'reset' step, inconsistent results may surface. Tests may pass or fail depending on what ran before.

Mock Rules - Example configuration

Below is a single JSON file that defines multiple scenarios.

{
"rules": [
{
"enabled": true,
"method": "POST",
"description": "Block login after repeated attempts",
"conditions": [
{
"type": "path",
"operator": "equals",
"value": "/api/login"
},
{
"type": "body_param",
"key": "user.email",
"operator": "equals",
"value": "test@example.com"
},
{
"type": "state",
"key": "login_attempts",
"stateType": "counter",
"operator": "greater_than",
"value": "3"
}
],
"action": {
"type": "mock",
"delay": 100,
"status": 429,
"headers": [
{
"key": "Content-Type",
"value": "application/json",
"templated": false
}
],
"templated": false,
"body": "{\"error\": \"Too many attempts\"}"
}
},
{
"enabled": true,
"method": "POST",
"description": "Successful login",
"conditions": [
{
"type": "path",
"operator": "equals",
"value": "/api/login"
},
{
"type": "body",
"operator": "contains",
"value": "username"
}
],
"action": {
"type": "mock",
"delay": 50,
"status": 200,
"headers": [
{
"key": "Content-Type",
"value": "application/json",
"templated": false
}
],
"templated": true,
"body": "{\"status\": \"success\", \"user\": \"{{faker \\\"person.firstName\\\"}}\"}"
}
},
{
"enabled": true,
"method": "GET",
"description": "GraphQL user email query",
"conditions": [
{
"type": "graphql",
"operator": "equals",
"value": "GetUserEmail"
}
],
"action": {
"type": "mock",
"status": 200,
"templated": false,
"body": "{\"data\": {\"email\": \"test@example.com\"}}"
}
}
]
}

How this works:

The first rule tracks login attempts using a counter. After three attempts, it returns a 429 response. This is useful for testing retry logic. The second rule handles normal login requests and returns a success response. The third rule simulates a GraphQL query and returns a fixed payload.

Note that rules are evaluated from top to bottom, here the order matters. The more specific rule appears first so it gets matched before the generic ones.

State Data - Reset

If your mock rules use state, such as counters or stored key-value pairs, that data can persist across requests. This is useful for simulation, but it can affect test executions if not reset between consecutive runs.

Clear the state store so every run starts clean using the DELETE API with a request body:

curl -X DELETE 'https://api.beeceptor.com/api/v2/endpoints/api-service/state' \
-H 'Content-Type: application/json' \
-H 'Authorization: <Authorization>' \
-d '{
"all": true
}'

Applying this in CI (GitHub Actions)

You can set this up in GitHub Actions with the following simple step. There is no SDK or special integration required. Simply store your mock rules as a JSON file and upload them using a PUT API call at the start of CI pipeline.

steps:
- name: Checkout repo
uses: actions/checkout@v3

- name: Clear Beeceptor state
run: |
curl -X DELETE 'https://api.beeceptor.com/api/v2/endpoints/api-service/state' \
-H 'Content-Type: application/json' \
-H 'Authorization: ${{ secrets.BEECEPTOR_TOKEN }}' \
-d '{
"all": true
}'

- name: Apply Beeceptor configuration
run: |
curl -X PUT 'https://api.beeceptor.com/api/v2/endpoints/api-service/rules' \
-H 'Content-Type: application/json' \
-H 'Authorization: ${{ secrets.BEECEPTOR_TOKEN }}' \
-d @mocks/api-service-rules.json

- name: Run tests
run: npm test

These step resets the endpoint with the configuration stored in your Git/Github repository. Every run starts from the same state, so test results do not depend on previous executions or manual changes.


When you combine a version-controlled rules file, a full PUT based reset, and clearing state before each run, your tests execute against a predictable setup every time. This also allows you to validate different scenarios by updating rules per branch, or even isolate parallel runs using separate endpoints.

Over time, the JSON file becomes a clear record of expected API behavior, including edge cases. Keep it structured, review changes carefully, and avoid hidden state dependencies, keeping the tests stable and reduces debugging effort.