使用PyQt5实现自动化测试工具(正交表)

首先上点废话:

正交表例如L9(3^4),表1-1, 它表示需作9次实验,最多可观察4个因素,每个因素均为3水平。一个正交表中也可以各列的水平数不相等,我们称它为混合型正交表,如L8(4^1×2^4),表2-1 ,此表的5列中,有1列为4水平,4列为2水平。根据正交表的数据结构看出,正交表是一个n行c列的表,其中第j列由数码1,2,… Sj 组成,这些数码均各出现n/Sj 次,例如表1-1中,第二列的数码个数为3,S=3 ,即由1、2、3组成,各数码均出现3次。

大概意思就是:

现在有一软件,他可以在不同的环境下运行,而这些环境因子可以让程序正常运行或是崩溃,现在需要做出测试用例,能够让这些因素都能够被测完,如果是正常的正交,那么需要花费大量的用例才能够测完。现在,经过大量的实验得到了一个既能测完所有因素,又能尽可能地减少测试次数的正交表。

上点效果图:

效果图1

效果图2

生成的xlsx文件:

接下来上文件结构:

开始界面部分:

自个儿在QtDesigner拖拖拽拽,然后保存用pyuic来编译.ui文件成为.py文件,这时候生成的.py文件可以作为一个资源看待,还要另外创建一个uirun.py文件来让界面出来。

下面是uirun.py代码:

from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QInputDialog, qApp
from MainWindows import *
from PyQt5.QtCore import Qt
import re
from run import CreateXlsx
import pandas
import numpy
import getfilename
import sys


class MyMainWindow(QMainWindow, Ui_MainWindow):

    text = getfilename.get_data()
    head = re.findall(r'\d+\^[\d\D]*?=\d+', text)

    def __init__(self):
        super(MyMainWindow, self).__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(qApp.quit)
        self.btn_input.clicked.connect(self.btn_input_clicked)
        self.btn_help.clicked.connect(self.btn_help_clicked)
        self.combox_init()

    def combox_init(self):
        self.comboBox.addItem('')
        self.comboBox.addItems(self.head)
        self.comboBox.activated.connect(self.combox_change)

    def combox_change(self):
        if self.comboBox.currentIndex() == 0:
            return
        ldlist = re.findall(r'\d*\^\d*', self.comboBox.currentText())
        head = self.comboBox.currentText()
        lddict = {}
        mydict = {}


        #开始输入因子名
        for i in ldlist:
            tlist = i.split('^')
            lddict.update({int(tlist[0]): int(tlist[1])})
        namelist = []
        for key in lddict:
            a = []
            while len(a) != lddict[key]:
                text, ok = QInputDialog.getMultiLineText(self, "输入", "请输入%d水平%d因子的%d个因子名" %
                                                         (key, lddict[key], lddict[key]))
                if ok:
                    a = text.split('\n')
                    for i in range(0, a.count('')):  # 删除空字符
                        a.remove('')
                    self.comboBox.setEnabled(False)
                else:
                    self.comboBox.setEnabled(True)
                    return
                if len(a) != lddict[key]:
                    QMessageBox.information(self, '提示', '输入有误,请重新输入')
            namelist.extend(a)
        #结束输入因子名

        #开始输入水平变量名
        count = 0
        for key in lddict:
            i = 0
            while i != lddict[key]:
                text, ok = QInputDialog.getMultiLineText(self, "输入", "请输入%d水平%s因子的%d个水平变量" %
                                                         (key, namelist[count], key))
                if ok:
                    a = text.split('\n')
                    for j in range(0, a.count('')):  # 删除空字符
                        a.remove('')
                else:
                    self.comboBox.setEnabled(True)
                    return
                if len(a) == key:
                    for k in range(0, len(a)):
                        item = {str(count) + ',' + str(k): a[k]}
                        mydict.update(item)
                    count = count + 1
                else:
                    QMessageBox.information(self, '提示', '输入有误,请重新输入')
                    continue
                i = i + 1
        #结束输入水平变量名

        #创建xlsx文档
        xlsx = CreateXlsx(head, namelist, mydict, count)
        filename = xlsx.create()
        #结束创建

        self.write_table(filename)

    def btn_input_clicked(self):
        text, ok = QInputDialog.getMultiLineText(self, '输入因子和水平', '请输入因子和变量')
        if ok:
            #处理输入
            tlist = text.split('\n')
            tlist = self.remove_empty(tlist)
            for i in range(0, len(tlist)):
                tlist[i] = tlist[i].replace(':', ':')
            if ''.join(tlist).count(':') == 0:
                QMessageBox.information(self, '提示', '输入不符合规范!')
                return
            tlist = self.get_pure_list(tlist)
            tlist.sort(key=self.get_num_item)                       #排序,使输入规范化
            #处理输入

            namelist = []                                       #第二参数,用于存储因子名
            level = []                                          #用于记录水平变量
            for i in tlist:
                a = i.split(':')
                namelist.append(a[0])
                level.append(a[1])
            count = len(namelist)                               #第四参数,总因子数

            levelnum = []                                       #用于记录水平数
            for i in level:
                t = i.split(' ')
                t = self.remove_empty(t)
                levelnum.append(len(t))
            inhead = set()                                      #用于解析出数据头
            for i in levelnum:
                inhead.add(str(i) + '^' + str(levelnum.count(i)))
        else:
            return
        inhead = list(inhead)
        inhead.sort(key=lambda x: int(x.split('^')[0]), reverse=False)
        tmtext = "\n".join(self.head)
        pattern = " ".join(inhead)
        t = re.findall(pattern.replace('^', r'\^') + r' +n=\d+', tmtext)
        if len(t) == 0:
            QMessageBox.information(self, '提示', '抱歉!正交表中不存在对应方案!')
            return
        head = t[0]                                         #第一个参数

        mydict= {}                                                      #第三参数
        for i in range(0, count):
            for j in range(0, len(level[i].split(' '))):
                mydict.update({str(i) + ',' + str(j): level[i].split(' ')[j]})

        xlsx = CreateXlsx(head, namelist, mydict, count)
        filename = xlsx.create()
        self.write_table(filename)

    def remove_empty(self, olist):
        for i in range(0, olist.count('')):
            olist.remove('')
        return olist

    def get_pure_list(self, list):                  #获得处理后的列表,处理多余空格
        for i in range(0, len(list)):
            t = list[i].split(':')
            list[i] = t[0] + ':' + ' '.join(self.remove_empty(t[1].split(' ')))
        return list

    def get_num_item(self, item):                   #获得水平数,用于排序
        t = item.split(':')
        return len(t[1].split(' '))

    def write_table(self, filename):                #使xlsx文件显示在界面上
        # 读取文件
        input_xlsx = pandas.read_excel(filename)
        input_xlsx_rows = input_xlsx.shape[0]
        input_xlsx_cols = input_xlsx.shape[1]
        input_xlsx_header = input_xlsx.columns.values.tolist()

        # 设置行列表
        self.tableWidget.setColumnCount(input_xlsx_cols)
        self.tableWidget.setRowCount(input_xlsx_rows)
        self.tableWidget.setHorizontalHeaderLabels(input_xlsx_header)
        # 设置行列表

        # 开始写单元格
        for i in range(input_xlsx_rows):
            input_xlsx_rows_values = input_xlsx.iloc[[i]]
            input_xlsx_rows_values_array = numpy.array(input_xlsx_rows_values)
            input_xlsx_rows_values_list = input_xlsx_rows_values_array.tolist()[0]
            for j in range(input_xlsx_cols):
                input_xlsx_items_list = input_xlsx_rows_values_list[j]

                # 开始写到界面上
                input_xlsx_items = str(input_xlsx_items_list)
                newItem = QtWidgets.QTableWidgetItem(input_xlsx_items)
                newItem.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                self.tableWidget.setItem(i, j, newItem)
        QMessageBox.information(self, '提示', '已生成xlsx文件!')
        self.comboBox.setEnabled(True)

    def btn_help_clicked(self):
        with open(getfilename.get_path() + '/help', 'r') as f:
            text = f.read()
        QMessageBox.about(self, '帮助', text)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWin = MyMainWindow()
    myWin.show()
    sys.exit(app.exec_())

下面是代码运行部分:

run.py

from openpyxl import Workbook
import re
import getfilename
import time


class CreateXlsx:
    head = ''
    namelist = []
    mydict = {}
    count = 0

    def __init__(self, head, namelist, mydict, count):
        self.head = head
        self.namelist = namelist
        self.mydict = mydict
        self.count = count

    def create(self):
        text = getfilename.get_data()

        # 开始获取文件中的正交表
        pattern = self.head.replace('^', r'\^') + r'[\d\D]+?\n\n'
        temp = re.findall(pattern, text)[0]
        n = int(re.findall(r'n=\d+', temp)[0].split('=')[-1])
        content = re.findall(r'0[\d\D]*\n\n| 0[\d\D]*\n\n', temp)[0].split('\n')  # 正交表具体内容
        
        t = re.findall(r'\d{2}\^\d+', self.head)
        dbn = 0                                                                    # 拥有两位数水平数的因子数量
        for i in t:
            if int(i.split('^')[0]) > 10:                                           #大于10即有两位数
                dbn += int(i.split('^')[-1])
        for i in range(content.count('')):                                          #去除空字符
            content.remove('')
        insidelist = []
        dbstart_index = self.count - dbn
        print(dbstart_index)
        temp = ''
        for y in range(n):
            for x in range(self.count + dbn):
                if x >= dbstart_index:
                    if ((x - dbstart_index) % 2) == 0:
                        temp = content[y][x]
                    else:
                        temp += content[y][x]
                        insidelist.append(temp.replace(' ', ''))
                else:
                    insidelist.append(content[y][x])
        print(insidelist)
        wb = Workbook()
        ws = wb.active
        for x in range(0, self.count):
            ws.cell(1, x + 1, self.namelist[x])
        for y in range(0, n):
            for x in range(0, self.count):
                ws.cell(y + 2, x + 1, self.mydict[str(x) + ',' + insidelist[x + self.count * y]])
        unix_time = str(time.time())
        filename = unix_time + '.xlsx'
        wb.save(filename)
        return filename



getfilename.py

至于为什么要搞这玩意出来,那是因为在打包过后的exe需要的data数据不在.exe所在的文件路径下,而是在系统盘的临时文件夹中,可以通过判断来找出data在哪。

import os
import sys


def get_data():
    if os.path.isfile(sys.path[0]):
        filename = os.path.join(os.path.dirname(sys.path[0]), 'data')
    else:
        filename = os.path.join(sys.path[0], 'data')
    with open(filename, 'r') as f:
        text = f.read()
    return text

写完这小工具还用到了openxl写文件,pandas读xlsx文件,制作Ui时在MainWindow下进行layout可以实现窗口与控件一起缩放(以前压根不懂)

关于打包时的spec:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['uirun.py'],
             pathex=['F:\\Testtools'],
             binaries=[],
             datas=[('data','.'),('help','.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='uirun',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False , icon='tools.ico')

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值