Session info:
1. Intro API automation
Why?
1. faster result than API manual testing, faster than UI automation execution,
2. detect issues as soon as new changes added
3. reduce time and resource
4. reduce human errors
2. Current API automation framework is based on
- BDD with python testing framework
- asyncio, aiohttp, protobuf, pytest-bdd libs used for api automation
3. overview of entire repo (exclude workflows, soundbox feature). Protobuf - need
more info
4. Demo: order of implementation can be up to QA
protoc -> feature -> step definition -> builder
feature -> step definition -> protoc -> builder
feature -> protoc -> step definition -> builder
5. show postman, api manual testing, db verification
---------------------------------------------------
user_info > get_client_info.feature
Feature: Get Client Info API Tests
@p0
Scenario Outline: Verify user able to successfully call get client info API for
different client
When User call get client info api for <country> client
Then User should see get client info api response matches client record in
db
Examples:
| country |
| sg |
| my |
---------------------------------------------------
user_info > user_info.proto
syntax = "proto3";
package user_info.get_client_info;
message GetClientInfoRequest {
message Data {
string clientId = 1;
}
Data data = 1;
}
message GetClientInfoResponse {
message Result {
string clientId = 1;
string clientName = 2;
string userDisplayName = 3;
string id = 4;
string email = 5;
bool disabled = 6;
string createdAt = 7;
}
repeated Result result = 1;
}
Note:
1. copy paste request and response of API in https://codebeautify.org/json-to-
proto-converter ,get proto content and paste in .proto file
2. cd protobuf/user_info
3. run: protoc -I=. --pyi_out=. --python_out=. ./user_info.proto
4. user_info_pb2.pyi and user_info_pb2.py are generated
---------------------------------------------------
user_info > user_info_test.py
Step definition:
from pytest_bdd import scenarios, when, then, parsers
from helpers.builder.user_info.user_info_builder import UserInfoBuilder
from helpers.common.functions import *
scenarios("../../features/user_info/get_client_info.feature")
@when(parsers.parse('User call get client info api for {country} client'),
target_fixture='client_info_response')
def _(country) -> None:
userInfo = UserInfoBuilder(country)
client_info_response = userInfo.get_client_info_request()
print_log("Succesfully able to call client info API")
return client_info_response, country
@then('User should see get client info api response matches client record in db')
def _(local_run, client_info_response) -> None:
userInfo = UserInfoBuilder(client_info_response[1])
userInfo.verify_client_info_response(local_run, client_info_response[0])
print_log("Succesfully able to verify client info API response")
--------------------------------------------------
user_info > user_info_builder.py
from helpers.common.functions import *
import protobuf.user_info.user_info_pb2 as pb
from helpers.common.harness.rest import callAPI
from helpers.common.firebase.init_firestore import CreateFirestoreClient
from helpers.common.firebase.query import *
class UserInfoBuilder:
def __init__(self, country: str) -> None:
self.config = readConfig()
self.test_data = readConfig('configs/general/test_data.ini')
self.country = country
def get_client_info_request(self):
url = self.config['client.info']['base_url']
ClientInfoRequest = pb.GetClientInfoRequest()
ClientInfoRequest.data.clientId = self.test_data[f'{self.country}.client']
['clientId']
custom_headers = {'Authorization':'Bearer ' + getFirebaseAuthToken()}
print_log(f"Client info API url: \n{url}")
print_log(f"Client info API request:\
n{serialiseToJson(ClientInfoRequest)}")
response = callAPI(url, serialiseToJson(ClientInfoRequest), custom_headers)
print_log(f"Client info API response:\n{response[0]}")
response_value = serialiseToPb(response[0], pb.GetClientInfoResponse()),
response[1]
return response_value
def verify_client_info_response(self, local_run, client_info_response):
FireStoreClient = CreateFirestoreClient(local_run)
clientRecord = queryClientCollection(FireStoreClient.client,
self.test_data[f'{self.country}.client']['clientId'])
assert client_info_response[1] == 200
assert client_info_response[0].result[0].clientName == clientRecord[1][0]
['clientName']
assert client_info_response[0].result[0].email == clientRecord[1][0]
['contactEmail']
--------------------------------------------------
test_data.ini
[sg.client]
clientId = 8cWXfUQYLrcGzKwkf1f1
clientName = Jim Qashier Pte Ltd
[my.client]
clientId = BTIk9NqN4oz5COAbTy1M
clientName = Jim Qashier Pte Ltd MY
--------------------------------------------------
api_configuration
[client.info]
base_url = https://api.staging.qashier.com/v1/getClientUsersInfo
--------------------------------------------------
6. Execution:
pytest -m p0 steps/user_info/user_info_test.py --local_run=True --alluredir=allure-
report/testReport