Pywinauto自动化测试钉钉客户端

  • 效果
  • 前言
  • 一、什么是pywinauto?
  • 二、使用步骤
    • 1.安装
    • 2.启动客户端
  • 三、什么是PyQt5?
  • 四、使用步骤
    • 1.安装
    • 2.配置QtDesigner
  • 项目代码

效果




前言

一、什么是pywinauto?

中文官方文档
pywinauto是一组用于自动化Microsoft Windows GUI的python模块。 最简单的是,它允许您将鼠标和键盘操作发送到窗口对话框和控件。

二、使用步骤

1.安装

pip install pywinauto

2.启动客户端

代码如下(示例):

 self.app_path = "D:/package/DingDing/main/current/DingTalk.exe"app = Application(backend="uia").start(self.app_path)

三、什么是PyQt5?

官方文档
PyQt5 是Digia的一套Qt5应用框架与python的结合,同时支持2.x和3.x。本教程使用的是3.x。Qt库由Riverbank Computing开发,是最强大的GUI库之一。

四、使用步骤

1.安装

pip install PyQt5
pip install pyqt5-tools

2.配置QtDesigner

参考如何配置
代码如下(示例):

1.设计界面
在PyCharm中创建一个项目,然后点击“Tools”–“External Tools”–“QTDesinger”打开QT Desinger

2. 设计如下

保存,生成如下UI代码。
ui_mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>807</width><height>676</height></rect></property><property name="windowTitle"><string>Check Account</string></property><property name="styleSheet"><string notr="true"/></property><property name="unifiedTitleAndToolBarOnMac"><bool>false</bool></property><widget class="QWidget" name="centralwidget"><property name="styleSheet"><string notr="true"/></property><layout class="QGridLayout" name="gridLayout"><item row="0" column="0"><widget class="QTabWidget" name="tabWidget"><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property name="currentIndex"><number>2</number></property><property name="iconSize"><size><width>16</width><height>16</height></size></property><widget class="QWidget" name="tab_3"><property name="font"><font><family>Arial</family><pointsize>10</pointsize><weight>50</weight><bold>false</bold></font></property><attribute name="title"><string>Tool</string></attribute><widget class="QPushButton" name="pushButton_6"><property name="geometry"><rect><x>340</x><y>170</y><width>71</width><height>31</height></rect></property><property name="text"><string>RunButton</string></property></widget><widget class="QTextEdit" name="textEdit_11"><property name="geometry"><rect><x>70</x><y>20</y><width>641</width><height>131</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>9</pointsize><weight>50</weight><bold>false</bold></font></property></widget><widget class="QTextEdit" name="textEdit_12"><property name="geometry"><rect><x>70</x><y>220</y><width>641</width><height>341</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>9</pointsize><weight>50</weight><bold>false</bold></font></property></widget><widget class="QLabel" name="label_15"><property name="geometry"><rect><x>10</x><y>10</y><width>51</width><height>51</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize><weight>50</weight><bold>false</bold></font></property><property name="text"><string>Account</string></property></widget><widget class="QLabel" name="label_16"><property name="geometry"><rect><x>10</x><y>220</y><width>41</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize><weight>50</weight><bold>false</bold></font></property><property name="text"><string>Logs</string></property></widget></widget><widget class="QWidget" name="tab"><property name="tabletTracking"><bool>false</bool></property><attribute name="icon"><iconset theme="dsa"><normaloff>.</normaloff>.</iconset></attribute><attribute name="title"><string>Multiple</string></attribute><widget class="QLabel" name="label"><property name="geometry"><rect><x>10</x><y>20</y><width>51</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Excel</string></property></widget><widget class="QPushButton" name="pushButton"><property name="geometry"><rect><x>510</x><y>20</y><width>75</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="text"><string>Select</string></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>10</x><y>120</y><width>51</width><height>51</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Account</string></property></widget><widget class="QLabel" name="label_3"><property name="geometry"><rect><x>10</x><y>330</y><width>41</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Logs</string></property></widget><widget class="QPushButton" name="pushButton_2"><property name="geometry"><rect><x>360</x><y>280</y><width>81</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="text"><string>RunButton</string></property></widget><widget class="QTextEdit" name="textEdit_6"><property name="geometry"><rect><x>70</x><y>130</y><width>641</width><height>131</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>9</pointsize></font></property></widget><widget class="QTextEdit" name="textEdit_8"><property name="geometry"><rect><x>70</x><y>330</y><width>641</width><height>231</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>9</pointsize></font></property></widget><widget class="QLabel" name="label_14"><property name="geometry"><rect><x>10</x><y>70</y><width>51</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Zoom</string></property></widget><widget class="QPushButton" name="pushButton_5"><property name="geometry"><rect><x>510</x><y>70</y><width>75</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="text"><string>Select</string></property></widget><widget class="QLineEdit" name="lineEdit"><property name="geometry"><rect><x>70</x><y>19</y><width>411</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>9</pointsize></font></property></widget><widget class="QLineEdit" name="lineEdit_2"><property name="geometry"><rect><x>70</x><y>70</y><width>411</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>9</pointsize></font></property></widget><zorder>label</zorder><zorder>label_2</zorder><zorder>label_3</zorder><zorder>pushButton_2</zorder><zorder>pushButton</zorder><zorder>textEdit_6</zorder><zorder>textEdit_8</zorder><zorder>label_14</zorder><zorder>pushButton_5</zorder><zorder>lineEdit</zorder><zorder>lineEdit_2</zorder></widget><widget class="QWidget" name="tab_2"><attribute name="title"><string>Single</string></attribute><widget class="QLabel" name="label_4"><property name="geometry"><rect><x>10</x><y>70</y><width>61</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Username</string></property></widget><widget class="QLabel" name="label_5"><property name="geometry"><rect><x>10</x><y>120</y><width>61</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Password</string></property></widget><widget class="QLabel" name="label_6"><property name="geometry"><rect><x>10</x><y>171</y><width>121</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Buy A License</string></property></widget><widget class="QLabel" name="label_7"><property name="geometry"><rect><x>10</x><y>220</y><width>91</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>AccountType</string></property></widget><widget class="QLabel" name="label_8"><property name="geometry"><rect><x>400</x><y>70</y><width>54</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Role</string></property></widget><widget class="QLabel" name="label_9"><property name="geometry"><rect><x>400</x><y>110</y><width>71</width><height>51</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>UserType</string></property></widget><widget class="QLabel" name="label_10"><property name="geometry"><rect><x>400</x><y>160</y><width>54</width><height>51</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>K12(Y/N)</string></property></widget><widget class="QPushButton" name="pushButton_3"><property name="geometry"><rect><x>600</x><y>271</y><width>91</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="text"><string>RunButton</string></property></widget><widget class="QRadioButton" name="radioButton"><property name="geometry"><rect><x>270</x><y>171</y><width>81</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="text"><string>No</string></property></widget><widget class="QRadioButton" name="radioButton_2"><property name="geometry"><rect><x>150</x><y>171</y><width>71</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="text"><string>Yes</string></property><property name="checked"><bool>true</bool></property><property name="autoRepeat"><bool>false</bool></property></widget><widget class="QComboBox" name="comboBox"><property name="geometry"><rect><x>100</x><y>221</y><width>231</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property><property name="cursor"><cursorShape>ArrowCursor</cursorShape></property><item><property name="text"><string/></property></item><item><property name="text"><string>enterprise-activehost</string></property></item><item><property name="text"><string>Education</string></property></item><item><property name="text"><string>biz-enterprise</string></property></item><item><property name="text"><string>Single Pro (Named Host)</string></property></item><item><property name="text"><string>single pro+webinar</string></property></item><item><property name="text"><string>free with cc</string></property></item><item><property name="text"><string>free without cc</string></property></item><item><property name="text"><string>freetrail</string></property></item><item><property name="text"><string>ZR</string></property></item><item><property name="text"><string>pro(license&gt;1)</string></property></item><item><property name="text"><string>biz(license&lt;100)</string></property></item><item><property name="text"><string>API</string></property></item><item><property name="text"><string>free with CC (Free-type2)</string></property></item><item><property name="text"><string>free with CC (EDU - K12)</string></property></item></widget><widget class="QComboBox" name="comboBox_2"><property name="geometry"><rect><x>480</x><y>120</y><width>211</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property><item><property name="text"><string/></property></item><item><property name="text"><string>License</string></property></item><item><property name="text"><string>Basic</string></property></item><item><property name="text"><string>On-Prem</string></property></item></widget><widget class="QLabel" name="label_12"><property name="geometry"><rect><x>10</x><y>330</y><width>54</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Logs</string></property></widget><widget class="QTextEdit" name="textEdit_4"><property name="geometry"><rect><x>100</x><y>330</y><width>591</width><height>211</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property><property name="styleSheet"><string notr="true"/></property></widget><widget class="QComboBox" name="comboBox_3"><property name="geometry"><rect><x>480</x><y>70</y><width>211</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property><item><property name="text"><string/></property></item><item><property name="text"><string>owner</string></property></item><item><property name="text"><string>member</string></property></item></widget><widget class="QComboBox" name="comboBox_4"><property name="geometry"><rect><x>480</x><y>170</y><width>211</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property><item><property name="text"><string/></property></item><item><property name="text"><string>Yes</string></property></item><item><property name="text"><string>No</string></property></item></widget><widget class="QLabel" name="label_13"><property name="geometry"><rect><x>10</x><y>20</y><width>71</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>9</pointsize></font></property><property name="text"><string>Zoom Path</string></property></widget><widget class="QPushButton" name="pushButton_4"><property name="geometry"><rect><x>600</x><y>20</y><width>91</width><height>31</height></rect></property><property name="font"><font><family>Arial</family><pointsize>10</pointsize></font></property><property name="text"><string>Select</string></property></widget><widget class="QLineEdit" name="lineEdit_3"><property name="geometry"><rect><x>100</x><y>20</y><width>381</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property></widget><widget class="QLineEdit" name="lineEdit_4"><property name="geometry"><rect><x>100</x><y>70</y><width>271</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property></widget><widget class="QLineEdit" name="lineEdit_5"><property name="geometry"><rect><x>100</x><y>120</y><width>271</width><height>31</height></rect></property><property name="font"><font><family>Times New Roman</family><pointsize>10</pointsize></font></property></widget></widget></widget></item></layout></widget><widget class="QMenuBar" name="menubar"><property name="geometry"><rect><x>0</x><y>0</y><width>807</width><height>23</height></rect></property></widget><widget class="QStatusBar" name="statusbar"/></widget><resources/><connections/>
</ui>

转换为python代码
ui_mainwindow.py

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'ui_mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(807, 676)MainWindow.setStyleSheet("")MainWindow.setUnifiedTitleAndToolBarOnMac(False)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setStyleSheet("")self.centralwidget.setObjectName("centralwidget")self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)self.gridLayout.setObjectName("gridLayout")self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.tabWidget.setFont(font)self.tabWidget.setStyleSheet("")self.tabWidget.setIconSize(QtCore.QSize(16, 16))self.tabWidget.setObjectName("tabWidget")self.tab_3 = QtWidgets.QWidget()font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)font.setBold(False)font.setWeight(50)self.tab_3.setFont(font)self.tab_3.setObjectName("tab_3")self.pushButton_6 = QtWidgets.QPushButton(self.tab_3)self.pushButton_6.setGeometry(QtCore.QRect(340, 170, 71, 31))self.pushButton_6.setObjectName("pushButton_6")self.textEdit_11 = QtWidgets.QTextEdit(self.tab_3)self.textEdit_11.setGeometry(QtCore.QRect(70, 20, 641, 131))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(9)font.setBold(False)font.setWeight(50)self.textEdit_11.setFont(font)self.textEdit_11.setObjectName("textEdit_11")self.textEdit_12 = QtWidgets.QTextEdit(self.tab_3)self.textEdit_12.setGeometry(QtCore.QRect(70, 220, 641, 341))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(9)font.setBold(False)font.setWeight(50)self.textEdit_12.setFont(font)self.textEdit_12.setObjectName("textEdit_12")self.label_15 = QtWidgets.QLabel(self.tab_3)self.label_15.setGeometry(QtCore.QRect(10, 10, 51, 51))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)font.setBold(False)font.setWeight(50)self.label_15.setFont(font)self.label_15.setObjectName("label_15")self.label_16 = QtWidgets.QLabel(self.tab_3)self.label_16.setGeometry(QtCore.QRect(10, 220, 41, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)font.setBold(False)font.setWeight(50)self.label_16.setFont(font)self.label_16.setObjectName("label_16")self.tabWidget.addTab(self.tab_3, "")self.tab = QtWidgets.QWidget()self.tab.setTabletTracking(False)self.tab.setObjectName("tab")self.label = QtWidgets.QLabel(self.tab)self.label.setGeometry(QtCore.QRect(10, 20, 51, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label.setFont(font)self.label.setObjectName("label")self.pushButton = QtWidgets.QPushButton(self.tab)self.pushButton.setGeometry(QtCore.QRect(510, 20, 75, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.pushButton.setFont(font)self.pushButton.setObjectName("pushButton")self.label_2 = QtWidgets.QLabel(self.tab)self.label_2.setGeometry(QtCore.QRect(10, 120, 51, 51))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_2.setFont(font)self.label_2.setObjectName("label_2")self.label_3 = QtWidgets.QLabel(self.tab)self.label_3.setGeometry(QtCore.QRect(10, 330, 41, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_3.setFont(font)self.label_3.setObjectName("label_3")self.pushButton_2 = QtWidgets.QPushButton(self.tab)self.pushButton_2.setGeometry(QtCore.QRect(360, 280, 81, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.pushButton_2.setFont(font)self.pushButton_2.setObjectName("pushButton_2")self.textEdit_6 = QtWidgets.QTextEdit(self.tab)self.textEdit_6.setGeometry(QtCore.QRect(70, 130, 641, 131))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(9)self.textEdit_6.setFont(font)self.textEdit_6.setObjectName("textEdit_6")self.textEdit_8 = QtWidgets.QTextEdit(self.tab)self.textEdit_8.setGeometry(QtCore.QRect(70, 330, 641, 231))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(9)self.textEdit_8.setFont(font)self.textEdit_8.setObjectName("textEdit_8")self.label_14 = QtWidgets.QLabel(self.tab)self.label_14.setGeometry(QtCore.QRect(10, 70, 51, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_14.setFont(font)self.label_14.setObjectName("label_14")self.pushButton_5 = QtWidgets.QPushButton(self.tab)self.pushButton_5.setGeometry(QtCore.QRect(510, 70, 75, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.pushButton_5.setFont(font)self.pushButton_5.setObjectName("pushButton_5")self.lineEdit = QtWidgets.QLineEdit(self.tab)self.lineEdit.setGeometry(QtCore.QRect(70, 19, 411, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(9)self.lineEdit.setFont(font)self.lineEdit.setObjectName("lineEdit")self.lineEdit_2 = QtWidgets.QLineEdit(self.tab)self.lineEdit_2.setGeometry(QtCore.QRect(70, 70, 411, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(9)self.lineEdit_2.setFont(font)self.lineEdit_2.setObjectName("lineEdit_2")self.label.raise_()self.label_2.raise_()self.label_3.raise_()self.pushButton_2.raise_()self.pushButton.raise_()self.textEdit_6.raise_()self.textEdit_8.raise_()self.label_14.raise_()self.pushButton_5.raise_()self.lineEdit.raise_()self.lineEdit_2.raise_()icon = QtGui.QIcon.fromTheme("dsa")self.tabWidget.addTab(self.tab, icon, "")self.tab_2 = QtWidgets.QWidget()self.tab_2.setObjectName("tab_2")self.label_4 = QtWidgets.QLabel(self.tab_2)self.label_4.setGeometry(QtCore.QRect(10, 70, 61, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_4.setFont(font)self.label_4.setObjectName("label_4")self.label_5 = QtWidgets.QLabel(self.tab_2)self.label_5.setGeometry(QtCore.QRect(10, 120, 61, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_5.setFont(font)self.label_5.setObjectName("label_5")self.label_6 = QtWidgets.QLabel(self.tab_2)self.label_6.setGeometry(QtCore.QRect(10, 171, 121, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_6.setFont(font)self.label_6.setObjectName("label_6")self.label_7 = QtWidgets.QLabel(self.tab_2)self.label_7.setGeometry(QtCore.QRect(10, 220, 91, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_7.setFont(font)self.label_7.setObjectName("label_7")self.label_8 = QtWidgets.QLabel(self.tab_2)self.label_8.setGeometry(QtCore.QRect(400, 70, 54, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_8.setFont(font)self.label_8.setObjectName("label_8")self.label_9 = QtWidgets.QLabel(self.tab_2)self.label_9.setGeometry(QtCore.QRect(400, 110, 71, 51))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_9.setFont(font)self.label_9.setObjectName("label_9")self.label_10 = QtWidgets.QLabel(self.tab_2)self.label_10.setGeometry(QtCore.QRect(400, 160, 54, 51))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_10.setFont(font)self.label_10.setObjectName("label_10")self.pushButton_3 = QtWidgets.QPushButton(self.tab_2)self.pushButton_3.setGeometry(QtCore.QRect(600, 271, 91, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.pushButton_3.setFont(font)self.pushButton_3.setObjectName("pushButton_3")self.radioButton = QtWidgets.QRadioButton(self.tab_2)self.radioButton.setGeometry(QtCore.QRect(270, 171, 81, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.radioButton.setFont(font)self.radioButton.setObjectName("radioButton")self.radioButton_2 = QtWidgets.QRadioButton(self.tab_2)self.radioButton_2.setGeometry(QtCore.QRect(150, 171, 71, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.radioButton_2.setFont(font)self.radioButton_2.setChecked(True)self.radioButton_2.setAutoRepeat(False)self.radioButton_2.setObjectName("radioButton_2")self.comboBox = QtWidgets.QComboBox(self.tab_2)self.comboBox.setGeometry(QtCore.QRect(100, 221, 231, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.comboBox.setFont(font)self.comboBox.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))self.comboBox.setObjectName("comboBox")self.comboBox.addItem("")self.comboBox.setItemText(0, "")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox_2 = QtWidgets.QComboBox(self.tab_2)self.comboBox_2.setGeometry(QtCore.QRect(480, 120, 211, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.comboBox_2.setFont(font)self.comboBox_2.setObjectName("comboBox_2")self.comboBox_2.addItem("")self.comboBox_2.setItemText(0, "")self.comboBox_2.addItem("")self.comboBox_2.addItem("")self.comboBox_2.addItem("")self.label_12 = QtWidgets.QLabel(self.tab_2)self.label_12.setGeometry(QtCore.QRect(10, 330, 54, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_12.setFont(font)self.label_12.setObjectName("label_12")self.textEdit_4 = QtWidgets.QTextEdit(self.tab_2)self.textEdit_4.setGeometry(QtCore.QRect(100, 330, 591, 211))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.textEdit_4.setFont(font)self.textEdit_4.setStyleSheet("")self.textEdit_4.setObjectName("textEdit_4")self.comboBox_3 = QtWidgets.QComboBox(self.tab_2)self.comboBox_3.setGeometry(QtCore.QRect(480, 70, 211, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.comboBox_3.setFont(font)self.comboBox_3.setObjectName("comboBox_3")self.comboBox_3.addItem("")self.comboBox_3.setItemText(0, "")self.comboBox_3.addItem("")self.comboBox_3.addItem("")self.comboBox_4 = QtWidgets.QComboBox(self.tab_2)self.comboBox_4.setGeometry(QtCore.QRect(480, 170, 211, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.comboBox_4.setFont(font)self.comboBox_4.setObjectName("comboBox_4")self.comboBox_4.addItem("")self.comboBox_4.setItemText(0, "")self.comboBox_4.addItem("")self.comboBox_4.addItem("")self.label_13 = QtWidgets.QLabel(self.tab_2)self.label_13.setGeometry(QtCore.QRect(10, 20, 71, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(9)self.label_13.setFont(font)self.label_13.setObjectName("label_13")self.pushButton_4 = QtWidgets.QPushButton(self.tab_2)self.pushButton_4.setGeometry(QtCore.QRect(600, 20, 91, 31))font = QtGui.QFont()font.setFamily("Arial")font.setPointSize(10)self.pushButton_4.setFont(font)self.pushButton_4.setObjectName("pushButton_4")self.lineEdit_3 = QtWidgets.QLineEdit(self.tab_2)self.lineEdit_3.setGeometry(QtCore.QRect(100, 20, 381, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.lineEdit_3.setFont(font)self.lineEdit_3.setObjectName("lineEdit_3")self.lineEdit_4 = QtWidgets.QLineEdit(self.tab_2)self.lineEdit_4.setGeometry(QtCore.QRect(100, 70, 271, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.lineEdit_4.setFont(font)self.lineEdit_4.setObjectName("lineEdit_4")self.lineEdit_5 = QtWidgets.QLineEdit(self.tab_2)self.lineEdit_5.setGeometry(QtCore.QRect(100, 120, 271, 31))font = QtGui.QFont()font.setFamily("Times New Roman")font.setPointSize(10)self.lineEdit_5.setFont(font)self.lineEdit_5.setObjectName("lineEdit_5")self.tabWidget.addTab(self.tab_2, "")self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 807, 23))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)self.tabWidget.setCurrentIndex(2)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "Check Account"))self.pushButton_6.setText(_translate("MainWindow", "RunButton"))self.label_15.setText(_translate("MainWindow", "Account"))self.label_16.setText(_translate("MainWindow", "Logs"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Tool"))self.label.setText(_translate("MainWindow", "Excel"))self.pushButton.setText(_translate("MainWindow", "Select"))self.label_2.setText(_translate("MainWindow", "Account"))self.label_3.setText(_translate("MainWindow", "Logs"))self.pushButton_2.setText(_translate("MainWindow", "RunButton"))self.label_14.setText(_translate("MainWindow", "Zoom"))self.pushButton_5.setText(_translate("MainWindow", "Select"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Multiple"))self.label_4.setText(_translate("MainWindow", "Username"))self.label_5.setText(_translate("MainWindow", "Password"))self.label_6.setText(_translate("MainWindow", "Buy A License"))self.label_7.setText(_translate("MainWindow", "AccountType"))self.label_8.setText(_translate("MainWindow", "Role"))self.label_9.setText(_translate("MainWindow", "UserType"))self.label_10.setText(_translate("MainWindow", "K12(Y/N)"))self.pushButton_3.setText(_translate("MainWindow", "RunButton"))self.radioButton.setText(_translate("MainWindow", "No"))self.radioButton_2.setText(_translate("MainWindow", "Yes"))self.comboBox.setItemText(1, _translate("MainWindow", "Enterprise-activehost"))self.comboBox.setItemText(2, _translate("MainWindow", "Education"))self.comboBox.setItemText(3, _translate("MainWindow", "Biz-enterprise"))self.comboBox.setItemText(4, _translate("MainWindow", "Single Pro (Named Host)"))self.comboBox.setItemText(5, _translate("MainWindow", "Single Pro+webinar"))self.comboBox.setItemText(6, _translate("MainWindow", "Free with cc"))self.comboBox.setItemText(7, _translate("MainWindow", "Free without cc"))self.comboBox.setItemText(8, _translate("MainWindow", "Freetrail"))self.comboBox.setItemText(9, _translate("MainWindow", "ZR"))self.comboBox.setItemText(10, _translate("MainWindow", "Pro(license>1)"))self.comboBox.setItemText(11, _translate("MainWindow", "Biz(license<100)"))self.comboBox.setItemText(12, _translate("MainWindow", "API"))self.comboBox.setItemText(13, _translate("MainWindow", "Free with CC (Free-type2)"))self.comboBox.setItemText(14, _translate("MainWindow", "Free with CC (EDU-K12)"))self.comboBox_2.setItemText(1, _translate("MainWindow", "License"))self.comboBox_2.setItemText(2, _translate("MainWindow", "Basic"))self.comboBox_2.setItemText(3, _translate("MainWindow", "On-Prem"))self.label_12.setText(_translate("MainWindow", "Logs"))self.comboBox_3.setItemText(1, _translate("MainWindow", "Owner"))self.comboBox_3.setItemText(2, _translate("MainWindow", "Member"))self.comboBox_4.setItemText(1, _translate("MainWindow", "Yes"))self.comboBox_4.setItemText(2, _translate("MainWindow", "No"))self.label_13.setText(_translate("MainWindow", "Zoom Path"))self.pushButton_4.setText(_translate("MainWindow", "Select"))self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Single"))

项目代码


main.py

# -*- coding: utf-8 -*-
import os
import sys
import time
import threadingfrom mainwindow import MainWindow
from PyQt5.QtWidgets import QApplicationparent_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(parent_path)class RunGUI(object):"""运行GUI界面"""def gui_start(self):"""启动gui界面"""app = QApplication(sys.argv)  # QApplication采用事件循环机制,当QApplication初始化后,就进入应用程序的主循环main_window = MainWindow()  # 打开主界面main_window.show()  # 显示主界面sys.exit(app.exec_())  # sys.exit()函数可以结束一个应用程序,使应用程序在主循环中退出。def create_thread(self, func, *args):"""将函数放入线程中执行"""t = threading.Thread(target=func, args=args)  # 创建线程t.setDaemon(True)  # 守护线程t.start()  # 启动线程def run(self):self.create_thread(self.gui_start)  # 将GUI界面放到守护线程中运行while True:time.sleep(1)print(len(threading.enumerate()))if len(threading.enumerate()) < 2:  # 当只剩下1个线程时,即GUI线程关闭,主线程退出breakif __name__ == '__main__':r = RunGUI()r.run()

mainwindow.py

# coding: utf-8
import os
import xlrd
from PyQt5 import QtWidgets
from PyQt5.QtGui import QTextCursorfrom thread_work import WorkThread
from ui_mainwindow import Ui_MainWindow
from PyQt5.QtWidgets import QMessageBox, QWidget, QMainWindowclass MainWindow(QMainWindow, Ui_MainWindow):"""GUI主界面操作"""def __init__(self):"""初始化"""super(MainWindow, self).__init__()  # super().__init__()继承父类的init方法self.setupUi(self)  # 初始化窗口self.app_path = None  # app路径self.account_lists = []  # 账号listself.account_path = None  # 账号路径self.thread = None  # 初始化线程self.log_msg = ""  # 简单界面log日志# 绑定多账号按钮点击事件self.pushButton.clicked.connect(self.get_multiple_file_path)  # 绑定账号文件选择按钮点击事件self.pushButton_5.clicked.connect(self.get_multiple_app_path)  # 绑定app选择按钮点击事件self.pushButton_2.clicked.connect(self.multiple_run_button)  # 绑定运行按钮点击事件# 绑定单账号按钮点击事件self.pushButton_3.clicked.connect(self.single_run_button)  # 绑定运行按钮点击事件self.pushButton_4.clicked.connect(self.get_single_app_path)  # 绑定app选择按钮点击事件# 绑定多账号简单界面按钮点击事件self.pushButton_6.clicked.connect(self.simple_run_button)  # 绑定app选择按钮点击事件def simple_run_button(self):"""多账号简单界面点击运行按钮"""self.pushButton_6.setEnabled(False)app_path = os.getenv("APPDATA") + "\\Zoom\\bin\\Zoom.exe"  # 获取app路径self.account_path = os.getcwd() + "\\Zoom.xlsx"  # 获取账号文件路径self.get_account()self.thread = WorkThread()  # 初始化一条线程self.thread.account_lists = self.account_lists  # 将账号list传给线程self.thread.app_path = app_path  # 将 app path 传给线程if app_path:self.thread.sinOut.connect(self.simple_output)  # 绑定信号槽,获取信号self.thread.complete_sinOut.connect(self.simple_complete_sinOut)self.thread.start()  # 开启线程else:w = QWidget()QMessageBox.about(w, 'Error', 'Failed to get Zoom.exe path')self.pushButton_6.setEnabled(True)def simple_complete_sinOut(self, msg):"""多账号简单界面完成信号槽信息"""w = QWidget()QMessageBox.about(w, 'Success', 'All account test completed')self.pushButton_6.setEnabled(True)def simple_output(self, msg):"""多账号简单界面信号槽信息"""res = self.account_msg(msg[0])  # 拼接账号信息显示框展示内容self.textEdit_11.setText(res)log = self.logs_msg(msg[1])  # 拼接账号信息显示框展示内容self.log_msg += logself.textEdit_12.setText(self.log_msg)self.move_cursor(self.textEdit_12)  # 移动光标到文档最后self.pushButton_6.setEnabled(False)def get_multiple_file_path(self):"""多账号界面获取账号文件信息"""account_path, file_type = QtWidgets.QFileDialog.getOpenFileName(None, "选取账号文件",os.getcwd() + "\\Zoom.xlsx", )  # 打开文件选择框if str(account_path).strip() == "" or str(account_path).split(".")[-1] != "xlsx":w = QWidget()QMessageBox.about(w, 'Error', 'The file is not xlsx')  # 提示框self.account_path = ''self.lineEdit.setText(self.account_path)  # 设置输入框valueelse:self.account_path = account_pathself.lineEdit.setText(self.account_path)def get_multiple_app_path(self):"""多账号界面获取app路径"""if self.account_path:self.get_account()  # 调用读取账号文件函数获取所有账号listapp_path, file_type = QtWidgets.QFileDialog.getOpenFileName(None, "选取Zoom软件", os.getenv("APPDATA") + "\\Zoom\\bin\\Zoom.exe", )  # 路径if str(app_path).strip() == "" or app_path.split("/")[-1] != "Zoom.exe":w = QWidget()QMessageBox.about(w, 'Error', 'The file is not Zoom.exe')self.app_path = ''self.lineEdit_2.setText(self.app_path)else:self.lineEdit_2.setText(app_path)self.app_path = app_pathelse:w = QWidget()QMessageBox.about(w, 'Error', 'Please select the account path')self.pushButton_2.setEnabled(True)  # 设置按钮可点击状态def multiple_run_button(self):"""多账号界面点击运行按钮"""self.pushButton_2.setEnabled(False)self.thread = WorkThread()  # 初始化一条线程self.thread.account_lists = self.account_lists  # 将账号list传给线程self.thread.app_path = self.app_path  # 将 app path 传给线程if self.app_path:self.thread.sinOut.connect(self.multiple_output)  # 绑定信号槽,获取信号self.thread.complete_sinOut.connect(self.multiple_complete_sinOut)self.thread.start()  # 开启线程else:w = QWidget()QMessageBox.about(w, 'Error', 'Please select the Zoom.exe path')self.pushButton_2.setEnabled(True)def multiple_complete_sinOut(self, msg):"""多账号界面完成信号槽信息"""w = QWidget()QMessageBox.about(w, 'Success', 'All account test completed')self.pushButton_2.setEnabled(True)def multiple_output(self, msg):"""多账号界面信号槽信息"""res = self.account_msg(msg[0])  # 拼接账号信息显示框展示内容self.textEdit_6.setText(res)log = self.logs_msg(msg[1])  # 拼接账号信息显示框展示内容self.log_msg += logself.textEdit_8.setText(self.log_msg)self.move_cursor(self.textEdit_8)  # 移动光标到文档最后self.pushButton_2.setEnabled(False)def get_single_app_path(self):"""单账号界面获取app路径"""app_path, file_type = QtWidgets.QFileDialog.getOpenFileName(None, "选取Zoom软件",os.getenv("APPDATA") + "\\Zoom\\bin\\Zoom.exe", )if str(app_path).strip() == "" or app_path.split("/")[-1] != "Zoom.exe":w = QWidget()QMessageBox.about(w, 'Error', 'The file is not Zoom.exe')self.app_path = ''self.lineEdit_3.setText(self.app_path)else:self.lineEdit_3.setText(app_path)self.app_path = app_pathdef single_run_button(self):"""单账号界面点击运行按钮"""if self.app_path:self.pushButton_3.setEnabled(False)account_dict = {}username = self.lineEdit_4.text().replace(' ', '')  # 获取输入框信息password = self.lineEdit_5.text().replace(' ', '')buy_a_license_yes = self.radioButton_2.isChecked()  # 获取单选框是否被选择account_type = self.comboBox.currentText()  # 获取复选框当前选择信息user_type = self.comboBox_2.currentText()role = self.comboBox_3.currentText()k12 = self.comboBox_4.currentText()if buy_a_license_yes:buy_a_license = "Yes"else:buy_a_license = "No"if self.check_value(username, "Username") and self.check_value(password, "Password") and self.check_value(account_type, "AccountType") and self.check_value(user_type, "UserType") and \self.check_value(role, "Role") and self.check_value(k12, "K12"):  # 判断所有信息是否都填写完毕account_dict["AccountType"] = account_typeaccount_dict["Role"] = roleaccount_dict["UserType"] = user_typeaccount_dict["K12"] = k12account_dict["UserName"] = usernameaccount_dict["PassWord"] = passwordaccount_dict["BuySign"] = buy_a_licenseself.account_lists.append(account_dict)self.thread = WorkThread()self.thread.account_lists = self.account_listsself.thread.app_path = self.app_pathself.thread.sinOut.connect(self.single_output)self.thread.start()else:w = QWidget()QMessageBox.about(w, 'Error', 'Please select the Zoom.exe path')self.pushButton_3.setEnabled(True)def single_output(self, msg):"""单账号界面信号槽信息"""log = self.logs_msg(msg[1])  # 拼接账号信息显示框展示内容self.log_msg += logself.textEdit_4.setText(self.log_msg)self.pushButton_3.setEnabled(True)def check_value(self, msg, name):"""校验单账号界面,输入框、单选框、多选框等信息是否填写"""if msg.strip() == "":w = QWidget()QMessageBox.about(w, 'Error', 'Please input the %s' % name)self.pushButton_3.setEnabled(True)return Falseelse:return Truedef get_account(self):"""获取账号信息"""try:wb = xlrd.open_workbook(self.account_path)  # 打开excel文件table = wb.sheets()[0]  # 获取第一个sheetrows = table.nrows  # 总行数for i in range(1, rows):account_dict = {}row_values = table.row_values(i)account_type = row_values[0]role = row_values[1]user_type = row_values[2]k12 = row_values[3]username = row_values[4]password = row_values[5]buy_sign = row_values[6]account_dict["UserName"] = str(username).replace(' ', '')account_dict["PassWord"] = str(password).replace(' ', '')account_dict["BuySign"] = str(buy_sign).strip()account_dict["AccountType"] = str(account_type).strip()account_dict["Role"] = str(role).strip()account_dict["UserType"] = str(user_type).strip()account_dict["K12"] = str(k12).strip()self.account_lists.append(account_dict)return Trueexcept Exception as e:w = QWidget()  # 没有父类的widget将被作为窗口使用QMessageBox.about(w, 'Error', 'Failed to read account information in excel!')return Falsedef account_msg(self, msg):"""拼接账号信息显示框展示内容"""res = ""for k, v in msg.items():res += "<font color='black' size='3' style='line-height:2'><red><strong>" + str(k) + ":" + "</strong></font>" + \"<font color='black' size='3' style='line-height:2'><red>" + str(v) + "</font>" + "<br>"return resdef logs_msg(self, m):"""装饰日志框展示内容"""if str(m).__contains__("Fail") or str(m).__contains__("Error"):msg = "<font color='red' size='4' style='line-height:2'><red>" + str(m) + "</font>" + "<br>"else:msg = "<font color='black' size='3' style='line-height:2'><red>" + str(m) + "</font>" + "<br>"return msgdef move_cursor(self, edit):"""移动光标到文档最后"""edit.setText(self.log_msg)cursor = edit.textCursor()  # 获取logs框鼠标光标cursor.movePosition(QTextCursor.End)  # 光标移动到文档末尾edit.setTextCursor(cursor)  # 设置文档光标

thread_work.py

# -*- coding: utf-8 -*-
import timefrom PyQt5.QtCore import QThread, pyqtSignalfrom check_a_license import ZoomClientAutoTestclass WorkThread(QThread):"""工作线程"""sinOut = pyqtSignal(list)  # 信号槽:和UI主线程通讯, 数据类型str、int、list等complete_sinOut = pyqtSignal(str)  # 测试完成信号槽def __init__(self):"""初始化"""super(WorkThread, self).__init__()def run(self):"""线程运行"""for account_dict in self.account_lists:time.sleep(1)sin_out_list = []username = account_dict["UserName"]password = account_dict["PassWord"]buy_sign = account_dict["BuySign"]account_type = account_dict["AccountType"]user_type = account_dict["UserType"]k12 = account_dict["K12"]role = account_dict["Role"]sin_out_list.append(account_dict)try:z = ZoomClientAutoTest(self.app_path, account_type, role, user_type, k12, username, password, buy_sign)res = z.run()sin_out_list.append(str(res))except Exception as e:sin_out_list.append(" %s: Error" % username)self.sinOut.emit(sin_out_list)  # 发射信号到主界面self.complete_sinOut.emit("True")

check_a_license.py

# coding: utf-8
import pytesseract
import os, re, sys, time
import cv2, psutil
from PIL import ImageGrab
from log_module import LogClass
from pywinauto import keyboard, mouse
from pywinauto.application import Applicationparent_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(parent_path)class ZoomClientAutoTest(LogClass):"""ZoomClientAutoTest"""def __init__(self, app_path, account_type, role, user_type, k12, username, password, buy_sign):"""__init__"""LogClass.__init__(self, logName='ZoomClientAutoTest')self.setTimedRotatingFileHandler(fileName='ZoomClientAutoTest')  # 日志self.app_path = app_path  # zoom客户端路径self.img_path = parent_path + "\\IMG\\"  # 截图路径self.account_type = account_typeself.role = roleself.user_type = user_type  # 账号信息self.k12 = k12self.username = usernameself.password = passwordself.buy_sign = buy_signdef start_app(self):"""start_app"""app = Application(backend="uia").start(self.app_path)  # 启动程序return appdef get_PID(self, pName):"""获取 zoom.exe PID"""p = psutil.process_iter()for r in p:aa = str(r)f = re.compile(pName)if f.search(aa):PID = aa.split('pid=')[1].split(',')[0]return PIDelse:return Nonedef connect_app(self):"""根据 zoom PID 绑定程序"""PID = self.get_PID("Zoom.exe")# app = Application().connect(path=self.app_path)  # 程序路径绑定,常用方法app = Application().connect(process=PID)  # 用于连接已经启动的程序,注意会改变# app = Application().connect(handle=0x100A6E)  # 应用程序的窗口句柄,注意会改变# app = Application().connect(title_re="Zoom*", class_name="ZPFTEWndClass")  # 标题、类型等匹配return appdef click_before_login_sign_in(self, app):"""click_before_login_sign_in"""dlg_spec = app.window(class_name='ZPFTEWndClass')  # 定位窗口dlg_spec.wait("exists ready", timeout=5, retry_interval=3)  # 等到窗口真的开着time.sleep(1)dlg_spec.window(title=r'Sign In', control_type="Button").click()  # 点击Button控件,进入登录界面return dlg_specdef login_app(self, dlg_spec, username, password):"""login_app"""dlg_spec.wait("exists ready", timeout=5, retry_interval=3)  # 等到窗户真的开着time.sleep(1)keyboard.send_keys('^a^c')  # 全选并剪贴keyboard.send_keys(username)  # 输入用户名time.sleep(1)keyboard.send_keys('{VK_TAB}')  # 跳转输入框下一行keyboard.send_keys('^a^c')keyboard.send_keys(password)time.sleep(1)dlg_spec.window(title=r'Sign In', control_type="Button").click()def main_operation_zoom_interface(self, app, account_type, role, user_type, k12, username, password, buy_sign):zoom = app.window(class_name=r'ZPPTMainFrmWndClassEx')zoom.wait("exists ready", timeout=5, retry_interval=3)  # 等到窗户真的开着# zoom.print_control_identifiers()  # 打印详细的窗口信息zoom.window(title=r'最大化', control_type="Button").click()  # 注意定位到多个相同title,用control_type区分time.sleep(2)mouse.click(coords=(1895, 52))  # 鼠标点击头像  TODO:先写死time.sleep(2)coord = (1680, 585, 1885, 605)  # 截图  TODO:先写死im = ImageGrab.grab(coord)if os.path.exists(self.img_path) is False:os.makedirs(self.img_path)im.save(self.img_path + username + ".jpg")pytesseract.pytesseract.tesseract_cmd = parent_path + '\\Tesseract-OCR\\tesseract.exe'im = cv2.imread(self.img_path + username + ".jpg")im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)  # 灰度处理图片CONFIG = ("-l eng --oem 2 --psm 4")content = pytesseract.image_to_string(im_gray, config=CONFIG)  # 识别图片字母if str(buy_sign).lower().strip() == "no":if content == "":self.logger.info("AccountType:%s | Role:%s | UserType:%s | K12:%s | Username:%s | Password:%s |"" HaveBuyALicense?:%s | Content:%s | TestResult:%s" % (account_type, role, user_type, k12, username, password, buy_sign, content, "No"))result = " %s: Success" % usernameelse:self.logger.error("AccountType:%s | Role:%s | UserType:%s | K12:%s | Username:%s | Password:%s |"" HaveBuyALicense?:%s | Content:%s | TestResult:%s" % (account_type, role, user_type, k12, username, password, buy_sign, content, "Yes"))result = " %s: Fail" % usernameelse:if content == "":self.logger.error("AccountType:%s | Role:%s | UserType:%s | K12:%s | Username:%s | Password:%s |"" HaveBuyALicense?:%s | Content:%s | TestResult:%s" % (account_type, role, user_type, k12, username, password, buy_sign, content, "No"))result = " %s: Fail" % usernameelse:self.logger.info("AccountType:%s | Role:%s | UserType:%s | K12:%s | Username:%s | Password:%s |"" HaveBuyALicense?:%s | Content:%s | TestResult:%s" % (account_type, role, user_type, k12, username, password, buy_sign, content, "Yes"))result = " %s: Success" % usernametime.sleep(2)mouse.click(coords=(1895, 520))  # switch account TODO:To be optimizedtime.sleep(2)app.kill()return resultdef run(self):s_app = self.start_app()  # 注意:如果软件未启动,启动程序之前将账号退出登录并关闭窗口# self.connect_app() # 如果软件已启动,连接已经启动的程序 TODO:连接失败,暂不用dlg_spec = self.click_before_login_sign_in(s_app)self.login_app(dlg_spec, self.username, self.password)  # 登录客户端res = self.main_operation_zoom_interface(s_app, self.account_type, self.role, self.user_type, self.k12,self.username, self.password, self.buy_sign)return res

log_module.py

# coding: utf-8
import os
import sys
import datetime
import logging
from logging import handlersparent_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(parent_path)class LogClass(object):def __init__(self, logName="ete"):self.logName = logNameself.logger = logging.getLogger(self.logName)self.logger.setLevel(logging.DEBUG)self.now = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d")def setTimedRotatingFileHandler(self, path=parent_path + "\\logs", fileName="ete"):if os.path.exists(path) is False:os.makedirs(path)self.fileFullPath = os.path.join(path, self.now + '_' + fileName + ".log")self.Handlers = handlers.TimedRotatingFileHandler(self.fileFullPath, when='midnight', interval=1,backupCount=30)self.Handlers.setLevel(logging.DEBUG)self.formatter = logging.Formatter('[%(asctime)s][%(filename)s][%(lineno)s][%(levelname)s] - [%(message)s]', "%Y-%m-%d %H:%M:%S")self.Handlers.setFormatter(self.formatter)self.logger.addHandler(self.Handlers)return self.logger

基于PyQt5和Pywinauto自动化测试客户端相关推荐

  1. linux测试自动化,一种基于Linux系统下自动化测试RoCE性能的方法及系统与流程

    本发明涉及自动化测试的技术领域,特别涉及一种基于Linux系统下自动化测试roce性能的方法及其系统. 背景技术: 现在迅速发展的服务器行业,对网络服务性能提出了越来越高的要求.特别是在互联网行业以及 ...

  2. 论文python+selenium网页自动化测试论文_毕业设计(论文)-基于selenium的web自动化测试.docx...

    基于Selenium的Web自动化测试1 绪论1.1引言网络时代的到来和迅速普及,为软件产业带来了一场革命性的变化,基于Web的应用系统已经开始逐步取代原来的单机版应用系统,成为当前和未来的软件系统开 ...

  3. 基于PyQt5的图形化界面开发——模拟医院管理系统

    基于PyQt5的图形化界面开发--模拟医院管理系统 0. 前言 1. 需求分析 2. 挂号界面的思路.UI界面代码及相应触发函数 2.1 思路分析 2.2 ui_guahao.py 2.3 相应的触发 ...

  4. 基于PyQt5的图形化界面开发——Windows内存资源监视助手[附带编译exe教程]

    基于PyQt5的图形化界面开发--Windows内存资源监视助手[附带编译exe教程] 0. 前言 1. 资源信息获取函数--monitor.py 2. UI界面--listen.py 3. main ...

  5. 基于wsimport生成代码的客户端

    概述 wsimport是jdk自带的命令,可以根据wsdl文档生成客户端中间代码,基于生成的代码编写客户端,可以省很多麻烦. wsimport命令 wsimport的用法 wsimport [opti ...

  6. 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)

    最近看了关于XMPP的框架,以文本聊天为例,需要发送的消息为: <message type="chat" from="kang@server.com" t ...

  7. 基于PyQt5的快速开发框架QFramer

    2019独角兽企业重金招聘Python工程师标准>>> QFramer 是基于PyQt5的一款快速开发框架 ####1. 基于Qt/ PyQt /PySide开发GUI常用的开发方式 ...

  8. 基于python的界面自动化测试-基于Python语言的自动化测试实战第二章(上)

    原标题:基于Python语言的自动化测试实战第二章(上) 测试环境搭建 2.1 Windows 下的环境搭建 如果想要学习一门编程语言,对于新手来说只需到其官方网站上去下载最新版本安装即可,但对于想要 ...

  9. Python基于socket实现的TCP客户端

    ''' 基于socket实现的TCP客户端 '''import socket# 建立socket对象 # 参数一表示IP地址类型(AF_INET为IPV4,AF_INET6为IPV6),参数二表示连接 ...

最新文章

  1. explicit关键字
  2. Java基础之Comparable接口和Comparator接口的比较
  3. Effective Java读书笔记二:枚举和注解
  4. rostcm6情感分析案例分析_卷积情感分析
  5. 杂论架构—架构是一种设计 转。。。
  6. jquery的选择器之-表单对象属性过滤选择器
  7. CocoaPods 添加第三方库报错
  8. Django_modelform组件
  9. Intel600P三星sm951pm961nvme等固态硬盘安装WIN7教程
  10. 亚马逊 速卖通 Lazada 敦煌网测评自养号技巧知识
  11. R语言 常用的数据分析工具包
  12. 2022年0425 ICEM网格划分学习笔记
  13. HDU6080(很水的计算几何+floyd)
  14. 用Python写三级菜单的三个版本
  15. HTML+CSS实现一个淡显淡隐轮播图
  16. Imperva waf简介
  17. Telegram-This phone number is banned.手机号被禁止解决方法
  18. 信息安全是无价之宝 低代码平台安全机制全方位解密
  19. CPU数据预取对软件性能的影响
  20. DFA算法进行敏感词过滤

热门文章

  1. 多图预警!带你走进颠覆互联网企业的(2B)崇才科技
  2. mysql根据时分秒比较_MySQL的5种时间类型的比较
  3. 【汇正财经】短线波段操作怎样确定买入点?
  4. 微信是怎么防止xposed进行hook的
  5. 分布式系统治理-边车模式 sidecar
  6. java输入日期计算天数_JAVA计算输入一个日期到当前日期一共多少天
  7. 浅谈支付业务的分表方案
  8. Ant Design Vue日期选择器,禁止选择当前之前的时间
  9. h5 表单居中_div居中的几个方法 - 跛豪丶
  10. 接上传到php环境里运行即可,6个常用PHP运行环境一键安装包