1, Encapsulation and definition of interface process
to configure:
Obtain the initial configuration and dependencies according to the configuration file
Interface encapsulation
Encapsulate interface calls for abstract encapsulation
Similar to PageObject effect
operation flow
Business use case design contains the process definition formed by multiple APIs. Do not include any interface implementation details
Assert
1. The test framework contains
API object to complete the encapsulation of the interface
Interface testing framework to complete the driving of api
The configuration module completes the reading of the configuration file
Data encapsulation, data construction and data test case encapsulation
Utils: encapsulate other functions to improve the shortcomings of the native framework
Test case, call API object to realize business and assert
2.API objects include
Multi environment support:
Joint commissioning environment, test environment, pre release environment, online environment
3. Architecture management:
2, Test case design based on encryption interface
1. Environmental preparation
1. Create a json file and encrypt it with base64
json file:
base64 demo.json >demo.txt
Then start a service
python -m http.server 9999
Post startup access:
Principle of implementation:
Write a simple code:
import requests import json import base64 def test_code(): url="http://127.0.0.1:9999/demo.txt" r=requests.get(url=url) #print(r.text) #This is the encrypted ciphertext res=json.loads(base64.b64decode(r.content)) print(res) test_code()
This code needs to be optimized and encapsulated
After code optimization:
import requests import json import base64 class ApiRequest(): def send(self,data:dict): res=requests.request(data["method"],data["url"],headers=data["headers"]) if data["encoding"]=="base64": return json.loads(base64.b64decode(res.content)) #The following judgment is written casually. Return the encrypted value to the third-party service, let the third party decrypt it, and then return the decrypted information elif data["encoding"]=="private": return requests.post("url",data=res.content)
Run test:
from unittest import TestCase import unittest import test_request1 class TestApiRequest(TestCase): req_data = { "method": "get", "url": "http://127.0.0.1:9999/demo.txt", "headers": "None", "encoding": "base64" } def test_send(self): ar=test_request1.ApiRequest() print(ar.send(self.req_data)) if __name__ == '__main__': unittest.main()
3, Interface test in multi environment
Implementation principle:
Let's implement the above steps in code
envdemo.py: Script
import requests import yaml class Api: env=yaml.safe_load(open("env.yaml")) def send(self,data:dict): #data:dict reads the data in the dictionary data data["url"]=str(data["url"]).replace("tests",self.env["testing"][self.env["default"]])#Replace with the desired IP address r= requests.request(method=data["method"],url=data["url"],headers=data["headers"]) return r
test_envdemo.py: to run the test
from unittest import TestCase from testrequest.envdemo import Api class TestApi(TestCase): data = { "method": "get", "url": "http://tests:9999/demo. Txt ", # testing is replaced later "headers": None } def test_send(self): api=Api() re=api.send(self.data) print(re.text)
Note: env How to convert yaml files
import yaml def test_yaml2(): env={ "default":"dev", "testing":{ "dev":"127.0.0.1", "test":"127.0.0.2" } } #In order to convert the file into yaml file, I'm afraid I write it wrong with open("env.yaml","w")as f: yaml.safe_dump(data=env,stream=f) test_yaml2()
Then run to generate an env Yaml file
4, ApiObject mode and principle
Problems of traditional case
High coupling
Poor maintainability
Run api object mode to solve this problem
The idea is interlinked with PageObject
Isolate the changing and unchanging content
Interface details and services shall be separated
ApiObject principle:
Each public method represents the functionality provided by the interface
Don't expose the internal details of the api
Do not write assertions at the interface implementation layer
Each method returns other API objects or information used to make assertions
You don't need to implement every api
Application of api object mode:
Get of enterprise wechat_ Example of token interface
Enterprise wechat address:
https://work.weixin.qq.com/api/doc/90000/90135/91039
First, write a function with particularly high coupling
import requests class TestToken: corpid="ww93348658d7c66ef4" corp_secret="T0TFrXmGYel167lnkzEydsjl6bcDDeXVmkUnEYugKIW" def test_get_token(self): url="https://qyapi.weixin.qq.com/cgi-bin/gettoken" params={ "corpid":self.corpid, "corpsecret":self.corp_secret } r=requests.get(url=url,params=params) print(r.json()) assert r.json()["errcode"]==0 aa=TestToken() aa.test_get_token()
Then the idea of api object is transformed
get_token.py Code:
import requests #The api packpage represents the concrete implementation of all interface information, and a public method represents an interface class GetToken: corpid="ww93348658d7c66ef4" corp_secret="T0TFrXmGYel167lnkzEydsjl6bcDDeXVmkUnEYugKIW" def test_get_token(self): url="https://qyapi.weixin.qq.com/cgi-bin/gettoken" params={ "corpid":self.corpid, "corpsecret":self.corp_secret } r=requests.get(url=url,params=params) print(r.json()) return r
test_gettoken.py call test
import requests from unittest import TestCase import unittest from api.get_token import GetToken #testcases takes pytest as the testing framework, and a method is a case class TestToken(TestCase): #First instantiate gettoken def setUp(self): self.gettoken=GetToken() def test_get_token(self): assert self.gettoken.test_get_token().json()["errcode"]==0 if __name__ == '__main__': unittest.main()
General api encapsulation
The api above can also optimize the encapsulation
Operate through a case
Encapsulation of general interface protocol
Secondary encapsulation of http request
Introduction to BaseApi: it is equivalent to a parent class of all APIs. In this way, some general APIs can be put into this BaseApi
Principle of implementation:
1. Convert the sent request information into a dictionary structure
2. # use the python keyword to pass the request structure to requests request
Optimized code:
There is an additional baseapi method:
#Use the python keyword to pass the request structure to requests request import requests class BaseApi: def request_https(self,req_data): #It's equivalent to requests request(method="get",url=" https://qyapi.weixin.qq.com/cgi-bin/gettoken ",params="{"corpid": self.corpid,"corpsecret": self.corp_secret}") r=requests.request(**req_data)#Same as above return r
get_ token. The request method of Py is modified to:
import requests #The api packpage represents the concrete implementation of all interface information, and a public method represents an interface from testtoken2.api.baseapi import BaseApi class GetToken(BaseApi): corpid="ww93348658d7c66ef4" corp_secret="T0TFrXmGYel167lnkzEydsjl6bcDDeXVmkUnEYugKIW" def test_get_token(self): #Convert the request information into a standard dictionary structure req_data={ "method":"get", "url":"https://qyapi.weixin.qq.com/cgi-bin/gettoken", "params":{ "corpid":self.corpid, "corpsecret":self.corp_secret } } url="https://qyapi.weixin.qq.com/cgi-bin/gettoken" params={ "corpid":self.corpid, "corpsecret":self.corp_secret } #Call baseapi request method r =self.request_https(req_data) print(r.json()) return r
Run test cases:
from unittest import TestCase import unittest from testtoken2.api.get_token import GetToken #testcases takes pytest as the testing framework, and a method is a case class TestToken(TestCase): #First instantiate gettoken def setUp(self): self.gettoken=GetToken() def test_get_token(self): assert self.gettoken.test_get_token().json()["errcode"]==0 if __name__ == '__main__': unittest.main()