Pytest Interface Automation Test Framework Building Template

  • 2021-10-15 10:54:42
  • OfStack

auto_api_test

Development environment: Pycharm

Development language & Version: python 3.7. 8

Test Framework: Pytest, Test Report: Allure

Project source code Git address

Project directory structure

api imitates PO mode and abstracts the page class, which contains all the interfaces contained in the page and encapsulates them into methods for other modules to call directly config Profile Directory data Test Data Directory doc Document Storage Directory log Log report Test Report scripts Test Script Storage Directory tools tool class directory . gitignore git Ignore app. py Command Line Launch Entry pytest. ini pytest Test Framework Configuration File README. md development documentation

Code analysis

pytest.ini

Configuration file for the pytest framework


[pytest]
addopts = --html=../report/report.html  # pytest-html Report plug-in configuration  
;addopts = -s --alluredir report  # allure-pytest Report plug-in configuration 
testpaths = ./scripts  #  Set the use case directory identification name 
python_files = test*_*.py  #  Set the test file identification name 
python_classes = Test*  #  Set the test class identification name 
python_functions = test_*  #  Set the test method identification name 

app.py


#  Base routing ( Facilitate switching global base routes when the deployment environment changes )
BASE_URL = "http://xxxx.com"
#  Gets the absolute path of the script ( The script can be understood as the project path in the project root directory )
ABS_PATH = os.path.abspath(__file__)
BASE_DIR = os.path.dirname(ABS_PATH)

#  Execute the test case when the command line starts this script 
pytest.main(["scripts/"])

/config/config.json

Configuration file, currently contains global request header configuration, similar to the setting of global variables, can be read and written through the tool functions in tools
The specific parameters of the request header can be configured according to the requirements


{
 "headers": {
  "Host": "xxx.com",
  "Connection": "keep-alive",
  "Accept": "application/json, text/plain, */*",
  "Authorization": "xxxx",
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
  "Content-Type": "application/json;charset=UTF-8",
  "Origin": "http://xxx.com",
  "Referer": "http://xxx.com/",
  "Accept-Encoding": "gzip, deflate",
  "Accept-Language": "zh-CN,zh;q=0.9"
 }
}

/api/template_api.py

Page class template, including page interface request method (add, delete, modify and check) encapsulation, mainly in this definition of interface and request into the parameters and other content


#  Guide pack 
import app
import json
from tools.config_info import get_header


class TemplateAPI:
  # xx Add interface 
  api_add_url = app.BASE_URL + "/xxx/xxxx/add"
  # xx Modify interface 
  api_upd_url = app.BASE_URL + "/xxx/xxxx/upd"
  # xx Query interface 
  api_get_url = app.BASE_URL + "/xxx/xxxx/get"
  # xx Delete interface 
  api_del_url = app.BASE_URL + "/xxx/xxxx/del/{id}"

  # xx Add interface function implementation 
  def api_add(self, session, attr1, attr2):
    post_data = {
      "attr1": attr1,
      "attr2": attr2
    }
    return session.post(self.api_add_url, headers=get_header(), data=json.dumps(post_data))

  # xx Modify the interface function implementation 
  def api_upd(self, session, attr1, attr2):
    put_data = {
      "attr1": attr1,
      "attr2": attr2
    }
    return session.put(self.api_upd_url, headers=get_header(), data=json.dumps(put_data))

  # xx Implementation of query interface function 
  def api_get(self, session, attr1, attr2):
    params = {
      "attr1": attr1,
      "attr2": attr2
    }
    return session.get(self.api_get_url, headers=get_header(), params=params)

  # xx Delete interface function implementation 
  def api_del(self, session, uid):
    return session.delete(self.api_del_url.format(id=uid), headers=get_header())

/scripts/test_template.py

Test classes begin with Test, and test classes and test methods add allure decorators

Pre-test class method-initialize session object of requests request library and create corresponding page object

Post-test class method-close session object

Pre-test method-plus hibernation

Adding optional parameterized decorator in test method, calling page interface request method through page object, passing in session object of requests and necessary parameters needed by method, processing response result and asserting

The logger can be called by introducing tools


#  Guide pack 
import pytest
import requests
from time import sleep
from api.template_api import TemplateAPI
from tools.get_log import GetLog
from tools.read_file import read_json
import allure

#  Get Logger 
log = GetLog.get_log()


@allure.feature(' Test class template ')
class TestTemplate:
  session = None

  #  Initialization method 
  @classmethod
  def setup_class(cls):
    cls.session = requests.Session()  #  Initialization session Object 
    cls.template = TemplateAPI()

  #  End method 
  @classmethod
  def teardown_class(cls):
    cls.session.close()

  @classmethod
  def setup(cls):
    sleep(1.5)

  #  Test method 
  @allure.story(" Test method template -add")
  @pytest.mark.parametrize(("attr1", "attr2", "success", "expect"), read_json("test_add"))
  def test_add(self, attr1, attr2, success, expect):
    #  Add functionality API Call 
    response = self.template.api_add(self.session, attr1, attr2)
    #  Print log 
    log.info(" Add functionality - The status code is : {}".format(response.status_code))
    #  Assertion status code 
    assert response.status_code == expect, " Status code assertion failed "

  @allure.story(" Test method template -upd")
  @pytest.mark.parametrize(("attr1", "attr2", "success", "expect"), read_json("test_upd"))
  def test_upd(self, attr1, attr2, success, expect):
    #  Add functionality API Call 
    response = self.template.api_upd(self.session, attr1, attr2)
    #  Print log 
    log.info(" Modify function - The status code is : {}".format(response.status_code))
    #  Assertion status code 
    assert response.status_code == expect, " Status code assertion failed "

  @allure.story(" Test method template -get")
  @pytest.mark.parametrize(("attr1", "attr2", "success", "expect"), read_json("test_get"))
  def test_get(self, attr1, attr2, success, expect):
    #  Add functionality API Call 
    response = self.template.api_get(self.session, attr1, attr2)
    #  Print log 
    log.info(" Query function - The status code is : {}".format(response.status_code))
    #  Assertion status code 
    assert response.status_code == expect, " Status code assertion failed "

  @allure.story(" Test method template -del")
  @pytest.mark.parametrize(("uid", "success", "expect"), read_json("test_del"))
  def test_del(self, uid, success, expect):
    #  Add functionality API Call 
    response = self.template.api_del(self.session, uid)
    #  Print log 
    log.info(" Delete function - The status code is : {}".format(response.status_code))
    #  Assertion status code 
    assert response.status_code == expect, " Status code assertion failed "

/data | /tools

Test data and specific operation tool classes are customized as needed


Related articles: