Объяснение примера автоматизации интерфейса Python3+requests+unittest

Python

предисловие

В начале этого квартала руководство нашей компании выдвинуло требование всесторонне повысить технический уровень отдела, а так как важнейшая часть процесса разработки проекта - тестирование, у нас есть и свои технические занятия, поэтому для изменение исходного функционального бизнес-тестирования превращается в автоматизированное тестирование. Большая часть делалась раньше вручную, с помощью postman и fiddler для захвата пакетов и перехвата данных.Потом после всеобщего обсуждения было решено учиться на питоне и начать автоматизировать интерфейс.После всех стараний этот фреймворк автоматизации в основном был завершена. Поэтому сделаны некоторые резюме, чтобы облегчить будущий обзор и пересмотр. Есть много недостатков. Вы можете оставить сообщение, чтобы обсудить и изучить вместе и добиться прогресса вместе.

Прежде всего, мы можем взглянуть на мышление и подумать о процессе тестирования интерфейса.


Во-вторых, выберите правильный фреймворк

После того, как процесс ясен, нам нужно выбрать подходящий фреймворк, поэтому мы выбираем фреймворк Python3+requests+unittest.

Модуль «Запросы» отправляет сетевые http-запросы. Типы запросов в основном включают post, get, PUT, DELETE, HEAD.

Составление каркаса модульного тестирования Python + unittest и создание отчета о тестировании (HTMLTestRunner)

Подробное объяснение фреймворка здесь не повторяется, запросы могут относиться кНажмите, чтобы перейти

ссылка на юниттестНажмите, чтобы перейти

Основываясь на вышеизложенном, давайте построим наш фреймворк шаг за шагом. В этом процессе нам нужно разделить бизнес и данные, чтобы мы могли быть гибкими и достичь цели написания фреймворка. Далее разделим структуру.

Наша структура такая


data: хранить файлы данных, используемые в автоматических тестах

log: сохранить сгенерированный файл журнала

база: хранить общедоступные методы

отчет: сохранить сгенерированный автоматический отчет о тестировании

testcase: хранить тестовые скрипты

Далее, разработка общедоступных методов

Общая структура была разделена, а затем пришло время заполнить всю структуру шаг за шагом.Давайте сначала взглянем на общедоступные классы или функции в файле Base, которые в основном используются для последующих вызовов тестовых случаев.Все общедоступные и неизменяемые данные. Его можно разместить здесь для удобства обслуживания.

Документ конфигурации выглядит следующим образом

[DATABASE]
data_address = ./data/
report_address = ./report/

[HTTP]
base_url = http://xxx.xx

Хотите знать, как получить или записать соответствующие данные из файла конфигурации? Тогда продолжайте читать

import os
import configparser

# 获取当前py文件地址
proDir = os.path.split(os.path.realpath(__file__))[0]
# 组合config文件地址
configPath = os.path.join(proDir,"config.ini")

class ReadConfig:
    def __init__(self):
        #获取当前路径下的配置文件
        self.cf = configparser.ConfigParser()
        self.cf.read(configPath)

    def get_config(self,field,key):
        #获取配置文件中的key值
        result = self.cf.get(field,key)
        return result

    def set_config(self,field,key,value):
        #向配置文件中写入配置信息
        fb = open(configPath,'w')
        self.cf.set(field,key,value)
        self.cf.write(fb)

Тогда снова возникает вопрос, где наши тестовые данные? Как получить значение? Как писать? Как сэкономить? . . .

Не волнуйся, посмотри вниз

Тестовые данные предпочтительно размещать в Excel или базе данных.Вот краткое введение на примере Excel.

Здесь нужны две библиотеки для манипулирования таблицами, xlrd data-driven read, которая действует на документы excel, но xlrd не может записывать данные, поэтому вводится xlutils data-driven чтение и запись.

Метод установки можно установить с помощью pip3 install xlrd и pip3 install xlutils.

import xlrd
import xlutils.copy
from Base.readConfig import ReadConfig
import time

class ReadExcel:

    def __init__(self,section,field,sheet):
        # 打开工作表,并定位到sheet
        data_address = ReadConfig().get_config(section,field)
        workbook = xlrd.open_workbook(data_address)
        self.table = workbook.sheets()[sheet]


    def get_rows(self):
        # 获取excel行数
        rows = self.table.nrows
        return rows

    def get_cell(self,row,col):
        # 获取单元格数据
        cell_data = self.table.cell(row,col).value
        return cell_data

    def get_col(self,col):
        # 获取整列数据
        col_data = self.table.col_value(col)
        return col_data

class WriteExcel:
    def __init__(self,section,field,sheet):
        # 打开工作表
        self.address = ReadConfig().get_config(section,field)
        self.workbook = xlrd.open_workbook(self.address)
        self.wf = xlutils.copy.copy(self.workbook)
        self.ws = self.wf.get_sheet(sheet)

    def set_cell(self,row,col,value):
        #设置单元格数据
        self.ws.write(row,col,value)

    def save_excel(self,filename,format):
        #获取当前时间
        self.time = time.strftime("%Y%m%d%H%M%S", time.localtime())
        #生成文件的文件名及格式
        self.report = filename + '_' +self.time + format
        #保存文件
        self.wf.save(self.report)


Затем протестируйте редактирование скрипта

Все готово, ниже приведен простой и полный код для демонстрации вызова публичных функций, использования фреймворка и генерации отчетов.

import unittest
import requests
from Base.readConfig import ReadConfig
from Base.readExcel import ReadExcel
from Base.readExcel import WriteExcel
#实例化
readexcel = ReadExcel('DATABASE','data_address',0)
writeexcel = WriteExcel('DATABASE','data_address',0)

class testcase(unittest.TestCase):
    #初始化
    def setUp(self):
        #获取url
        self.base_url = ReadConfig().get_config('HTTP', 'base_url')
        self.url = self.base_url + readexcel.get_cell(1,1)
        #获取请求头
        self.headers = readexcel.get_cell(1,4)

    def test_case(self):
        nok = 0
        ner = 0
        # 循环读取excel中的测试数据,进行结果验证,并生成excel形式的测试报告
        for i in range(3,readexcel.get_rows()):
            #发送网络请求,得到响应值
            response = requests.post(self.url, headers=self.headers,   data=readexcel.get_cell(i,4).encode('utf-8'))
            actualresult = response.json()
            #获取excel中的预期结果
            expectresult = eval(readexcel.get_cell(i,6))
            # 获取需验证的数据
            key = eval(readexcel.get_cell(i, 5))
            keylen = len(key)
            j = 0
            for k in range(keylen):
                aresult = 'actualresult' + key[k]
                eresult = 'expectresult' + key[k]
                if eval(aresult) == eval(eresult):
                    #预期结果和实际结果一致
                    j = j + 1
            if j == keylen:
                #测试数据执行通过
                nok = nok + 1
                writeexcel.set_cell(i, 8, 'SUCCESS')
            else:
                # 测试数据执行失败,并将实际结果写入excel
                ner = ner + 1
                writeexcel.set_cell(i, 8, 'FAILURE')
                writeexcel.set_cell(i, 7, str(actualresult))
                print('第', i + 1, '行用例执行失败:预期结果是', expectresult, '实际结果是', actualresult)
            # 保存测试报告
            writeexcel.save_excel('testreport', '.xls')
            print('测试数据中总共', nok, '条用例执行通过', ner, '条用例执行失败')

    #释放资源
    def tearDown(self):
        pass

if __name__ == '__main__':
    #构造测试集合
    suite = unittest.TestSuite()
    suite.addTest(testcase('test_case'))
    #创建html文件
    filename = ReadConfig().get_config('DATABASE', 'report_address') + 'testreport.html'
    fb = open(filename,"wb")
    #执行测试并生成html测试报告
    runner = HTMLTestRunner.HTMLTestRunner(stream = fb,description = '针对接口的描述信息',title = '某某的自动化测试报告')
    runner.run(suite)
    #关闭文件
    fb.close()

Наконец, сгенерированный HTML-отчет


Выше приведены некоторые из недавно подведенных результатов. Надеюсь, они будут вам полезны. В будущем они будут обновляться. Пожалуйста, оставляйте много комментариев, чтобы общаться и расти вместе.