5 levels of API test
automation
/shekhar-ramphal @shakes_test
About me
13 years
testing
experience
Full stack
tester
/shekhar-ramphal @shakes_test
Context
Development / Testing
Team A
Team C
Team B
Team E
Team D
/shekhar-ramphal @shakes_test
Some key AllanGray automation testing principles
Programmatic approach.
● Anyone can contribute as they build features.
● Test code lives with the feature code.
Design the framework to be easily maintainable.
● Testers are at different levels.
● Consistency is king.
Automation is a tool
● Automate to support testing not replace it.
/shekhar-ramphal @shakes_test
API test example
/shekhar-ramphal @shakes_test
API test, so why 5 levels?
test('Search people named shakes', async () => {
const url = 'http://api.dev.com/people?search=shakes';
const response = await request.GET(url);
expect(response.code).toBe(200);
});
/shekhar-ramphal @shakes_test
expect(response.body.length).toBeGreaterThan(0);
expect(response.body[0].name).toContain('shakes');
});
Unpack a test
test('Search people named shakes', async () => {
const url = 'http://api.dev.com/people?search=shakes';
const response = await request.GET(url);
expect(response.code).toBe(200);
API has been deployed to
an env.
I need legit data
Should probably test
different response
codes… but how?
Good idea to do more
checks. Test ran fine 15 mins ago ???
Are there restrictions?
Numbers? special chars?
/shekhar-ramphal @shakes_test
Levels
What type of tests per level?
What data to use?
When do they run?
● Acceptance / Component tests
● Verification / Integration tests
● Smoke tests
● Synthetic tests
● Data chaos monkey tests
Assumption that unit / unit integration tests have been done.
/shekhar-ramphal @shakes_test
Acceptance / component tests
Test suite API
API
Dependencies
API
API
DBMQ
/shekhar-ramphal @shakes_test
Acceptance / component tests
Test suite API
Dependencies
CI
DB
Mock
data
Mock
data
Mock
data
P
r
o
x
y
MQ
/shekhar-ramphal @shakes_test
Acceptance / component tests
Test suite API
Dependencies
CI
DB
Mock
data
Mock
data
Mock
data
P
r
o
x
y
MQ
/shekhar-ramphal @shakes_test
Acceptance / component tests
Test suite API
API
Dependencies
API
API
DBMQ
person
contact
details
bank
details
account
info
All methods
GET, PUT,
POST,
DELETE
Bad responses
5XXs
4XXs
Data
Scenarios
Empty / null
Missing data
Combinations
/shekhar-ramphal @shakes_test
Mocking is great…
Amazing test scenario coverage.
Tests pass consistently in this mocked world.
/shekhar-ramphal @shakes_test
test('Search people named bob with mocked dependencies', async () => {
mockServer.loadFixtures([dependencyFixture1, dependencyFixture2,
dependencyFixture3]);
const url = 'http://api.local.com/people?search=bob’;
const response = await request.GET(url);
expect(response).toMatchSnapShot();
});
Verification / Integration tests
Understand the implementation.
Tests focus on integration points.
Core functionality 80:20
Isolate the integration environment.
/shekhar-ramphal @shakes_test
Verification / Integration tests
Ringfenced namespace
/shekhar-ramphal @shakes_test
Test with actual dependencies
Test suite API
API
Dependencies
API
API
CI
DBMQ
Ringfenced namespace
/shekhar-ramphal @shakes_test
Verification / Integration tests
Test suite API
API
Dependencies
API
API
DBMQ
person
contact
details
bank
details
account
info
Hit all
dependencies
Core / critical
functionality
Contract tests
/shekhar-ramphal @shakes_test
All good to go… lets deploy
API
Development
/shekhar-ramphal @shakes_test
All good to go… lets deploy
API
Development
/shekhar-ramphal @shakes_test
Post deployment Smoke tests
Super happy day cases
Focus on GET endpoints to avoid manipulating data.
Check any 3rd party integration that couldn't be simulated.
/shekhar-ramphal @shakes_test
Now we can start testing...
API
Development
/shekhar-ramphal @shakes_test
API is stable in PROD
API API
Development Production
Tests:
Unit / Unit integration
Acceptance
Verification
Smoke
Do you keep testing a
microservice when code hasn't
changed in a while?
/shekhar-ramphal @shakes_test
Synthetics tests
Similar suite of Smoke tests.
Runs on a schedule.
Optimize for best execution time.
/shekhar-ramphal @shakes_test
test('Search people named Shekhar with few results', async () => {
const url = 'http://api.dev.com/people?search=Shekhar Ramphal’;
const response = await request.GET(url);
expect(response.code).toBe(200);
expect(response.code).not.toBeUndefined();
});
Checks run all the time
API
‘s‘s
‘s
‘s
‘s
/shekhar-ramphal @shakes_test
Data chaos monkey tests
Some things we just can't predict.
And our users are crazy.
Set random payloads or params.
Incorrect API usage.
Expect longer running tests.
Fetch data dynamically from DBs.
/shekhar-ramphal @shakes_test
Best data is PROD data
test('Update a random persons name', async () => {
const searchTerm = await getRandomNameFromDB();
const url = `http://api.dev.com/people?search=${searchTerm}`;
const response = await request.GET(url);
expect(response.body[0].name).toBe(searchTerm);
const updateUrl = `http://api.dev.com/people/${response.id}`;
const newName = await getRandomNameFromDB();
await request.PUT(updateUrl, {name: newName});
const updatedResponse = await request.GET(updateUrl);
expect(updatedResponse.body[0].name).toBe(newName);
});
/shekhar-ramphal @shakes_test
In sprint?
● Should be able to ask questions without knowing the details.
○ What are the sources for this endpoint ?
○ Does it handle errors ?
○ Which databases does it talk to ?
○ Are there underlying SPs / Views, can I test those directly ?
○ Async ? What does the sequence of events look like ?
● Understand the implementation at a high level.
● Put them down as tasks
In sprint?
● Write the tests, even if they don’t pass yet.
test.todo('Search people named bob');
test.todo('Search people named bob with failed bank call');
test.todo('Search people named bob with failed contact call');
test.todo('Search people named bob with failed account call');
test.todo('Search people with multiple results');
test.todo('Search people with no results');
test.todo('Search people with no bank details');
test.todo('Search people with missing mandatory fields from account');
Pipeline
Static code analysis,
unit/unit integration
tests all passed.
Built docker image
Acceptance DeployBuild
Verification
Smoke Synthetics
Chaos
monkey
/shekhar-ramphal @shakes_test
Recap
Static code analysis,
unit/unit integration
tests all passed.
Built docker image
Acceptance DeployBuild
Verification
Smoke Synthetics
Chaos
monkey
Tests functionality
Tests
connectivity
Tests deployment
Tests stability
Tests data
/shekhar-ramphal @shakes_test
Recap
Static code analysis,
unit/unit integration
tests all passed.
Built docker image
Acceptance DeployBuild
Verification
Smoke Synthetics
Chaos
monkey
Tests functionality
Tests
connectivity
Tests deployment
Tests stability
Tests data
/shekhar-ramphal @shakes_test
Does the latest API code do what is
expected of it?
Does the latest API code integrate with the
latest versions of all its dependencies?
Did the latest API code deploy to the
test environment correctly?
Is the API stable in the environment?
Does the API handle all of the weird data
permutations the users have created?
?
/shekhar-ramphal @shakes_test

5 levels of api test automation

  • 1.
    5 levels ofAPI test automation /shekhar-ramphal @shakes_test
  • 2.
    About me 13 years testing experience Fullstack tester /shekhar-ramphal @shakes_test
  • 3.
    Context Development / Testing TeamA Team C Team B Team E Team D /shekhar-ramphal @shakes_test
  • 4.
    Some key AllanGrayautomation testing principles Programmatic approach. ● Anyone can contribute as they build features. ● Test code lives with the feature code. Design the framework to be easily maintainable. ● Testers are at different levels. ● Consistency is king. Automation is a tool ● Automate to support testing not replace it. /shekhar-ramphal @shakes_test
  • 5.
  • 6.
    API test, sowhy 5 levels? test('Search people named shakes', async () => { const url = 'http://api.dev.com/people?search=shakes'; const response = await request.GET(url); expect(response.code).toBe(200); }); /shekhar-ramphal @shakes_test
  • 7.
    expect(response.body.length).toBeGreaterThan(0); expect(response.body[0].name).toContain('shakes'); }); Unpack a test test('Searchpeople named shakes', async () => { const url = 'http://api.dev.com/people?search=shakes'; const response = await request.GET(url); expect(response.code).toBe(200); API has been deployed to an env. I need legit data Should probably test different response codes… but how? Good idea to do more checks. Test ran fine 15 mins ago ??? Are there restrictions? Numbers? special chars? /shekhar-ramphal @shakes_test
  • 8.
    Levels What type oftests per level? What data to use? When do they run? ● Acceptance / Component tests ● Verification / Integration tests ● Smoke tests ● Synthetic tests ● Data chaos monkey tests Assumption that unit / unit integration tests have been done. /shekhar-ramphal @shakes_test
  • 9.
    Acceptance / componenttests Test suite API API Dependencies API API DBMQ /shekhar-ramphal @shakes_test
  • 10.
    Acceptance / componenttests Test suite API Dependencies CI DB Mock data Mock data Mock data P r o x y MQ /shekhar-ramphal @shakes_test
  • 11.
    Acceptance / componenttests Test suite API Dependencies CI DB Mock data Mock data Mock data P r o x y MQ /shekhar-ramphal @shakes_test
  • 12.
    Acceptance / componenttests Test suite API API Dependencies API API DBMQ person contact details bank details account info All methods GET, PUT, POST, DELETE Bad responses 5XXs 4XXs Data Scenarios Empty / null Missing data Combinations /shekhar-ramphal @shakes_test
  • 13.
    Mocking is great… Amazingtest scenario coverage. Tests pass consistently in this mocked world. /shekhar-ramphal @shakes_test test('Search people named bob with mocked dependencies', async () => { mockServer.loadFixtures([dependencyFixture1, dependencyFixture2, dependencyFixture3]); const url = 'http://api.local.com/people?search=bob’; const response = await request.GET(url); expect(response).toMatchSnapShot(); });
  • 14.
    Verification / Integrationtests Understand the implementation. Tests focus on integration points. Core functionality 80:20 Isolate the integration environment. /shekhar-ramphal @shakes_test
  • 15.
    Verification / Integrationtests Ringfenced namespace /shekhar-ramphal @shakes_test
  • 16.
    Test with actualdependencies Test suite API API Dependencies API API CI DBMQ Ringfenced namespace /shekhar-ramphal @shakes_test
  • 17.
    Verification / Integrationtests Test suite API API Dependencies API API DBMQ person contact details bank details account info Hit all dependencies Core / critical functionality Contract tests /shekhar-ramphal @shakes_test
  • 18.
    All good togo… lets deploy API Development /shekhar-ramphal @shakes_test
  • 19.
    All good togo… lets deploy API Development /shekhar-ramphal @shakes_test
  • 20.
    Post deployment Smoketests Super happy day cases Focus on GET endpoints to avoid manipulating data. Check any 3rd party integration that couldn't be simulated. /shekhar-ramphal @shakes_test
  • 21.
    Now we canstart testing... API Development /shekhar-ramphal @shakes_test
  • 22.
    API is stablein PROD API API Development Production Tests: Unit / Unit integration Acceptance Verification Smoke Do you keep testing a microservice when code hasn't changed in a while? /shekhar-ramphal @shakes_test
  • 23.
    Synthetics tests Similar suiteof Smoke tests. Runs on a schedule. Optimize for best execution time. /shekhar-ramphal @shakes_test test('Search people named Shekhar with few results', async () => { const url = 'http://api.dev.com/people?search=Shekhar Ramphal’; const response = await request.GET(url); expect(response.code).toBe(200); expect(response.code).not.toBeUndefined(); });
  • 24.
    Checks run allthe time API ‘s‘s ‘s ‘s ‘s /shekhar-ramphal @shakes_test
  • 25.
    Data chaos monkeytests Some things we just can't predict. And our users are crazy. Set random payloads or params. Incorrect API usage. Expect longer running tests. Fetch data dynamically from DBs. /shekhar-ramphal @shakes_test
  • 26.
    Best data isPROD data test('Update a random persons name', async () => { const searchTerm = await getRandomNameFromDB(); const url = `http://api.dev.com/people?search=${searchTerm}`; const response = await request.GET(url); expect(response.body[0].name).toBe(searchTerm); const updateUrl = `http://api.dev.com/people/${response.id}`; const newName = await getRandomNameFromDB(); await request.PUT(updateUrl, {name: newName}); const updatedResponse = await request.GET(updateUrl); expect(updatedResponse.body[0].name).toBe(newName); }); /shekhar-ramphal @shakes_test
  • 27.
    In sprint? ● Shouldbe able to ask questions without knowing the details. ○ What are the sources for this endpoint ? ○ Does it handle errors ? ○ Which databases does it talk to ? ○ Are there underlying SPs / Views, can I test those directly ? ○ Async ? What does the sequence of events look like ? ● Understand the implementation at a high level. ● Put them down as tasks
  • 28.
    In sprint? ● Writethe tests, even if they don’t pass yet. test.todo('Search people named bob'); test.todo('Search people named bob with failed bank call'); test.todo('Search people named bob with failed contact call'); test.todo('Search people named bob with failed account call'); test.todo('Search people with multiple results'); test.todo('Search people with no results'); test.todo('Search people with no bank details'); test.todo('Search people with missing mandatory fields from account');
  • 29.
    Pipeline Static code analysis, unit/unitintegration tests all passed. Built docker image Acceptance DeployBuild Verification Smoke Synthetics Chaos monkey /shekhar-ramphal @shakes_test
  • 30.
    Recap Static code analysis, unit/unitintegration tests all passed. Built docker image Acceptance DeployBuild Verification Smoke Synthetics Chaos monkey Tests functionality Tests connectivity Tests deployment Tests stability Tests data /shekhar-ramphal @shakes_test
  • 31.
    Recap Static code analysis, unit/unitintegration tests all passed. Built docker image Acceptance DeployBuild Verification Smoke Synthetics Chaos monkey Tests functionality Tests connectivity Tests deployment Tests stability Tests data /shekhar-ramphal @shakes_test Does the latest API code do what is expected of it? Does the latest API code integrate with the latest versions of all its dependencies? Did the latest API code deploy to the test environment correctly? Is the API stable in the environment? Does the API handle all of the weird data permutations the users have created?
  • 32.