Unit Testing Apigee Proxies with API Tester

Hey Apigee community! In our recent Community Tech Talk on Apigee Unit Testing I demoed a new tool for unit testing Apigee proxies. That tool has now been updated in this repo: GitHub - upstreamplatforms/api-tester: A simple unit testing framework for APIs.. It has a ton of new features since the demo, so read on here for an introduction and getting started guide, and in case of questions, just post in the comments!

The source code for the API Tester tool used can be found here: https://github.com/upstreamplatforms/api-tester.

A video walkthough of the tutorial can also be found here:

:test_tube: API Tester Guide

If you believe that testing your APIs shouldn’t require a PhD in Computer Science or a sacrifice to the XML gods, you’re in the right place. This is a Test Driven Development (TDD) framework that lets you write tests in YAML, run them instantly, and get on with your life.

Here is how to go from “I hope this works” to “I know this works” in 4 easy steps.


Step 1: The “I Just Want to Click Buttons” Method (Web Client)

The easiest way to see what this tool does is to use the hosted beta version. No installation required—just pure, unadulterated testing bliss. :rocket:

  1. Go to the landing page: https://tdd.upstr.dev
  2. Click on the New Test Suite button, and then click on the Admin Link.
  3. Look at the Editor: You’ll see a default YAML file loaded up. It targets mocktarget.apigee.net (the unsung hero of API testing), and has some assertions to test the response.
  4. Hit Run: Click the “Run” button.

What just happened?
You sent a request to https://mocktarget.apigee.net/json, intercepted the response, and the tool checked if the headers matched the expectations. If you see green checks, you are winning. If you see red, mocktarget might be having a bad day (unlikely), or the test logic did its job!

Step 2: The “Hacker Mode” Method (Stateless CLI)

Maybe you prefer the terminal because it makes you look busy and important. :man_detective: We can run a stateless test right from your command line. “Stateless” means the server runs the test and forgets it immediately—perfect for quick sanity checks without leaving a paper trail.

Open your terminal and paste this command:

curl -X POST https://tdd.upstr.dev/tests/run \
  -H "Content-Type: application/yaml" \
  -d '
tests:
  - name: test httpbin.org hostname
    url: https://httpbin.org
    path: /get
    verb: get
    assertions:
      - $.headers.Host===httpbin.org
'

The Result:
You should get a JSON response back detailing the pass/fail status. You just unit-tested a remote endpoint using a cURL command. Pretty cool, right?

Step 3: Understanding the “Secret Sauce” (YAML & Assertions)

The magic lies in how you write the tests. You don’t need complex code; you just need to know what you expect.

Here is the anatomy of a test block:

name: My Awesome Test
tests:
  - name: check if user exists
    url: https://api.example.com
    path: /users/1
    method: GET
    assertions:
      - $.username==johndoe       # 1. Check the JSON Payload
      - response.header.Status==200 # 2. Check the Headers

The Operators:

  • == : Loosely equals (The chill operator). Matches even if types differ.
  • === : Strictly equals (The strict parent). Types and case must match exactly.
  • != : Not equals.
  • : : String includes (Great for checking if an error message contains a specific word).

Step 4: Deploy an Apigee Shared Flow and test a proxy

Now let’s deploy the API Tester Apigee shared flow to an Apigee environment, and do some more detailed proxy unit tests.

# clone the github repo
git clone https://github.com/upstreamplatforms/api-tester.git && cd api-tester
PROJECT_ID=YOUR_APIGEE_ORG
ENV=YOUR_APIGEE_ENV

# create and deploy the shared flow
apigeecli sharedflows create bundle -n SF-Tester-v1 -f ./apigee/sharedflowbundle \
  -o $PROJECT_ID -e $ENV --ovr -t $(gcloud auth print-access-token)

# attach pre-proxy and post-proxy flowhooks for the environment
apigeecli flowhooks attach -n PreProxyFlowHook -s SF-Tester-v1 -o $PROJECT_ID \
  -e $ENV -t $(gcloud auth print-access-token)
apigeecli flowhooks attach -n PostProxyFlowHook -s SF-Tester-v1 -o $PROJECT_ID \
  -e $ENV -t $(gcloud auth print-access-token)

And then deploy an Apigee test proxy and do some comparison tests.

# create and deploy a test proxy to mocktarget.apigee.net
apigeecli apis create bundle -f ./apigee/apiproxy --name ApigeeMockProxy-v1 \
  -o $PROJECT_ID -e $ENV --ovr -t $(gcloud auth print-access-token)

# get apigee hostname
APIGEE_HOST=$(apigeecli envgroups list -o $PROJECT_ID -t $(gcloud auth print-access-token) | jq --raw-output '.environmentGroups[0].hostnames[0]')

# validate that you get traffic from both endpoints (original and proxy)
curl https://mocktarget.apigee.net/json
curl https://$APIGEE_HOST/v1/apigeemock/json

And now do some tests to both endpoints - the original mocktarget and the Apigee proxy. In the Apigee proxy test we can do more detailed unit tests of internal variables.

curl -X POST https://tdd.upstr.dev/tests/run \
-H "Content-Type: application/yaml" \
--data-binary @- << EOF

tests:
  - name: test apigee mock
    url: https://mocktarget.apigee.net
    path: /json
    method: GET
    assertions:
      - $.firstName==john
      - $.city===San Jose
      - response.status===200
      - response.header.content-length===68
  - name: test apigee mock proxy
    url: https://$APIGEE_HOST/v1/apigeemock
    path: /json
    method: GET
    variables:
      test.name: test123
    assertions:
      - $.firstName==john
      - $.city===San Jose
      - response.status===200
      - response.header.content-length===68
      - test.message===Hello test123!
      - proxy.basepath===/v1/apigeemock
EOF

Conclusion

API Tester takes the headache out of TDD for APIs. Whether you are running quick stateless checks via cURL or building complex suites in the web UI, it keeps things simple with readable YAML and powerful JSONPath assertions. It even supports Apigee proxy unit testing for the enterprise folks among us.

If you have ideas to improve or new feature adds, just reach out in the comments!