Tools for recording mParticle Apple SDK API requests using WireMock for later use in integration testing.
Before getting started, install Tuist:
brew install tuist
Then generate the Xcode project:
cd IntegrationTests
tuist generate
This will create the IntegrationTests.xcodeproj and IntegrationTests.xcworkspace files and automatically open them in Xcode.
If you need to edit the Tuist project configuration (Project.swift):
tuist edit
This will open a temporary Xcode project for editing Tuist manifest files.
If you encounter any issues with project generation, you can clean the Tuist cache first:
tuist clean
tuist generate
This project provides tools for recording mParticle SDK API requests by:
- Building mParticle SDK as an xcframework for iOS Simulator
- Generating a test iOS app using Tuist that links to the built framework
- Running the app in iOS Simulator
- Recording all API traffic with WireMock for later use in testing
The project builds the SDK into an xcframework stored in temp_artifacts/ before each test run, ensuring tests always use your latest code changes. The framework is built for iOS Simulator only for faster compilation times during testing.
Records all mParticle SDK API requests using WireMock for later use in integration testing.
./run_wiremock_recorder.sh
What it does:
- Builds mParticle SDK as xcframework for iOS Simulator
- Generates Tuist project linked to the built framework
- Builds the integration test application
- Finds and resets iOS Simulators
- Automatically selects available iPhone simulator (iPhone 17/16/15 priority)
- Starts simulator
- Installs test application
- Starts WireMock in recording mode
- Launches test application
- Records all API traffic to mapping files
- Waits for application completion
- Stops WireMock and shows results
Recorded Files:
wiremock-recordings/mappings/*.json- API request/response mappingswiremock-recordings/__files/*- Response body files
Build Artifacts:
temp_artifacts/mParticle_Apple_SDK.xcframework- Compiled SDK framework (auto-generated, not committed to git)
Extracts JSON request body from a WireMock mapping file for easier editing and maintenance.
# Extract request body without field replacements
python3 extract_request_body.py wiremock-recordings/mappings/mapping-v1-identify.json identify_test
# Extract with field replacements (replaces dynamic fields with ${json-unit.ignore})
python3 extract_request_body.py wiremock-recordings/mappings/mapping-v1-identify.json identify_test --replace
What it does:
- Extracts the JSON request body from WireMock mapping file
- Optionally replaces known dynamic fields (IDs, timestamps, device info) with
${json-unit.ignore} - Saves extracted body to
wiremock-recordings/requests/{test_name}.json - Makes it easier to edit and maintain test request bodies
Dynamic fields replaced with --replace:
a, bid, bsv, ct, das, dfs, dlc, dn, dosv, est, ict, id, lud, sct, sid, vid
Output file format:
{
"test_name": "identify_test",
"source_mapping": "wiremock-recordings/mappings/mapping-v1-identify.json",
"request_method": "POST",
"request_url": "/v1/identify",
"request_body": { ... }
}
Updates a WireMock mapping file with a modified request body from an extracted JSON file.
python3 update_mapping_from_extracted.py wiremock-recordings/requests/identify_test.json
What it does:
- Reads the extracted request body from JSON file
- Updates the source WireMock mapping file with the modified request body
- Preserves all WireMock configuration (response, headers, etc.)
Use case: After extracting and editing a request body, use this script to apply changes back to the mapping.
Note: This script is automatically called by run_clean_integration_tests.sh for all files in wiremock-recordings/requests/ before starting WireMock, so manual execution is usually not needed during testing.
If you see "port already allocated" errors or if no API requests were recorded, it's likely that the ports (8080 and 443) where WireMock should be running are already occupied by another container or application.
Check what's running on the ports:
# Check running Docker containers
docker ps
# Check what's using port 443
lsof -i :443
# Check what's using port 8080
lsof -i :8080
Stop any conflicting Docker containers:
docker stop <container-name>
docker rm <container-name>
If another application is using the ports, terminate it before running the script.
-
Write test code in the integration app:
- Make changes to SDK source code (if needed)
- Edit
IntegrationTests/Sources/main.swiftto test your new or existing SDK functionality - Add code to call the specific SDK methods you want to record
- Best practice: Temporary comment out calls to unrelated your new code to record only relevant API requests
-
Run the WireMock recorder:
./run_wiremock_recorder.shThe script automatically builds the SDK as an xcframework with your latest changes, runs the app, and records all API traffic
-
Review and filter recorded mappings:
- All recordings are saved to
wiremock-recordings/mappings/ - The script records all API requests made during the test run
- Keep only the mappings related to your new test code
- Delete any unrelated or duplicate recordings
Tip: To get cleaner recordings, modify
main.swiftto call only the specific SDK method you're testing, avoiding unrelated API calls - All recordings are saved to
-
Verify the recordings:
- Check that the recorded mappings match your expected API behavior
- Review request URLs, methods, and bodies
- Verify response data in
wiremock-recordings/__files/
After recording, you should update request bodies to make them more maintainable (e.g., replace dynamic values):
-
Extract request body from mapping:
# Extract with automatic field replacement (recommended) python3 extract_request_body.py \ wiremock-recordings/mappings/mapping-v1-identify.json \ identify_test \ --replaceThis creates
wiremock-recordings/requests/identify_test.jsonwith dynamic fields replaced by${json-unit.ignore} -
Edit the extracted request body (optional):
- Open
wiremock-recordings/requests/identify_test.json - Modify the
request_bodysection as needed - Add or remove fields, change expected values, etc.
- Open
-
Update the mapping file with changes:
python3 update_mapping_from_extracted.py \ wiremock-recordings/requests/identify_test.jsonThis updates the original mapping file with your changes
-
Commit both files:
git add wiremock-recordings/mappings/mapping-v1-identify.json git add wiremock-recordings/requests/identify_test.json git commit -m "Update identify request mapping"
Use the verification script to run full end-to-end integration tests:
./run_clean_integration_tests.sh
What the verification script does:
- Rebuilds SDK: Compiles mParticle SDK as xcframework for iOS Simulator from latest source code
- Regenerates project: Runs Tuist to regenerate project linked to the new xcframework
- Resets environment: Cleans simulators and builds test app
- 📝 Applies user-friendly mappings: Automatically converts all user-friendly request bodies from
wiremock-recordings/requests/back to WireMock mappings - Starts WireMock: Launches WireMock container in verification mode with updated mappings
- Runs tests: Executes test app in simulator
- Verifies results: Checks that all requests matched mappings and all mappings were invoked
- Returns exit code: Exits with code 1 if any verification fails (CI/CD compatible)
Note: The SDK xcframework is built fresh on each run, stored in temp_artifacts/mParticle_Apple_SDK.xcframework. This ensures tests always use your latest code changes.
Automatic mapping application:
The script automatically looks for user-friendly request bodies in wiremock-recordings/requests/ and applies them to the corresponding WireMock mappings before starting WireMock. This means you can:
- Edit request bodies in
wiremock-recordings/requests/*.json - Run
./run_clean_integration_tests.sh - Changes are automatically applied - no manual update step needed!
Example workflow:
# 1. Edit user-friendly mapping
vim wiremock-recordings/requests/<test_name>.json
# 2. Run verification (automatically applies changes)
./run_clean_integration_tests.sh
# 3. If tests pass, commit both files
git add wiremock-recordings/requests/<test_name>.json
git add wiremock-recordings/mappings/<mapping_file>.json
git commit -m "Update request expectations"