python unittest-运行时生成的参数列表

时间:2019-12-05 13:47:41

标签: python python-unittest

是否可以为单元测试提供一个在运行时提供的参数?

例如,我已将5个COM端口连接到我的机器。测试环境应选择正确的COM端口并对其进行测试。因此,所测试的不是实际的python代码,python单元测试工具基本上用于验证由python脚本建立的通信。取决于初始通信,应选择具有相应参数的多个测试(例如使用的端口)并将其添加到批次(测试套件)中。

下一步,我要遍历包含COM端口和其他选项的数组。

有一个装饰器@parametrized。该解决方案看起来不错,并且可以按需调用测试。但是不可能在运行时使用它。加载脚本时启动装饰器。我知道的唯一解决方法是使用全局变量将COM端口传递给TestCase。然后必须由测试运行程序调用测试。

总结:

是否有可能在运行时对测试进行参数设置? 然后,也可以将其添加到测试套件中,以列出仅参数不同的相同测试的列表。 或其他替代方法是在setUpClass()中分配参数,并且无论如何都要再次运行多个测试,但要使用其他参数。也许有可能吗?

那么,如何在运行时使用单元测试在python中使用参数设置测试?

1 个答案:

答案 0 :(得分:0)

找出COM端口是否正确的唯一方法是与之通信。我们在说哪种COM端口?例如,一台3D打印机将发送定期命令,表明已准备就绪,可以使用它来检测是否连接了3D打印机。在python中,您可以轻松获得可用COM端口的列表,并尝试连接到其中一个。我曾经写过一个可以连接到任何自动生成的可用COM端口列表的接口。也许您可以使用其中的一部分来完成您的项目:

import math
import serial
import wx
import threading

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title = "Hydroponics controller")

        self.comport = ""
        self.baudrate = 0
        self.ser = serial.Serial()

        self.p = wx.Panel(self)
        nb = Notebook(self)

        tab1 = connectionTab(nb)
        tab2 = ControllerTab(nb)

        nb.AddPage(tab1, "Connection")
        nb.AddPage(tab2, "Controller")

        sizer = wx.BoxSizer()
        sizer.Add(nb, 1, wx.EXPAND)
        self.p.SetSizer(sizer)

class Notebook(wx.Notebook):
    def __init__(self, parent):
        wx.Notebook.__init__(self, parent.p)
        self.ser = parent.ser

class connectionTab(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.p = parent

        comLabel = wx.StaticText(self, -1, "Serial port", pos = wx.Point(10, 10), size = wx.Size(64, 20))
        self.comList = wx.ListBox(self, size = wx.Size(64, 128), choices = [], pos = wx.Point(10, 40), style = wx.LB_SINGLE)

        baudrateLabel = wx.StaticText(self, -1, "Baudrate", pos = wx.Point(84, 10), size = wx.Size(64, 20))
        self.baudrateList = wx.ListBox(self, size = wx.Size(64, 128), choices = ["9600", "115200", "250000"], pos = wx.Point(84, 40), style = wx.LB_SINGLE)
        self.baudrateList.SetSelection(1)

        self.refreshButton = wx.Button(self, -1, "Refresh", pos = wx.Point(158, 40))
        self.refreshButton.Bind(wx.EVT_BUTTON, self.refreshButton_clicked)

        self.connectButton = wx.Button(self, -1, "Connect", pos = wx.Point(158, 70))
        self.connectButton.Bind(wx.EVT_BUTTON, self.connectButton_clicked)

        self.statusLabel = wx.StaticText(self, -1, "", pos = wx.Point(158, 100))

        self.refreshDevices()

    def refreshButton_clicked(self, event):
        self.refreshDevices()

    def connectButton_clicked(self, event):
        try:
            self.p.ser = serial.Serial(self.comList.GetStringSelection(), self.baudrateList.GetStringSelection())
            self.statusLabel.SetLabel("Connection succesful.")
        except serial.serialutil.SerialException:
            self.statusLabel.SetLabel("Connection failed.")

    def refreshDevices(self):
        self.availableDevices = []
        self.comList.Clear()
        for i in range(0,256):
            try:
                tmp = serial.Serial("COM{}".format(i))
                self.comList.Append("COM{}".format(i))
            except serial.serialutil.SerialException:
                continue
        if(self.comList.GetCount()):
            self.comList.SetSelection(0)

class ControllerTab(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.parent = parent

        self.threadStopped = True
        self.t = threading.Thread(target = self.runSequence)
        self.t.start()

        ROWS = 3
        ROWS_POS = [40, 370, 700]
        COLUMNS = 10
        COLUMNS_POS = [0, 88, 176, 264, 352, 440, 528, 616, 704, 792]

        self.commandList = []
        self.buttonList = []

        for i in range(0, COLUMNS):
            for j in range(0, ROWS):
                self.buttonList.append(PlantButton(self, COLUMNS_POS[i], ROWS_POS[j], wx.Point(i * 110 + 10, j * 30 + 10)))

        self.homeAllButton = wx.Button(self, -1, "Home all", pos = wx.Point(10, ROWS * 30 + 10))
        self.homeAllButton.Bind(wx.EVT_BUTTON, self.homeAllButton_clicked)

        self.dwellButton = wx.Button(self, -1, "Dwell 1s", pos = wx.Point(10, (ROWS + 1) * 30 + 10))
        self.dwellButton.Bind(wx.EVT_BUTTON, self.dwellButton_clicked)

        self.commandListBox = wx.ListBox(self, size = wx.Size(192, 512), choices = [], pos = wx.Point(10, (ROWS + 2) * 30 + 10))

        self.startSequenceButton = wx.Button(self, -1, "Start sequence", pos = wx.Point(212, (ROWS + 2) * 30 + 10))
        self.startSequenceButton.Bind(wx.EVT_BUTTON, self.startSequenceButton_clicked)

        self.saveFileButton = wx.Button(self, -1, "Save to file", pos = wx.Point(212, (ROWS + 3) * 30 + 10))
        self.saveFileButton.Bind(wx.EVT_BUTTON, self.saveFileButton_clicked)

        self.deleteCommandButton = wx.Button(self, -1, "Delete selected command", pos = wx.Point(212, (ROWS + 4) * 30 + 10))
        self.deleteCommandButton.Bind(wx.EVT_BUTTON, self.deleteCommandButton_clicked)

    def homeAllButton_clicked(self, event):
        self.commandList.append("G92 X200\nG1 X0 F6000\nG28 XYZ\n")
        self.commandListBox.Append("Home all")

    def dwellButton_clicked(self, event):
        self.commandList.append("G4 P1000\n")
        self.commandListBox.Append("Dwell for 1 second")

    def startSequenceButton_clicked(self, event):
        self.threadStopped = False

    def saveFileButton_clicked(self, event):
        file = open("sequence.gcode", "w")
        for i in range(0, len(self.commandList)):
            file.write(self.commandList[i])
        file.close()

    def deleteCommandButton_clicked(self, event):
        index = self.commandListBox.GetSelection()
        if(index == wx.NOT_FOUND):
            return
        self.commandList.pop(index)
        self.commandListBox.Delete(index)
        if(index == 0):
            self.commandListBox.SetSelection(0)
        else:
            self.commandListBox.SetSelection(index - 1)


    def runSequence(self):
        while True:
            if(self.threadStopped == False):
                sequenceLength = len(self.commandList)
                index = 0

                self.parent.ser.write("G92 X100\nG1 X0 F6000\nM340 P3 S2000\nG28 XYZ\n")

                while((index < sequenceLength) & (self.threadStopped == False)):
                    data = self.parent.ser.readline()
                    if(len(data) != 0):
                        print "READ: {}".format(data),
                    if(data == "ok 0\r\n"):
                        print "SENT: {}".format(self.commandList[index]),
                        self.parent.ser.write(self.commandList[index])
                        index += 1

                print "Stopped"
                self.threadStopped = True

class PlantButton:
    def __init__(self, parent, x, y, buttonPos):
        self.parent = parent
        self.x = x
        self.y = y
        self.buttonPos = buttonPos

        self.button = wx.Button(self.parent, -1, "({}, {})".format(self.x, self.y), pos = self.buttonPos)
        self.button.Bind(wx.EVT_BUTTON, self.button_clicked)

    def button_clicked(self, event):
        self.parent.commandList.append("G1 X{} Y{} F6000\n".format(self.y, self.x))
        self.parent.commandList.append("G1 Z70 F6000\nG4 P1000\nM340 P3 S2500\nG4 P500\nM340 P3 S2468\nG4 P1000\nG91\nG1 X-40 F6000\nG90\nG1 Z0 F6000\n")
        self.parent.commandList.append("G1 X700 F6000\nG4 P1000\nM340 P3 S2000\n")
        self.parent.commandListBox.Append("Go to position ({}, {})\n".format(self.x, self.y))

if __name__ == "__main__":
    app = wx.App()
    MainFrame().Show()
    app.MainLoop()