精华内容
下载资源
问答
  • 在此之前呢,我还是要给大家几个建议,大家在接单的时候也可以注意一下: 程序员接私活的报价方式: 简单公示:项目工时*日薪+紧急程度+报价 这样有利于在报价的时候可以尽量多报一些价格,然而,客户那边在砍价...

    前言

    现如今,相信很多职场朋友都非常羡慕程序员的高薪工作吧,很多学习计算机专业的大学生,他们在毕业以后,往往通过自己的专业就能找到互联网公司的高薪工作,而作为一名程序员,他们的工作压力还是非常大的,有时候经常熬夜加班,可是有些程序员也会在工作之余接一些私活,赚取零花钱。

    在此之前呢,我还是要给大家几个建议,大家在接单的时候也可以注意一下:

    程序员接私活的报价方式:

    简单公示:项目工时*日薪+紧急程度+报价

    这样有利于在报价的时候可以尽量多报一些价格,然而,客户那边在砍价的时候,自己这边也是有理有据,有利于自己这边可以有更高的回报。注意:记得留个小bug,防止不给尾款,因为,小编以前也结果单,有些客户确实很刁蛮,自己并不是非常了解,喜欢乱指挥,就是拖着不给尾款。

    接私活的注意事项:

    1.需求要整明白
    2.保持沟通
    3.工期要整明白
    4.不要在上班的时间去做
    5.要有没有周末的心理准备

    程序员可以接单的平台

    说了一大堆,我这边呢介绍完在接活的时候要注意的一些事项和准备后,下一步就是我们的高潮啦——在哪可以接单:

    1.CODING  码市

    网址:http://codemart.com/

    码市 是 CODING 旗下的软件众包平台。
    基于云计算技术搭建的云端软件开发平台作为沟通和监管工具,快速连接开发者与需求方,提供专业项目经理进行项目全过程监控,旨在通过云端众包的方式提高软件交付的效率,帮助软件开发行业实现高效的资源匹配。

    2.开源众包

    网址: http://zb.oschina.net

    3.程序员客栈

      http://www.proginn.com/

    程序员可以从什么平台接私活?

    程序员可以从什么平台接私活?

    程序员客栈中国非常领先的自由工作平台,为中高端程序员、产品经理和设计师等等互联网相关人员提供稳定的线上工作机会,包括自由工作、远程工作和兼职工作,还支持按需雇佣,工作模式非常多,感兴趣的推荐大家尝试一下。

    虽然名称叫程序员客栈,但是除了程序员,像产品经理,设计师等等互联网相关人员,都能在上面找到适合自己的项目。感兴趣的可以体验一下。

    4.英选

     http://www.yingxuan.io/

    平台以定制开发外包服务为主,也是外包项目平台。

    程序员可以从什么平台接私活?

    5.开发邦

    http://www.kaifabang.com

    程序员可以从什么平台接私活?

    6.猿急送

    https://www.yuanjisong.com/

    程序员可以从什么平台接私活?

     

       7。人人开发

    rrkf.com

    程序员可以从什么平台接私活?

    8.我爱方案网

    http://www.52solution.com/

    我爱方案网认证体系正式上线,帮雇主区别优劣服务商

    我爱方案网认证体系正式上线,帮雇主区别优劣服务商

    我爱方案网一直坚持为电子行业服务,通过搭建健康的方案交易生态,促进电子行业发展。

    8.码易

    http://www.mayigeek.com/

     

    码易 (CodEase)是一款简单实用的代码查看软件,提供代码语法高亮功能(支持常见语言java,C,C++,VB,html,xml,javascript,css,SQL,python,bash,makefile,VHDL等等),方便在移动设备上随时随地查看代码。

    9.我要外包网

    http://www.51waibao.net

    我要外包网是以web2.0为基础的互联网在线工作平台(work2.0),基于互联网的工作模式,使我要外包网可以消除地理差异限制,在全国乃至全球形成一个跨地域的协作平台。不受空间地域的限制,为企业和个人提供免费的项目和软件合作等信息,整合全国乃至全世界的信息与资源,凝聚全人类的智慧推动科学与社会发展的进步。它也将不拘泥于工作形式,你可以随意选择喜爱的时间、地点,以最能激发灵感与热情的方式进行创作。它倡导一种全新的工作模式,使思考与工作融入到人类的生活中,在时间与空间日趋宝贵的现代社会,让人才和先机的把握成为你成功的支点。

    彩蛋

    这边呢,我给大家准备了很多的资料,方便大家更好的学习Python

    领取方式V: xxy12311007(备注CSDN)。

    展开全文
  • Python+mysql=接单管理系统 起因:接的单子越来越多,各种信息记录太麻烦,容易弄丢还不好统计 经过:闲得慌用python花了两个下午写了个自用的接单管理系统,复习一下pyqt5的使用 结果:就这样吧,懒得办了 思路就是...

    Python+mysql=接单管理系统

    起因:接的单子越来越多,各种信息记录太麻烦,容易弄丢还不好统计
    经过:闲得慌用python花了两个下午写了个自用的接单管理系统,复习一下pyqt5的使用
    结果:就这样吧,懒得办了
    思路就是本人太懒,所以直接上代码

    1. 主界面
    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file '主界面.ui'
    #
    # Created by: PyQt5 UI code generator 5.14.1
    #
    # WARNING! All changes made in this file will be lost!
    
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.setEnabled(True)
            MainWindow.resize(981, 779)
            font = QtGui.QFont()
            font.setBold(False)
            font.setItalic(False)
            font.setWeight(50)
            MainWindow.setFont(font)
            MainWindow.setToolTip("")
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.add_order = QtWidgets.QPushButton(self.centralwidget)
            self.add_order.setGeometry(QtCore.QRect(40, 140, 93, 28))
            font = QtGui.QFont()
            font.setFamily("隶书")
            font.setPointSize(12)
            font.setBold(False)
            font.setItalic(False)
            font.setWeight(50)
            self.add_order.setFont(font)
            self.add_order.setObjectName("add_order")
            self.delete_order = QtWidgets.QPushButton(self.centralwidget)
            self.delete_order.setGeometry(QtCore.QRect(760, 170, 93, 28))
            font = QtGui.QFont()
            font.setFamily("隶书")
            font.setPointSize(12)
            font.setBold(False)
            font.setItalic(False)
            font.setWeight(50)
            self.delete_order.setFont(font)
            self.delete_order.setObjectName("delete_order")
            self.label = QtWidgets.QLabel(self.centralwidget)
            self.label.setGeometry(QtCore.QRect(340, 10, 311, 71))
            font = QtGui.QFont()
            font.setFamily("华文新魏")
            font.setPointSize(29)
            font.setBold(False)
            font.setItalic(False)
            font.setWeight(50)
            self.label.setFont(font)
            self.label.setStyleSheet("color:rgb(0, 85, 255);")
            self.label.setFrameShape(QtWidgets.QFrame.NoFrame)
            self.label.setFrameShadow(QtWidgets.QFrame.Raised)
            self.label.setTextFormat(QtCore.Qt.AutoText)
            self.label.setObjectName("label")
            self.label_2 = QtWidgets.QLabel(self.centralwidget)
            self.label_2.setGeometry(QtCore.QRect(430, 700, 161, 20))
            font = QtGui.QFont()
            font.setFamily("Franklin Gothic Demi")
            font.setBold(False)
            font.setItalic(False)
            font.setWeight(50)
            self.label_2.setFont(font)
            self.label_2.setStyleSheet("color:rgb(25, 85, 25);")
            self.label_2.setFrameShape(QtWidgets.QFrame.NoFrame)
            self.label_2.setFrameShadow(QtWidgets.QFrame.Raised)
            self.label_2.setObjectName("label_2")
            self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
            self.tableWidget.setGeometry(QtCore.QRect(30, 220, 921, 461))
            self.tableWidget.setFrameShape(QtWidgets.QFrame.WinPanel)
            self.tableWidget.setFrameShadow(QtWidgets.QFrame.Raised)
            self.tableWidget.setLineWidth(3)
            self.tableWidget.setMidLineWidth(2)
            self.tableWidget.setDragEnabled(True)
            self.tableWidget.setObjectName("tableWidget")
            self.tableWidget.setColumnCount(8)
            self.tableWidget.setRowCount(0)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(0, item)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(1, item)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(2, item)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(3, item)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(4, item)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(5, item)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(6, item)
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(7, item)
            self.line_2 = QtWidgets.QFrame(self.centralwidget)
            self.line_2.setGeometry(QtCore.QRect(20, 140, 20, 71))
            self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
            self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.line_2.setObjectName("line_2")
            self.line_3 = QtWidgets.QFrame(self.centralwidget)
            self.line_3.setGeometry(QtCore.QRect(140, 140, 20, 71))
            self.line_3.setStyleSheet("color:rgb(235, 85, 0);")
            self.line_3.setFrameShape(QtWidgets.QFrame.VLine)
            self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.line_3.setObjectName("line_3")
            self.delete_num = QtWidgets.QLineEdit(self.centralwidget)
            self.delete_num.setGeometry(QtCore.QRect(860, 170, 71, 31))
            self.delete_num.setText("")
            self.delete_num.setObjectName("delete_num")
            self.line = QtWidgets.QFrame(self.centralwidget)
            self.line.setGeometry(QtCore.QRect(30, 130, 118, 20))
            self.line.setFrameShape(QtWidgets.QFrame.HLine)
            self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.line.setObjectName("line")
            self.line_4 = QtWidgets.QFrame(self.centralwidget)
            self.line_4.setGeometry(QtCore.QRect(30, 200, 118, 20))
            self.line_4.setFrameShape(QtWidgets.QFrame.HLine)
            self.line_4.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.line_4.setObjectName("line_4")
            self.shuxin = QtWidgets.QPushButton(self.centralwidget)
            self.shuxin.setGeometry(QtCore.QRect(40, 180, 81, 28))
            font = QtGui.QFont()
            font.setFamily("幼圆")
            font.setBold(True)
            font.setItalic(False)
            font.setUnderline(False)
            font.setWeight(75)
            self.shuxin.setFont(font)
            self.shuxin.setMouseTracking(False)
            self.shuxin.setStyleSheet("color: rgb(0, 0, 127);")
            self.shuxin.setAutoDefault(True)
            self.shuxin.setFlat(False)
            self.shuxin.setObjectName("shuxin")
            self.statics = QtWidgets.QToolButton(self.centralwidget)
            self.statics.setEnabled(False)
            self.statics.setGeometry(QtCore.QRect(170, 180, 101, 31))
            font = QtGui.QFont()
            font.setFamily("隶书")
            font.setPointSize(12)
            self.statics.setFont(font)
            self.statics.setCheckable(False)
            self.statics.setPopupMode(QtWidgets.QToolButton.DelayedPopup)
            self.statics.setAutoRaise(False)
            self.statics.setObjectName("statics")
            self.alert_order = QtWidgets.QPushButton(self.centralwidget)
            self.alert_order.setGeometry(QtCore.QRect(760, 130, 93, 28))
            font = QtGui.QFont()
            font.setFamily("隶书")
            font.setPointSize(12)
            self.alert_order.setFont(font)
            self.alert_order.setObjectName("alert_order")
            self.serach_edit = QtWidgets.QLineEdit(self.centralwidget)
            self.serach_edit.setGeometry(QtCore.QRect(370, 160, 211, 21))
            self.serach_edit.setEchoMode(QtWidgets.QLineEdit.Normal)
            self.serach_edit.setClearButtonEnabled(False)
            self.serach_edit.setObjectName("serach_edit")
            self.search_box = QtWidgets.QComboBox(self.centralwidget)
            self.search_box.setGeometry(QtCore.QRect(590, 160, 71, 22))
            font = QtGui.QFont()
            font.setFamily("隶书")
            font.setPointSize(11)
            font.setBold(True)
            font.setWeight(75)
            self.search_box.setFont(font)
            self.search_box.setObjectName("search_box")
            self.search_box.addItem("")
            self.search_box.addItem("")
            self.alert_edit = QtWidgets.QLineEdit(self.centralwidget)
            self.alert_edit.setGeometry(QtCore.QRect(860, 130, 71, 31))
            self.alert_edit.setObjectName("alert_edit")
            self.line_5 = QtWidgets.QFrame(self.centralwidget)
            self.line_5.setGeometry(QtCore.QRect(750, 110, 191, 20))
            self.line_5.setFrameShape(QtWidgets.QFrame.HLine)
            self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.line_5.setObjectName("line_5")
            self.line_6 = QtWidgets.QFrame(self.centralwidget)
            self.line_6.setGeometry(QtCore.QRect(750, 200, 191, 20))
            self.line_6.setFrameShape(QtWidgets.QFrame.HLine)
            self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.line_6.setObjectName("line_6")
            self.line_7 = QtWidgets.QFrame(self.centralwidget)
            self.line_7.setGeometry(QtCore.QRect(740, 120, 16, 91))
            self.line_7.setFrameShadow(QtWidgets.QFrame.Raised)
            self.line_7.setFrameShape(QtWidgets.QFrame.VLine)
            self.line_7.setObjectName("line_7")
            self.line_8 = QtWidgets.QFrame(self.centralwidget)
            self.line_8.setGeometry(QtCore.QRect(930, 120, 16, 91))
            self.line_8.setFrameShape(QtWidgets.QFrame.VLine)
            self.line_8.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.line_8.setObjectName("line_8")
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtWidgets.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 981, 26))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtWidgets.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
    
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            _translate = QtCore.QCoreApplication.translate
            MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
            self.add_order.setStyleSheet(_translate("MainWindow", "color: rgb(0, 0, 127);"))
            self.add_order.setText(_translate("MainWindow", "添加"))
            self.delete_order.setStyleSheet(_translate("MainWindow", "color: rgb(0, 0, 127);"))
            self.delete_order.setText(_translate("MainWindow", "删除"))
            self.label.setText(_translate("MainWindow", "订单管理系统"))
            self.label_2.setText(_translate("MainWindow", "Author——》YMING"))
            self.tableWidget.setSortingEnabled(True)
            item = self.tableWidget.horizontalHeaderItem(0)
            item.setText(_translate("MainWindow", "单号"))
            item = self.tableWidget.horizontalHeaderItem(1)
            item.setText(_translate("MainWindow", "单名"))
            item = self.tableWidget.horizontalHeaderItem(2)
            item.setText(_translate("MainWindow", "类型"))
            item = self.tableWidget.horizontalHeaderItem(3)
            item.setText(_translate("MainWindow", "价格"))
            item = self.tableWidget.horizontalHeaderItem(4)
            item.setText(_translate("MainWindow", "状态"))
            item = self.tableWidget.horizontalHeaderItem(5)
            item.setText(_translate("MainWindow", "成交日期"))
            item = self.tableWidget.horizontalHeaderItem(6)
            item.setText(_translate("MainWindow", "交货截至日期"))
            item = self.tableWidget.horizontalHeaderItem(7)
            item.setText(_translate("MainWindow", "备注"))
            self.delete_num.setPlaceholderText(_translate("MainWindow", "删除单号"))
            self.shuxin.setText(_translate("MainWindow", "刷新"))
            self.statics.setText(_translate("MainWindow", "统计分析"))
            self.alert_order.setStyleSheet(_translate("MainWindow", "color: rgb(0, 0, 127);"))
            self.alert_order.setText(_translate("MainWindow", "完成"))
            self.serach_edit.setPlaceholderText(_translate("MainWindow", "请键入搜索内容..."))
            self.search_box.setStyleSheet(_translate("MainWindow", "color: rgb(0, 0, 127);"))
            self.search_box.setItemText(0, _translate("MainWindow", "单号"))
            self.search_box.setItemText(1, _translate("MainWindow", "状态"))
            self.alert_edit.setPlaceholderText(_translate("MainWindow", "修改单号"))
    
    

    2.主界面后端

    import sys
    from qtpy import QtWidgets
    from database_handle import database_handle
    from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QHBoxLayout, QTableWidget, QMessageBox, QMenu, \
        QAction, QToolButton
    from 主界面 import Ui_MainWindow
    from 订单添加后端 import order_handle, QRegExpValidator, QRegExp, QIcon, Qt
    
    
    class main_window_handle(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super().__init__()
            self.setupUi()
    
        def update_table(self):
            dh = database_handle()
            data = dh.get_all()
            row = len(data)
            self.tableWidget.setRowCount(row)
            for i in range(len(data)):
                for j in range(len(data[i])):
                    item = QTableWidgetItem(str(data[i][j]))
                    self.tableWidget.setItem(i, j, item)
    
        def delete_data(self):
            dh = database_handle()
            if self.delete_num.text() != '':
                dh.delete(int(self.delete_num.text()))
                QMessageBox.information(self, '提示', f'订单:{int(self.delete_num.text())}删除成功!')
                self.delete_num.setText('')
            self.update_table()
    
        def alert_data(self):
            dh = database_handle()
            id = self.alert_edit.text()
            if id != '':
                dh.update(id)
                QMessageBox.information(self, '提示', f'订单:{int(id)}状态修改成功!')
            self.update_table()
    
        def setupUi(self, **kwargs):
            super().setupUi(self)
            self.setWindowTitle('订单管理系统')
            self.setWindowIcon(QIcon('images/ic.ico'))
            self.setFixedSize(1000, 746)
            self.delete_num.setValidator(QRegExpValidator(QRegExp('[0-9]+$')))
            self.alert_edit.setValidator(QRegExpValidator(QRegExp('[0-9]+$')))
            self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers)
            self.tableWidget.clicked.connect(self.update_table)
            self.shuxin.clicked.connect(self.update_table)
            self.delete_order.clicked.connect(self.delete_data)
            self.update_table()
            self.alert_tool_add()
            self.search_box.currentIndexChanged.connect(self.search)
            self.serach_edit.setText('待交')
            self.setWindowOpacity(0.95)
            self.add_order.setIcon(QIcon('images/add.ico'))
            self.alert_order.setIcon(QIcon('images/alert.ico'))
            self.delete_order.setIcon(QIcon('images/delete.ico'))
            self.shuxin.setIcon(QIcon('images/update.ico'))
            self.alert_order.clicked.connect(self.alert_data)
            self.setStyleSheet("#MainWindow{border-image:url(images/bj.png)}")
            op = QtWidgets.QGraphicsOpacityEffect()
            op.setOpacity(0.6)
            self.serach_edit.setGraphicsEffect(op)
            self.statics.setHidden(True)
    
        def search(self):
            type = self.search_box.currentText()
            content = self.serach_edit.text()
            if type == '状态':
                dh = database_handle()
                data = dh.get_state(content)
                row = len(data)
                self.tableWidget.setRowCount(row)
                for i in range(len(data)):
                    for j in range(len(data[i])):
                        item = QTableWidgetItem(str(data[i][j]))
                        self.tableWidget.setItem(i, j, item)
    
            if type == '单号':
                dh = database_handle()
                data = dh.get_id(content)
                row = len(data)
                self.tableWidget.setRowCount(row)
                for i in range(len(data)):
                    for j in range(len(data[i])):
                        item = QTableWidgetItem(str(data[i][j]))
                        self.tableWidget.setItem(i, j, item)
    
        def alert_tool_add(self):
            menu = QMenu(self.statics)
            action = QAction(QIcon('images/finish.ico'), '完成', menu)
            action.triggered.connect(lambda: print('ssss'))
            menu.addAction(action)
            menu.addSeparator()
            self.statics.setMenu(menu)
            self.statics.setPopupMode(QToolButton.MenuButtonPopup)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        mwh = main_window_handle()
        mwh.show()
        oh = order_handle()
        om = oh.mainwindow
        mwh.add_order.clicked.connect(om.show)
    
        sys.exit(app.exec_())
    
    

    3.订单添加页面

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file '订单添加.ui'
    #
    # Created by: PyQt5 UI code generator 5.14.1
    #
    # WARNING! All changes made in this file will be lost!
    
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.setWindowModality(QtCore.Qt.WindowModal)
            MainWindow.setEnabled(True)
            MainWindow.resize(1060, 746)
            font = QtGui.QFont()
            font.setFamily("华文楷体")
            font.setPointSize(12)
            font.setBold(True)
            font.setItalic(False)
            font.setWeight(75)
            MainWindow.setFont(font)
            MainWindow.setInputMethodHints(QtCore.Qt.ImhNone)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.label_3 = QtWidgets.QLabel(self.centralwidget)
            self.label_3.setGeometry(QtCore.QRect(540, 180, 41, 21))
            self.label_3.setObjectName("label_3")
            self.label_4 = QtWidgets.QLabel(self.centralwidget)
            self.label_4.setGeometry(QtCore.QRect(200, 320, 91, 21))
            self.label_4.setObjectName("label_4")
            self.label_5 = QtWidgets.QLabel(self.centralwidget)
            self.label_5.setGeometry(QtCore.QRect(540, 250, 91, 16))
            self.label_5.setObjectName("label_5")
            self.label_6 = QtWidgets.QLabel(self.centralwidget)
            self.label_6.setGeometry(QtCore.QRect(540, 320, 141, 21))
            self.label_6.setObjectName("label_6")
            self.label_7 = QtWidgets.QLabel(self.centralwidget)
            self.label_7.setGeometry(QtCore.QRect(200, 390, 101, 21))
            self.label_7.setObjectName("label_7")
            self.label_8 = QtWidgets.QLabel(self.centralwidget)
            self.label_8.setGeometry(QtCore.QRect(200, 500, 61, 16))
            self.label_8.setObjectName("label_8")
            self.label_2 = QtWidgets.QLabel(self.centralwidget)
            self.label_2.setGeometry(QtCore.QRect(200, 180, 50, 30))
            self.label_2.setObjectName("label_2")
            self.label = QtWidgets.QLabel(self.centralwidget)
            self.label.setGeometry(QtCore.QRect(200, 240, 51, 41))
            self.label.setObjectName("label")
            self.title = QtWidgets.QLabel(self.centralwidget)
            self.title.setGeometry(QtCore.QRect(460, 40, 211, 61))
            font = QtGui.QFont()
            font.setFamily("华文新魏")
            font.setPointSize(29)
            font.setBold(True)
            font.setItalic(False)
            font.setUnderline(False)
            font.setWeight(75)
            font.setStrikeOut(False)
            font.setKerning(True)
            self.title.setFont(font)
            self.title.setObjectName("title")
            self.order_number = QtWidgets.QLineEdit(self.centralwidget)
            self.order_number.setGeometry(QtCore.QRect(310, 180, 151, 21))
            self.order_number.setObjectName("order_number")
            self.order_name = QtWidgets.QLineEdit(self.centralwidget)
            self.order_name.setGeometry(QtCore.QRect(310, 250, 151, 21))
            self.order_name.setObjectName("order_name")
            self.order_type = QtWidgets.QComboBox(self.centralwidget)
            self.order_type.setGeometry(QtCore.QRect(700, 180, 151, 30))
            font = QtGui.QFont()
            font.setBold(False)
            font.setWeight(50)
            self.order_type.setFont(font)
            self.order_type.setObjectName("order_type")
            self.order_type.addItem("")
            self.order_type.addItem("")
            self.order_type.addItem("")
            self.order_type.addItem("")
            self.order_type.addItem("")
            self.order_type.addItem("")
            self.state = QtWidgets.QComboBox(self.centralwidget)
            self.state.setGeometry(QtCore.QRect(310, 390, 81, 22))
            font = QtGui.QFont()
            font.setBold(False)
            font.setWeight(50)
            self.state.setFont(font)
            self.state.setObjectName("state")
            self.state.addItem("")
            self.state.addItem("")
            self.state.addItem("")
            self.price = QtWidgets.QLineEdit(self.centralwidget)
            self.price.setGeometry(QtCore.QRect(310, 320, 151, 21))
            self.price.setObjectName("price")
            self.others = QtWidgets.QPlainTextEdit(self.centralwidget)
            self.others.setGeometry(QtCore.QRect(310, 440, 461, 131))
            self.others.setObjectName("others")
            self.end_date = QtWidgets.QDateTimeEdit(self.centralwidget)
            self.end_date.setGeometry(QtCore.QRect(700, 320, 194, 22))
            self.end_date.setDateTime(QtCore.QDateTime(QtCore.QDate(2020, 7, 1), QtCore.QTime(0, 0, 0)))
            self.end_date.setCalendarPopup(True)
            self.end_date.setObjectName("end_date")
            self.start_date = QtWidgets.QDateTimeEdit(self.centralwidget)
            self.start_date.setGeometry(QtCore.QRect(700, 250, 194, 22))
            self.start_date.setDateTime(QtCore.QDateTime(QtCore.QDate(2020, 7, 1), QtCore.QTime(0, 0, 0)))
            self.start_date.setCalendarPopup(True)
            self.start_date.setObjectName("start_date")
            self.submit = QtWidgets.QPushButton(self.centralwidget)
            self.submit.setGeometry(QtCore.QRect(490, 610, 91, 31))
            font = QtGui.QFont()
            font.setFamily("华文新魏")
            font.setPointSize(16)
            font.setBold(False)
            font.setWeight(50)
            self.submit.setFont(font)
            self.submit.setMouseTracking(False)
            self.submit.setObjectName("submit")
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtWidgets.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 1060, 26))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtWidgets.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
    
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            _translate = QtCore.QCoreApplication.translate
            MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
            self.label_3.setText(_translate("MainWindow", "类型"))
            self.label_4.setText(_translate("MainWindow", "成交价格"))
            self.label_5.setText(_translate("MainWindow", "成交日期"))
            self.label_6.setText(_translate("MainWindow", "交货截至日期"))
            self.label_7.setText(_translate("MainWindow", "交货状态"))
            self.label_8.setText(_translate("MainWindow", "备注"))
            self.label_2.setText(_translate("MainWindow", "单号"))
            self.label.setText(_translate("MainWindow", "单名"))
            self.title.setText(_translate("MainWindow", "订单添加"))
            self.order_number.setPlaceholderText(_translate("MainWindow", "请输入单号"))
            self.order_name.setPlaceholderText(_translate("MainWindow", "请输入单名"))
            self.order_type.setItemText(0, _translate("MainWindow", "Python"))
            self.order_type.setItemText(1, _translate("MainWindow", "C"))
            self.order_type.setItemText(2, _translate("MainWindow", "Java"))
            self.order_type.setItemText(3, _translate("MainWindow", "代考"))
            self.order_type.setItemText(4, _translate("MainWindow", "资料售卖"))
            self.order_type.setItemText(5, _translate("MainWindow", "代写设计报告"))
            self.state.setItemText(0, _translate("MainWindow", "待交"))
            self.state.setItemText(1, _translate("MainWindow", "完成"))
            self.state.setItemText(2, _translate("MainWindow", "失败"))
            self.price.setPlaceholderText(_translate("MainWindow", "请输入成交价"))
            self.end_date.setDisplayFormat(_translate("MainWindow", "yyyy-MM-dd"))
            self.start_date.setDisplayFormat(_translate("MainWindow", "yyyy-MM-dd"))
            self.submit.setText(_translate("MainWindow", "提交"))
    
    

    4.订单添加页面后端

    from 订单添加 import Ui_MainWindow
    import sys
    import pymysql
    from PyQt5.QtWidgets import QApplication, QMainWindow
    from PyQt5.Qt import *
    import time
    from PyQt5 import QtCore, QtGui
    
    
    class order_handle():
        def __init__(self):
            self.mainwindow = QMainWindow()
            self.um = Ui_MainWindow()
            self.db = pymysql.connect('localhost', 'root', 'root', '订单管理')
            self.create_table()
            self.set_ui()
    
        def set_ui(self):
            self.mainwindow.setWindowIcon(QIcon('images/ic.ico'))
            self.mainwindow.setFixedSize(1060, 746)
            self.mainwindow.setWindowOpacity(0.95)
            self.um.setupUi(self.mainwindow)
            self.um.price.setValidator(QRegExpValidator(QRegExp('[0-9 \.]+$')))
            self.um.order_number.setValidator(QRegExpValidator(QRegExp('[0-9]+$')))
            self.um.start_date.setDateTime(
                QtCore.QDateTime(QtCore.QDate(time.gmtime().tm_year, time.gmtime().tm_mon, time.gmtime().tm_mday),
                                 QtCore.QTime(0, 0, 0)))
            self.um.end_date.setDateTime(
                QtCore.QDateTime(QtCore.QDate(time.gmtime().tm_year, time.gmtime().tm_mon, time.gmtime().tm_mday),
                                 QtCore.QTime(0, 0, 0)))
            self.um.submit.clicked.connect(self.add_order)
            self.mainwindow.setWindowTitle('订单管理系统')
    
    
    
    
    
        def create_table(self):
            sql = "create table if not exists order_manger(id  int  primary key NOT NULL ,order_name varchar(50),order_type varchar(20),price FLOAT ,state varchar(5),start_date DATE,end_date DATE,others VARCHAR(500))"
            cursor = self.db.cursor()
            try:
                cursor.execute(sql)
                self.db.commit()
            except:
                self.db.rollback()
                pass
    
        def add_order(self):
            res=QMessageBox.information(self.mainwindow,'提交警告','你确定上传单子信息?',QMessageBox.Yes|QMessageBox.No)
            if res==65536:
                return
    
            order_name = self.um.order_name.text()
            order_number = self.um.order_number.text()
            order_type = self.um.order_type.currentText()
            price = self.um.price.text()
            start_date = self.um.start_date.text()
            end_date = self.um.end_date.text()
            state = self.um.state.currentText()
            others = self.um.others.toPlainText()
    
            try:
                sql = f"insert into order_manger values({order_number},'{order_name}','{order_type}',{float(price)},'{state}','{start_date}','{end_date}','{others}') "
                print(sql)
                cursor = self.db.cursor()
    
                cursor.execute(sql)
                self.db.commit()
                QMessageBox.information(self.mainwindow, '提示', '订单提交成功!')
                print('添加成功')
            except pymysql.err.IntegrityError:
                self.db.rollback()
                QMessageBox.information(self.mainwindow, '提示', '该单号已存在!')
            except ValueError:
                QMessageBox.information(self.mainwindow, '提示', '表单信息填写错误!')
            except:
                self.db.rollback()
                print('error')
    
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        t=order_handle()
        t.mainwindow.show()
        sys.exit(app.exec_())
    
    

    5.数据库(mysql)交互

    import pymysql
    
    
    class database_handle():
        def __init__(self):
            self.db = pymysql.connect('localhost', 'root', 'root', '订单管理')
    
        def get_all(self):
            sql = "select * from order_manger"
            cursor = self.db.cursor()
            cursor.execute(sql)
            data = cursor.fetchall()
            self.db.commit()
    
            return data
    
        def delete(self, id):
            sql = f"delete from order_manger where id={id}"
            cursor = self.db.cursor()
            cursor.execute(sql)
            self.db.commit()
    
        def update(self, id):
            sql = f''
    
        def get_hearders(self):
            sql = f"show columns from order_manger"
            cursor = self.db.cursor()
            cursor.execute(sql)
            cols = cursor.fetchall()
            self.db.commit()
            return cols
    
        def get_state(self, state):
            sql = "select * from order_manger where state ='%s'" % (state)
            try:
                cursor = self.db.cursor()
                cursor.execute(sql)
                data = cursor.fetchall()
                self.db.commit()
            except:
                self.db.rollback()
            return data
    
        def get_id(self, id):
            sql = "select * from order_manger where id ='%s'" % (id)
            try:
                cursor = self.db.cursor()
                cursor.execute(sql)
                data = cursor.fetchall()
                self.db.commit()
            except:
                self.db.rollback()
            return data
        def update(self,id):
            sql="update order_manger set state='%s' where id=%s"%('完成',id)
            print(sql)
            try:
                cursor = self.db.cursor()
                cursor.execute(sql)
                self.db.commit()
            except:
                self.db.rollback()
    
    
    if __name__ == '__main__':
        dh = database_handle()
        print(dh.update(19))
        pass
    
    

    效果展示

    在这里插入图片描述
    在这里插入图片描述
    这些是一些图标,背景图。在相对路径images文件夹下
    在这里插入图片描述
    注意事项:因为我用的我电脑上MySQL,所以要使用得配置mysql,然后自己根据数据库操作代码修改配置,虽然简陋,但是满足自己的小需求可还行

    展开全文
  • 在公司推广python的时候,发现一直没有一个好用的python版本的cas客户端,这样就不能和java平起平坐了,也就只能写点简单的脚本了。哎。。。 环境准备 python: 3.0 + 吧,没有特殊要求 django_cas_ng: 这个用最新...

    吐一下槽

    在公司推广python的时候,发现一直没有一个好用的python版本的cas客户端,这样就不能和java平起平坐了,也就只能写点简单的脚本了。哎。。。
    在这里插入图片描述

    环境准备

    • python: 3.0 + 吧,没有特殊要求
    • django_cas_ng: 这个用最新的吧, 我目前是4.1.1
    • django 3.0

    安装

    django_cas_ng的安装

    # 这一步我简单说了,不是中单
    - 官网下载包,记得最好用最新的呀
    - python setup.py install
    

    django的配置

    # 修改setting.py的INSTALLED_APPS  MIDDLEWARE  
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        "django_cas_ng",
    ]
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'django_cas_ng.middleware.CASMiddleware'
    ]
    # 修改setting.py的 增加下面的配置
    
    AUTHENTICATION_BACKENDS = (
        'django.contrib.auth.backends.ModelBackend',
        'django_cas_ng.backends.CASBackend'
    )
    CAS_SERVER_URL = "" # 你的cas server的地址
    CAS_CHECK_NEXT= lambda _: True
    CAS_VERSION = '3'
    

    CAS_CHECK_NEXT 这个要加上,不然会一直报Non-local url is forbidden to be redirected to.
    CAS_VERSION 这个要加上,并且最好用3 。不然不会执行退出操作

    修改urls.py

    # 增加下面的设置
    from django.contrib import admin
    from django.urls import path
    import django_cas_ng.views
    from . import views
    
    urlpatterns = [
        path('', views.index, name='index'), # 不是必须的
        path('admin/', admin.site.urls), # 不是必须的
        path('accounts/login', django_cas_ng.views.LoginView.as_view(), name='cas_ng_login'),
        path('accounts/logout', django_cas_ng.views.LogoutView.as_view(), name='cas_ng_logout'),
    ]
    
    

    创建对应的数据库表

    python manage.py migrate
    

    使用

      def get(self, request, *args, **kwargs):
            if request.user.is_authenticated:
                return render(request, 'index.html')
            else:
                return HttpResponseRedirect('/accounts/login')
    

    跨域问题

    因为cas server 是另个一地址(IP + Port), 所以当python应用重定向到cas server时会发生跨域问题。这时候解决方法如下:

    • 修改cas server 支持跨域
    • 把你的应用和cas server 放在一个nginx下面

    时间紧迫,先写到这里,有问题联系我就行, qq群 630300475

    在这里插入图片描述

    展开全文
  • 1、Python接口自动化系列之unittest

    千次阅读 多人点赞 2021-02-03 08:42:50
    好久没写博客了,最近在给朋友讲接口自动化,顺便记录一下,以便后面复习用,目前是打算用两三个月的时间来写整个Python接口自动框架从0到1的搭建过程,以及实际工作中接口框架是怎么用的,好了,现在就开始搞吧。...

    好久没写博客了,最近在给朋友讲接口自动化,顺便记录一下,以便后面复习用,目前是打算用两三个月的时间来写整个Python接口自动框架从0到1的搭建过程,以及实际工作中接口框架是怎么用的,好了,现在就开始搞吧。
    我们在学习任何技术之前都要弄清楚几个问题,这样会更方便理解。
    1、什么是单元测试?
    按照阶段来分,一般就是单元测试,集成测试,系统测试,验收测试。单元测试是对单个模块、单个类或者单个函数进行测试。
    将访问接口的过程封装在函数里面;
    接口测试就变成了单元测试;
    单元测试就是通过传参,对某个模块、某个类、某个函数进行结果输出后验证的测试。
    2、为什么要做单元测试?
    1).单元测试之后,才是集成测试,单个的功能模块测试通过之后,才能把单个功能模块集成起来做集成测试,为了从底层发现bug,减少合成后出现的问题。
    2).越早发现bug越好,否则问题累计到后期,如果做错了就要推倒重来,对于时间和人力成本来说非常耗费精力。
    对于我们测试来说:单元测试是为了执行测试用例。
    3、怎么做单元测试?
    Python里有两个单元测试类:
    1.Unittest(Python自带);
    2.Pytest(第三方库,需要下载安装);
    unittest多用于接口自动化项目用,pytest多用于WEB自动化项目、APP自动化项目。

    4、unittest简介
    unittest是Python自带的单元测试框,具备编写用例、组织用例、执行用例、输出报告等自动化框架的条件,可以用来作自动化测试框架的用例组织执行框架。
    unittest框架的特性:
    1)提供用例组织与执行:当测试用例只有几条的时候可以不考虑用例的组织,但是当测试用例数量较多时,此时就需要考虑用例的规范与组织问题。unittest单元测试框架就是用来解决这个问题的。
    2)提供丰富的断言方法:既然是测试,就有一个预期结果和实际结果的比较问题。比较就是通过断言来实现,unittest单元测试框架提供了丰富的断言方法,通过捕获返回值,并且与预期值进行比较,从而得出测试通过与否。
    3)提供丰富的日志:每一个失败用例我们都希望知道失败的原因,所有用例执行结束我们有希望知道整体执行情况,比如总体执行时间,失败用例数,成功用例数。unittest单元测试框架为我们提供了这些数据。

    4、unittest组成
    unittest单元测试中最核心的四个部分是:TestCase(测试用例),TestSuite(测试套件),TestRunner(测试运行器),TestFixture(测试环境数据准备和清理)。
    1)TestCase(测试用例):一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程。包括测试前准备环境的搭建(setUp)、实现测试过程的代码(run),以及测试后环境的还原(tearDown)。单元测试(Unittest)的本质也就在这里,一个测试用例就是一个完整的测试单元,通过运行这个测试单元,可以对某一个功能进行验证。

    2)TestSuite(测试套件):一个功能的验证往往需要多个测试用例,可以把多个测试用例集合在一起执行,这就产生了测试套件TestSuite的概念。TestSuite用来组装单个测试用例。可以通过addTest加载TestCase到TestSuite中,从而返回一个TestSuite实例。而且TestSuite也可以嵌套TestSuite。

    3)TestLoader(测试用例加载器):用来加载TestCase到TestSuite中的,其中loadTestsFrom__()方法用于寻找TestCase,并创建它们的实例,然后添加到TestSuite中,返回TestSuite实例;

    4)TextTestRunner(执行测试用例):用来执行测试用例,其中run(test)会执行TestSuite/TestCase中的run(result)方法,并将测试结果保存到TextTestResult实例中,包括运行了多少测试用例,成功多少,失败多少等信息;

    5)Test Fixture(测试环境数据准备和清理):一个测试用例的初始化准备及环境还原,主要是setUp() 和 tearDown()方法;比如说在测试用例中需要访问数据库,那么可以在setUp()中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的TestCase留下一个干净的环境。

    5、实现思路
    1)导入unittest模块、 被测文件或者其中的类;
    2)创建一个测试类,并继承unittest.TestCase方法;
    3)重写setUp和tearDown方法(如果有初始化条件和结束条件)。若setup()成功运行,无论测试方法是否成功,都会运行tearDown ();
    4)定义测试函数,函数名以test_开头,以识别测试用例;
    5)调用unittest.main()方法运行测试用例;
    6)用例执行后,需要判断用例是Pass还是Fail,可以用unittest.TestCase模块的:断言
    断言就是比对预期结果。如果不加断言,没有结果对比,需要手动去检查运行的结果是否符合预期

    前面5个模块百度都有,目的主要就是为了让那些手懒和不怎么会用百度的小伙伴不用自己百度了。接下来就是要敲代码来实现了。

    6、使用介绍
    前面我们提到过,unittest是Python自带的单元测试框架,所以无需下载,直接import unittest就可以

    import unittest
    
    
    # 我们先打印一下unittest的源码
    print(help(unittest))
    
    # 粘贴出源码里面提供的例子,然后我们总结一下每行代码的意思
    
    # Simple
    # usage:
    # import unittest  1、使用unittest前,需导入unittest框架
    
    # 2、IntegerArithmeticTestCase这个类必须继承unittest.TestCase,TestCase类,所有测试用例类继承的基类
    class IntegerArithmeticTestCase(unittest.TestCase):
        # 3、类内的方法必须以test开头,比如testAdd或者test_Add
        def testAdd(self):  # test method names begin with 'test'
            # 4、断言:assertEqual用来断言预期结果和实际结果是否一致。当然unittest还包含很多其他断言方法,后面统一介绍
            self.assertEqual((1 + 2), 3)
            self.assertEqual(0 + 1, 1)
        # 测试用例
        def testMultiply(self):
            self.assertEqual((0 * 10), 0)
            self.assertEqual((5 * 8), 40)
    
    # 5、用例执行顺序。在代码中不是写在前面的方法就先执行,如果把testMultiply放在testAdd方法之前,也是先执行testAdd方法,这是因为unittest执行测试用例,默认是根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。
    
    
    if __name__ == '__main__':
        # unittest.main()是运行主函数
        unittest.main(verbosity=2)
    
    # 6、verbosity是一个选项,表示测试结果的信息复杂度,有0、1、2 三个值。verbosity=0 : 你只能获得测试用例数总的结果;verbosity=1 (默认模式): 在每个成功的用例前面有个“.”,表示通过, 每个失败的用例前面有个 “F”,faild表示失败;verbosity=2 (详细模式):测试结果会显示每个测试用例的所有相关的信息。
    
    

    看一下运行结果
    在这里插入图片描述
    7、测试用例里面的setUp函数与tearDown函数的使用:

    import unittest
    
    
    # 我们先打印一下unittest的源码
    #print(help(unittest))
    
    # 粘贴出源码里面提供的例子,然后我们总结一下每行代码的意思
    
    # Simple
    # usage:
    # import unittest  1、使用unittest前,需导入unittest框架
    
    # 2、IntegerArithmeticTestCase这个类必须继承unittest.TestCase,TestCase类,所有测试用例类继承的基类
    class IntegerArithmeticTestCase(unittest.TestCase):
        # setUp函数:初始化环境(执行每条用例之前,都要执行setUp函数下面的代码,每次都要执行)
        # 前置条件。测试方法之前自动运行setup里面的代码,比如在接口自动化中需要先登录的接口就需要频繁获取cookie,这样很不方便,所以就可以把获取cookie的方法写在setup里面
        def setUp(self):
            print("用例执行前置条件")
        # tearDown函数:清洗环境(执行每条用例之后,都要执行tearDown函数下面的代码,每次都要执行)
        # 后置条件。测试方法之后自动运行teardown里面的代码,比如在接口自动化中清理跑完一条case在数据库里产生的垃圾数据就可以写在teardown里面
        def tearDown(self):
            print("用例执行后置条件")
        # 3、类内的方法必须以test开头,比如testAdd或者test_Add
        def testAdd(self):  # test method names begin with 'test'
            # 4、断言:assertEqual用来断言预期结果和实际结果是否一致。当然unittest还包含很多其他断言方法,后面统一介绍
            self.assertEqual((1 + 2), 3)
            self.assertEqual(0 + 1, 1)
            print("我是第一个方法")
        # 测试用例
        def testMultiply(self):
            self.assertEqual((0 * 10), 0)
            self.assertEqual((5 * 8), 40)
            print("我是第二个方法")
    # 5、用例执行顺序。在代码中不是写在前面的方法就先执行,如果把testMultiply放在testAdd方法之前,也是先执行testAdd方法,这是因为unittest执行测试用例,默认是根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。
    
    
    if __name__ == '__main__':
        # unittest.main()是运行主函数
        unittest.main(verbosity=2)
    
    # verbosity是一个选项,表示测试结果的信息复杂度,有0、1、2 三个值。verbosity=0 : 你只能获得测试用例数总的结果;verbosity=1 (默认模式): 在每个成功的用例前面有个“.”,表示通过, 每个失败的用例前面有个 “F”,faild表示失败;verbosity=2 (详细模式):测试结果会显示每个测试用例的所有相关的信息。
    

    在这里插入图片描述
    看打印结果我们很容易就能看出来setup和teardown在什么时候执行
    注意:若 setUp() 成功运行,无论测试方法是否成功,都会运行 tearDown()
    setUp()、tearDown()是TestCase里的方法,写在测试类中,就是方法的重写

    8、setUpClass函数与tearDownClass函数的使用:

    import unittest
    
    
    # 2、IntegerArithmeticTestCase这个类必须继承unittest.TestCase,TestCase类,所有测试用例类继承的基类
    class IntegerArithmeticTestCase(unittest.TestCase):
        # @classmethod 装饰器,根据名字就知道是类方法,在类运行之前运行,先知道这种用法就行,后面会单独讲一下装饰器的用法
        @classmethod
        # 当类中的测试方法被执行前会被调用的一个类方法。该方法只会在类方法前调用,也就是带有calssmethod装饰器并且没有其他参数的方法。
        def setUpClass(cls):
            print("测试类之前运行")
        @classmethod
        # 当类测试方法被执行完后会被调用的一个类方法。该方法只会在一个类的所有方法执行完成后调用,该方法被调用时,必须有calssmethod装饰器并且除了类以外没有其他参数的方法
        def tearDownClass(cls):
            print("测试类之后运行")
        # setUp函数:初始化环境(执行每条用例之前,都要执行setUp函数下面的代码,每次都要执行)
        # 前置条件。测试方法之前自动运行setup里面的代码,比如在接口自动化中需要先登录的接口就需要频繁获取cookie,这样很不方便,所以就可以把获取cookie的方法写在setup里面
        def setUp(self):
            print("用例执行前置条件")
        # tearDown函数:清洗环境(执行每条用例之后,都要执行tearDown函数下面的代码,每次都要执行)
        # 后置条件。测试方法之后自动运行teardown里面的代码,比如在接口自动化中清理跑完一条case在数据库里产生的垃圾数据就可以写在teardown里面
        def tearDown(self):
            print("用例执行后置条件")
        # 3、类内的方法必须以test开头,比如testAdd或者test_Add
        def testAdd(self):  # test method names begin with 'test'
            # 4、断言:assertEqual用来断言预期结果和实际结果是否一致。当然unittest还包含很多其他断言方法,后面统一介绍
            self.assertEqual((1 + 2), 3)
            self.assertEqual(0 + 1, 1)
            print("我是第一个方法")
        # 测试用例
        def testMultiply(self):
            self.assertEqual((0 * 10), 0)
            self.assertEqual((5 * 8), 40)
            print("我是第二个方法")
    
    
    if __name__ == '__main__':
        # unittest.main()是运行主函数
        unittest.main(verbosity=2)
    

    看一下运行结果,一目了然,哈哈
    在这里插入图片描述

    9、运行方式
    1)第一种直接右键运行
    在这里插入图片描述
    2)第二种命令行运行
    unittest 模块可以通过命令行运行模块、类和独立测试方法的测试:
    python -m unittest test_unittest
    python -m unittest test_unittest.TestClass
    python -m unittest test_unittest.TestClass.testAdd

    同样的,测试模块可以通过文件路径指定,这也是我常用的一种方式,我们下面就以这种方式执行
    我的目录:在这里插入图片描述

    在pycharm下面的Terminal使用命令行python -m unittest test_unittest/t1.py
    在这里插入图片描述
    在运行测试时,你可以通过添加 -v 参数获取更详细(更多的冗余)的信息:
    python -m unittest -v test_module
    当运行时不包含参数,开始 探索性测试:
    python -m unittest
    用于获取命令行选项列表:
    python -m unittest -h
    10、测试套件TestSuit(也叫测试集):
    1)第一种往测试套件添加测试用例的方式

    import unittest
    # 导入t1模块的类
    from test_unittest.t1 import IntegerArithmeticTestCase
    
    # TestSuite这个类代表一个测试用例或测试套件的集合,该类描述了一个可以被test runner执行的接口,通过它可以执行任何测试,运行一个TestSuite就相当于将测试套件迭代,然后执行每一个测试
    suite = unittest.TestSuite()
    # IntegerArithmeticTestCase下的测试用例
    cases= [IntegerArithmeticTestCase('testAdd'),
            IntegerArithmeticTestCase('testMultiply')]
    
    # 往套件里添加测试用例   注意:是addTests,不是addTest,addTest是添加一条测试用例
    suite.addTests(cases)
    # 运行,生成测试报告,我们先生成txt格式的,使用unittest自带的TextTestRunner生成测试报告(文本格式,不推荐使用)
    with open('demo.txt','w',encoding='utf-8') as f:
        # 初始化runner  runner可以理解为运行器
        runner = unittest.TextTestRunner(f)
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite)
    

    运行,会在当前目录下(也就是和t2同一目录)自动生成demo.txt文件,如果存在,不会重新生成,会覆盖之前的内容
    在这里插入图片描述
    看到生成demo.txt文件,两个…就代表两条测试用例通过
    我们在故意改错一个看看结果,把40改为4
    在这里插入图片描述
    在运行看一下结果
    在这里插入图片描述
    可以看到果然是覆盖,没有忽悠你们,哈哈。F代表失败,失败的原因会在下面显示出来
    2)第二种往测试套件添加测试用例的方式,其实和第一种差不多只不过是在unittest.TestSuite()中添加一个tests参数,值为测试用例列表:unittest.TestSuite(tests=cases)

    import unittest
    # 导入t1模块的类
    from test_unittest.t1 import IntegerArithmeticTestCase
    
    # IntegerArithmeticTestCase下的测试用例
    cases= [IntegerArithmeticTestCase('testAdd'),
            IntegerArithmeticTestCase('testMultiply')]
    
    #  创建测试套件的同时,直接往测试套件里面添加测试用例,省去suite.addTests(cases)
    #  如果写上tests参数,那么它必须是一个可迭代对象,用来创建套件的
    suite = unittest.TestSuite(tests=cases)
    
    # 运行,生成测试报告,我们先生成txt格式的,使用unittest自带的TextTestRunner生成测试报告(文本格式,不推荐使用)
    with open('demo.txt','w',encoding='utf-8') as f:
        # 初始化runner  runner可以理解为运行器
        runner = unittest.TextTestRunner(f)
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite)
    

    我们运行试一下
    在这里插入图片描述
    同样的也能得到测试结果

    3)我们来看一下第三种加载测试用例的方法:TestLoader()方法

    import unittest
    # 导入t1模块的类
    from test_unittest import t1
    from test_unittest.t1 import IntegerArithmeticTestCase
    
    # IntegerArithmeticTestCase下的测试用例
    # cases= [IntegerArithmeticTestCase('testAdd'),
    #        IntegerArithmeticTestCase('testMultiply')]
    
    # TestLoader用来加载测试用例的
    # 我们可以根据模块加载,也可以根据测试类加载,自己定义规则,让他自动发现
    loader = unittest.TestLoader()
    # 根据测试类去加载测试用例
    cases1 = loader.loadTestsFromTestCase(IntegerArithmeticTestCase)
    
    # 根据模块去加载测试用例
    # cases2 = loader.loadTestsFromModule(t1)
    
    suite = unittest.TestSuite()
    suite.addTests(cases1)
    # suite.addTests(cases2)
    
    # 运行,生成测试报告,我们先生成txt格式的,使用unittest自带的TextTestRunner生成测试报告(文本格式,不推荐使用)
    with open('demo.txt','w',encoding='utf-8') as f:
        # 初始化runner  runner可以理解为运行器
        runner = unittest.TextTestRunner(f)
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite)
    
    import unittest
    # 导入t1模块的类
    from test_unittest import t1
    from test_unittest.t1 import IntegerArithmeticTestCase
    
    # IntegerArithmeticTestCase下的测试用例
    # cases= [IntegerArithmeticTestCase('testAdd'),
    #        IntegerArithmeticTestCase('testMultiply')]
    
    # TestLoader用来加载测试用例的
    # 我们可以根据模块加载,也可以根据测试类加载,自己定义规则,让他自动发现
    loader = unittest.TestLoader()
    # 根据测试类去加载测试用例
    # cases1 = loader.loadTestsFromTestCase(IntegerArithmeticTestCase)
    
    # 根据模块去加载测试用例
    cases2 = loader.loadTestsFromModule(t1)
    
    suite = unittest.TestSuite()
    # suite.addTests(cases1)
    suite.addTests(cases2)
    
    # 运行,生成测试报告,我们先生成txt格式的,使用unittest自带的TextTestRunner生成测试报告(文本格式,不推荐使用)
    with open('demo.txt','w',encoding='utf-8') as f:
        # 初始化runner  runner可以理解为运行器
        runner = unittest.TextTestRunner(f)
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite)
    

    4)自动化发现测试用例:discover方法

    import os
    import unittest
    
    
    suite = unittest.TestSuite()
    # TestLoader用来加载测试用例的
    # 我们可以根据模块加载,也可以根据测试类加载,自己定义规则,让他自动发现
    loader = unittest.TestLoader()
    
    start_dir = os.path.dirname(os.path.abspath(__file__))
    # 自动发现测试用例的方法  从指定的start_dir(起始目录)递归查找所有子目录下的测试模块,并返回一个TestSuite对象。只有符合pattern模式匹配的测试文件才会被加载。模块名称必须有效才能被加载。
    suite1 = loader.discover(start_dir)
    # 运行,生成测试报告,我们先生成txt格式的,使用unittest自带的TextTestRunner生成测试报告(文本格式,不推荐使用)
    with open('demo.txt','w',encoding='utf-8') as f:
        # 初始化runner  runner可以理解为运行器
        runner = unittest.TextTestRunner(f, verbosity=2)
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite1)
    
    

    目前这样写完是可以运行的,但是不能自定发现测试用例,也不能生成测试报告,这是为什么呢?因为discover方法,我们先看一下discover方法的参数:discover(start_dir,pattern=’test*.py’,top_level_dir=None)
    start_dir参数:start_dir可以是一个模块名,也可以是一个目录,是必传参数
    pattern参数:pattern没有被特意存储为loader的属性,这样包就可以自行查找;就是因为这个参数的值必须是以test开头的模块才能被自动发现
    top_level_dir参数:top_level_dir被存储,top_level_dir=None,默认为None 不用管
    看完discover的几个参数和值我们就知道为啥没有自动加载到测试用例了,所以我们吧t1模块改为test1.py在运行

    import os
    import unittest
    
    
    suite = unittest.TestSuite()
    # TestLoader用来加载测试用例的
    # 我们可以根据模块加载,也可以根据测试类加载,自己定义规则,让他自动发现
    loader = unittest.TestLoader()
    
    start_dir = os.path.dirname(os.path.abspath(__file__))
    # 自动发现测试用例的方法  从指定的start_dir(起始目录)递归查找所有子目录下的测试模块,并返回一个TestSuite对象。只有符合pattern模式匹配的测试文件才会被加载。模块名称必须有效才能被加载。
    suite1 = loader.discover(start_dir)
    # 运行,生成测试报告,我们先生成txt格式的,使用unittest自带的TextTestRunner生成测试报告(文本格式,不推荐使用)
    with open('demo.txt','w',encoding='utf-8') as f:
        # 初始化runner  runner可以理解为运行器
        runner = unittest.TextTestRunner(f, verbosity=2)
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite1)
    
    

    看结果,是能自动发现测试用例并能生成报告的
    在这里插入图片描述
    还有一个小问题,我们看一下第一行代码,根本就没用到,所以说用discover方法自动生成用例是不用初始化suite的,小伙伴们可以自己去掉第一行代码执行一遍,就知道根本没啥用,小技巧,大经验,哈哈哈

    11、前面我们执行结果报告是不是太丑了,哈哈,我们接下来学习一下HTMLtestrunner,首先我们先安装一下HTMLtestrunner,由于现在从官网下载的是早期Python2的,现在很多小伙伴都是用的Python3,所以需要修改一下HTMLtestrunner的源码,怎么修改这里就不过多的说了,其实目前来说学习怎么修改用处不是很大,我把修改后的可以发给大家,有需要的,下方可以加我微信,私发你哦
    首先我们看一下如何把我修改后的HTMLtestrunner放在自己的lib目录下
    在这里插入图片描述

    import os
    import unittest
    # 1、首先导入HTMLTestRunner,注意:HTMLTestRunnerHh是我修改后的,其中Hh是为了区分一下,随便起的名字,哈哈
    from HTMLTestRunnerHh import HTMLTestRunner
    
    loader = unittest.TestLoader()
    start_dir = os.path.dirname(os.path.abspath(__file__))
    suite1 = loader.discover(start_dir)
    with open('demo.html','wb',encoding='utf-8') as f:
        # 2、我们把unittest里面的TextTestRunner替换成HTMLTestRunner
        runner = HTMLTestRunner(f, verbosity=2)
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite1)
    
    
    

    运行看一下结果:
    在这里插入图片描述
    呀,报错了,莫慌,看原因是说这个字符集的问题,因为是HTML报告嘛,所以我们把encoding='utf-8’去掉就好了
    去掉之后运行
    在这里插入图片描述
    是这样的,我们点击右上角的浏览器图标。自己想要用什么浏览器打开直接就点击对应的图标就行,我是习惯用谷歌,这里就拿谷歌演示一下
    在这里插入图片描述
    这报告不就好看多了嘛,而且很直观的就可以看出,作者最新改动了一下源码,改成条形图或者饼状图统计的了(得意),其中红色失败,绿色通过,我们再来看一次失败的结果
    在这里插入图片描述
    失败的用例会说明失败的原因,很详细,能快速准确的定位问题。
    最后我们看一下HTMLTestRunner()几个参数的用法

    import os
    import unittest
    # 1、首先导入HTMLTestRunner,注意:HTMLTestRunnerHh是我修改后的,其中Hh是为了区分一下,随便起的名字,哈哈
    from HTMLTestRunnerHh import HTMLTestRunner
    
    loader = unittest.TestLoader()
    start_dir = os.path.dirname(os.path.abspath(__file__))
    suite1 = loader.discover(start_dir)
    with open('demo.html','wb') as f:
        # 2、我们把unittest里面的TextTestRunner替换成HTMLTestRunner
        # 3、HTMLTestRunner参数,我们看一下源码可知需要的参数 HTMLTestRunner(stream= verbosity=2,title=None,description=None,tester=None)
        # stream= : 输入流 verbosity=2: 不说了 前面写过,可以往前翻翻,title=None:默认None 就是测试报告的标题的名字,description=None:默认None,描述测试报告的,tester=None:测试人是谁
        runner = HTMLTestRunner(f, verbosity=2,title='浩浩的测试报告',description='浩浩是单身狗',tester='浩浩')
        # run()方法是TextTestRunner主要的公共接口,需要一个TestSuite或者TestCase实例作为参数
        runner.run(suite1)
    
    
    

    看结果:
    在这里插入图片描述
    不写的话就取默认参数,默认参数值是在HTMLTestRunner的源码里面:
    在这里插入图片描述

    到这里unittest的基本用法就已经都说完了,后面应该还会有,一到两篇写unittest结合ddt做数据驱动,以及把这些方法都封装起来用,封装后的才算是框架需要的。

    作者写到这也不容易,各位小伙伴觉得写得好的点个赞+关注吧
    打一波广告哈!!!
    有不明白的小伙伴可以加我微信哈,进群一起学习哈 欢迎大家来撩,微信号:18547673653
    后面的更新可能就只在公众号更新,所以,你懂得。
    公众号搜索:IT小测开

    展开全文
  • 不过前提,是你要有那实力,私活干,并不是那么好的!以下我来说说我的一些看法吧!自学Py入门对于一名高中及以上文化以上的人难度不是很大,只要用心就行!第一:Python的主要作用是减少简单重复的工作量,把...
  • 2 #进程服务器 实现多客户端访问 IO复用 3 #吧所有的客户端套字 放在一个列表里面,一次又一次的便利过滤 4 #这就是apache: select模型 6 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 7...
  • 最近客户端上有个发送图文的需求,大致是...测试中期需要造一些数据来进行测试及观察整体效果,图片上传是个很费事的手机活,那么我又想到了python http神器requests 还是直接上代码加注释吧 1 #-*-coding:ut...
  • 最近,在一门涉及python的课上,老师讲解了Tushare这款股票数据接口。经过数据猿进一步探索之后发现,Tushare不但包含包含齐全的股票数据,还包含了其他领域的有用数据。除此之外,Baostock也是一个非常优秀的开源...
  • 当然这些平台不止Python语言能接单,事实上基本所有语言都能找到合适的单子~ 1、没有第三方担保的个人单,风险较大尽量少接 2、无需求文档,讲不清具体需求的不接 3、没有预付的不做,结款方式按442的方式 4、没有...
  • 先说1双引号与3个双引号的区别,双引号所表示的字 符串通常要写成一行 如: s1 = "hello,world" 如果要写成多行,那么就要使用\ (“连行...写了,如下: s3 = """hello, world, hahaha.""",那么s3实际上就
  • Python网络编程系列已经讲述了套字编程、HTTP协议、TCP/IP协议、多线程、多进程以及协程等知识,就以这篇博客结束Python网络编程系列吧。在这篇博客中会讲述两种以线程的方式完成多任务。 1. 线程实现多任务 ...
  • 所以决定,从python接口自动化来入手(接口自动化收益比较高),从零开始搭建一个框架,来记录一下自己的成长。时间可能很长,也可能很短,看心情吧,我不是大牛,单纯记录,不一定能指导别人,有问题欢迎提出。 ...
  • 并发测试框架本来已经在上一篇文章《常见的并发问题》已经写过,但是,有的小朋友必须要我把框架部分 单独拎出来。 好吧~ ~ 我直接把代码拎出来: # -*- coding: utf-8 -*- """ @ auth : carl_DJ ...
  • Python 2.5

    2007-05-28 12:33:42
    Python”这个英文单词的发音似“派森”,因此中文可以称之为派森。Python是一个有10年历史的Windows编程语言。Python的创始人为Guido van Rossum。 <br/> <br/>Python是一种即译式的,互动的,面向对象的...
  • 下来的文章就想给大家介绍下两者的一些区别以及优缺点。首先不多说,先给大家说下他们俩的一些差异或者优缺点吧:Python是通用的,也是高级编程语言之一。在python中编写代码时,无需声明即可直接使用变量。在C ...
  • 下来的文章就想给大家介绍下两者的一些区别以及优缺点。首先不多说,先给大家说下他们俩的一些差异或者优缺点吧:Python是通用的,也是高级编程语言之一。在python中编写代码时,无需声明即可直接使用变量。在C ...
  • python之ATM

    2021-01-07 08:35:17
    python之ATM  每次做一点就发出来,大神不要嫌重复  2016/11/4  今天来搞ATM,反正逃不了的,说来惭愧,这个作业是我10/4号20天前拿到的,当时是万脸蒙比的,今天又做了一点,现在算是百脸蒙比吧。 一、...
  • python基础语法

    2016-01-07 17:35:05
    下划线开头(_foo)的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用"from xxx import *"而导入; 以双下划线开头的(__foo)代表类的私有成员;以双下划线开头和结尾的(__foo__)代表python...
  • testRead.py # -*- coding: utf-8 -*- # @Software: PyCharm # @File : testRead.py # @Time : 2021/2/9 17:55 import threading import requests import debugtalk import yaml ymlFile = "D:\code_path\python\...
  • 之前参考过一些网上的文章做了python2.7下的集成,然而还没用几天,老板说把这块代码拉出去单独做个项目吧,哦呵呵呵。新项目是python3.5的,大体上差不多,有一些编码会有些变动,基本照着文档的接口写就可以了。...
  • python3之字符串

    2018-01-08 16:40:11
    有一段时间在游荡,没有回来管理这个新手博客,下来会逐步把之前的python系列入门给完善和完整,包括项目应用和一些底层交互内容,另外也会加入一些有趣的东西尝试。今天就从字符串的回顾开始吧。 python...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 131
精华内容 52
关键字:

python接单吧

python 订阅