1336 lines
48 KiB
VB.net
1336 lines
48 KiB
VB.net
Imports System.Text
|
||
Imports System.Threading
|
||
Imports UTS_Core.UTSModule.DbConnect
|
||
|
||
Imports UTS_Core.UTSModule.Station
|
||
Imports UTS_Core.UTSModule.Station.StationTestPlan
|
||
|
||
Imports UTS_Core.UTSModule.Test.Command
|
||
Imports UTS_Core.UTSModule.Test.StatusMonitor
|
||
Imports UTS_Core.UTSModule.Test.StatusMonitor.TestStatusMonitor
|
||
|
||
Namespace UTSModule.Test
|
||
Public Class TestNodeCompletedEventArgs
|
||
Inherits EventArgs
|
||
|
||
Sub New(node As RowNode, testReturn As TestCommandReturn)
|
||
Me.Node = node
|
||
Me.TestReturn = testReturn
|
||
End Sub
|
||
|
||
Public Property Node() As RowNode
|
||
|
||
Public Property TestReturn() As TestCommandReturn
|
||
End Class
|
||
|
||
Public Class TestNodeResultChangedEventArgs
|
||
Inherits EventArgs
|
||
|
||
Sub New(node As RowNode, testReturn As TestCommandReturn)
|
||
Me.Node = node
|
||
Me.TestReturn = testReturn
|
||
End Sub
|
||
|
||
Public Property Node() As RowNode
|
||
|
||
Public Property TestReturn() As TestCommandReturn
|
||
End Class
|
||
|
||
Public Class TestNodeChangedEventArgs
|
||
Inherits EventArgs
|
||
|
||
Sub New(node As RowNode)
|
||
Me.Node = node
|
||
End Sub
|
||
|
||
Public Property Node() As RowNode
|
||
|
||
End Class
|
||
|
||
|
||
Public Class TestProgressChangedEventArgs
|
||
Inherits EventArgs
|
||
|
||
Sub New(process As Double)
|
||
Percent = process
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' 当前百分比
|
||
''' </summary>
|
||
''' <returns></returns>
|
||
Public Property Percent As Double
|
||
End Class
|
||
|
||
|
||
Public Class TestCountChangedEventArgs
|
||
Inherits EventArgs
|
||
|
||
Sub New(pass As Integer, fail As Integer)
|
||
PassCount = pass
|
||
FailCount = fail
|
||
End Sub
|
||
|
||
Public Property PassCount As Integer
|
||
|
||
Public Property FailCount As Integer
|
||
|
||
Public ReadOnly Property Count() As Integer
|
||
Get
|
||
Return PassCount + FailCount
|
||
End Get
|
||
End Property
|
||
|
||
End Class
|
||
|
||
Public Class TestTimeEventArgs
|
||
Inherits EventArgs
|
||
|
||
Sub New(span As TimeSpan)
|
||
TimeElapsed = span
|
||
End Sub
|
||
|
||
Public Property TimeElapsed() As TimeSpan
|
||
End Class
|
||
|
||
Public Class TestPauseEventArgs
|
||
Sub New(node As RowNode)
|
||
Me.Node = node
|
||
End Sub
|
||
|
||
Public Property Node() As RowNode
|
||
End Class
|
||
|
||
Public Class TestFailEventArgs
|
||
Sub New(node As RowNode)
|
||
Me.Node = node
|
||
End Sub
|
||
|
||
Public Property Node() As RowNode
|
||
End Class
|
||
|
||
Public Class TestEndEventArgs
|
||
Inherits EventArgs
|
||
|
||
Sub New(result As TestResult)
|
||
TestResult = result
|
||
End Sub
|
||
|
||
Public Property TestResult() As TestResult
|
||
End Class
|
||
|
||
Public Class UtsTester
|
||
'''<summary>测试开始事件</summary>
|
||
Public Event TestStart(sender As Object, e As EventArgs)
|
||
|
||
'''<summary>测试暂停事件</summary>
|
||
Public Event TestPause(sender As Object, e As TestPauseEventArgs)
|
||
|
||
'''<summary>测试成功事件</summary>
|
||
Public Event TestPass(sender As Object, e As EventArgs)
|
||
|
||
'''<summary>测试失败事件</summary>
|
||
Public Event TestFail(sender As Object, e As TestFailEventArgs)
|
||
|
||
'''<summary>测试结束事件</summary>
|
||
Public Event TestEnd(sender As Object, e As TestEndEventArgs)
|
||
|
||
|
||
'''<summary>测试状态变更事件</summary>
|
||
Public Event TestStatusChanged(sender As Object, e As TestStatusChangedEventArgs)
|
||
|
||
'''<summary>测试计数变更事件</summary>
|
||
Public Event TestCountChanged(sender As Object, e As TestCountChangedEventArgs)
|
||
|
||
'''<summary>测试节点变更事件</summary>
|
||
Public Event TestNodeChanged(sender As Object, e As TestNodeChangedEventArgs)
|
||
|
||
'''<summary>测试节点完成事件</summary>
|
||
Public Event TestNodeCompleted(sender As Object, e As TestNodeCompletedEventArgs)
|
||
|
||
'''<summary>测试节点结果变化事件</summary>
|
||
Public Event TestNodeResultChanged(sender As Object, e As TestNodeResultChangedEventArgs)
|
||
|
||
'''<summary>测试时间变更事件</summary>
|
||
Public Event TestTimeChanged(sender As Object, e As TestTimeEventArgs)
|
||
|
||
'重试次数变更,加node
|
||
Public Event TestProgressChanged(sender As Object, e As TestProgressChangedEventArgs)
|
||
|
||
Public Event RetryProgressChanged(sender As Object, e As TestProgressChangedEventArgs)
|
||
|
||
|
||
|
||
''' <summary>当前测试节点</summary>
|
||
Private _testNode As RowNode
|
||
|
||
''' <summary> 当前测试固定模块</summary>
|
||
Private _testFixedModule As FixedModuleEnum = FixedModuleEnum.None
|
||
|
||
''' <summary>测试耗时计时器</summary>
|
||
Private ReadOnly _testWatch As New Stopwatch
|
||
|
||
''' <summary>单步执行耗时计时器</summary>
|
||
Private ReadOnly _stepWatch As New Stopwatch
|
||
|
||
''' <summary>程序运行后,测试通过总数</summary>
|
||
Private _testPassCount As Integer
|
||
|
||
''' <summary>程序运行后,测试失败总数</summary>
|
||
Private _testFailCount As Integer
|
||
|
||
''' <summary>是否已执行设置模块</summary>
|
||
Private _setupModuleExecuted As Boolean
|
||
|
||
''' <summary>是否处于调试断点</summary>
|
||
Private _nodePaused As Boolean
|
||
|
||
''' <summary>是否退出调试断点</summary>
|
||
Private _exitPaused As Boolean
|
||
|
||
''' <summary>是否下一节点调试断点</summary>
|
||
Private _nextPause As Boolean
|
||
|
||
''' <summary>内置模块入口集合</summary>
|
||
Private ReadOnly _testModules As Dictionary(Of String, RowNode)
|
||
|
||
''' <summary>自定义模块下函数入口集合</summary>
|
||
Private ReadOnly _customModules As Dictionary(Of String, RowNode)
|
||
|
||
''' <summary>测试结果内容</summary>
|
||
Private ReadOnly _testResult As TestResult
|
||
|
||
''' <summary>是否退出测试</summary>
|
||
Private _exitTest As Boolean
|
||
|
||
''' <summary>测试时间线程</summary>
|
||
Private ReadOnly _timeThread As Thread
|
||
|
||
''' <summary>测试过程中,产生的变量存储</summary>
|
||
Private ReadOnly _userVar As New Dictionary(Of String, String)
|
||
|
||
''' <summary>测试过程中,全局变量存储</summary>
|
||
Private ReadOnly _globalVar As New Dictionary(Of String, String)
|
||
|
||
''' <summary>测试过程中,使用的测试站位</summary>
|
||
Private _processStation As ProcessStation
|
||
|
||
''' <summary>测试器句柄,全局唯一</summary>
|
||
Private Shared _tester As UtsTester
|
||
|
||
''' <summary>初始化测试器线程锁</summary>
|
||
Private Shared ReadOnly InitLock As New Object()
|
||
|
||
Private _startTestIndex As Integer
|
||
Private _endTestIndex As Integer
|
||
Private _testCount As Integer
|
||
|
||
|
||
|
||
|
||
''' <summary>
|
||
''' 创建测试器,若测试器已经创建则返回句柄
|
||
''' </summary>
|
||
''' <returns></returns>
|
||
Public Shared Function CreateTester() As UtsTester
|
||
If _tester Is Nothing Then
|
||
SyncLock InitLock
|
||
Thread.MemoryBarrier()
|
||
If _tester Is Nothing Then
|
||
_tester = New UtsTester
|
||
End If
|
||
End SyncLock
|
||
End If
|
||
Return _tester
|
||
End Function
|
||
|
||
|
||
|
||
Private Sub New()
|
||
_testResult = New TestResult()
|
||
_testResult.AppName = Windows.Forms.Application.ProductName & Windows.Forms.Application.ProductVersion
|
||
_testResult.ServiceID = CInt(UtsRegistry.DataServiceIndex)
|
||
|
||
_testModules = New Dictionary(Of String, RowNode)()
|
||
_customModules = New Dictionary(Of String, RowNode)
|
||
|
||
_testWatch = New Stopwatch()
|
||
_stepWatch = New Stopwatch()
|
||
|
||
_exitTest = False
|
||
|
||
TestStatus = TestStatusEnum.WaitForTest
|
||
|
||
TestFailMode = TestFailModeEnum.StepFail
|
||
|
||
_timeThread = New Thread(AddressOf TestTime)
|
||
_timeThread.IsBackground = True
|
||
_timeThread.Start()
|
||
End Sub
|
||
|
||
|
||
Public Property DebugMode() As Boolean
|
||
|
||
|
||
''' <summary>测试状态</summary>
|
||
Public Property TestStatus As TestStatusEnum
|
||
Get
|
||
Return TestStatusMonitor.TestStatus
|
||
End Get
|
||
Set(value As TestStatusEnum)
|
||
TestStatusMonitor.TestStatus = value
|
||
End Set
|
||
End Property
|
||
|
||
|
||
Public ReadOnly Property TestResult() As TestResult
|
||
Get
|
||
Return _testResult
|
||
End Get
|
||
End Property
|
||
|
||
Public ReadOnly Property TestFiexdModule As FixedModuleEnum
|
||
Get
|
||
Return _testFixedModule
|
||
End Get
|
||
End Property
|
||
|
||
''' <summary>
|
||
''' 判定测试失败的模式
|
||
''' </summary>
|
||
''' <returns></returns>
|
||
Public Property TestFailMode() As TestFailModeEnum
|
||
|
||
''' <summary>
|
||
''' 测试时,重新执行Setup模块
|
||
''' </summary>
|
||
Public Sub RerunSetupModule()
|
||
_setupModuleExecuted = False
|
||
End Sub
|
||
|
||
Public Property ProcessStation() As ProcessStation
|
||
Get
|
||
Return _processStation
|
||
End Get
|
||
Set(value As ProcessStation)
|
||
'测试站位修改
|
||
|
||
_processStation = value
|
||
|
||
_setupModuleExecuted = False
|
||
UpdateTestModule(CType(_processStation.Packet.StationPlan, StationTestPlan).RowNodes)
|
||
|
||
_testResult.TestPlan = _processStation.Packet.FileName
|
||
End Set
|
||
End Property
|
||
|
||
''' <summary>
|
||
''' 获取指定名称的模块节点
|
||
''' </summary>
|
||
''' <param name="name"></param>
|
||
''' <returns></returns>
|
||
Public Function GetModule(name As String) As RowNode
|
||
If _customModules.ContainsKey($"{name}") = False Then Return Nothing
|
||
Return _customModules($"{name}")
|
||
End Function
|
||
|
||
|
||
Public Function GetFixedModule(name As FixedModuleEnum) As RowNode
|
||
If _testModules.ContainsKey($"{name}") = False Then Return Nothing
|
||
Return _testModules($"{name}")
|
||
End Function
|
||
|
||
Private Sub TestTime()
|
||
While _testWatch IsNot Nothing
|
||
If _testWatch.IsRunning Then
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
End If
|
||
Thread.Sleep(100)
|
||
End While
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' 开始测试,此函数为正式测试调用
|
||
''' </summary>
|
||
Public Sub StartTest()
|
||
|
||
_userVar.Clear() '清空全局变量
|
||
_testResult.ResetTestResult() '重置测试结果
|
||
|
||
DebugMode = False
|
||
_exitTest = False
|
||
|
||
RaiseEvent TestStart(Me, New EventArgs())
|
||
|
||
'重置测试进度
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(0))
|
||
|
||
'测试主代码
|
||
TestFunction()
|
||
|
||
'进度修改百分百
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(100))
|
||
|
||
'测试完成
|
||
RaiseEvent TestEnd(Me, New TestEndEventArgs(_testResult))
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' 开始调试测试,此函数为正式测试调用
|
||
''' </summary>
|
||
Public Sub StartDebugTest()
|
||
DebugMode = True
|
||
_exitTest = False
|
||
|
||
_userVar.Clear() '清空全局变量
|
||
_testResult.ResetTestResult() '重置测试结果
|
||
|
||
RaiseEvent TestStart(Me, New EventArgs())
|
||
|
||
'重置测试进度
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(0))
|
||
|
||
|
||
|
||
'测试主代码
|
||
TestFunction()
|
||
|
||
'进度修改百分百
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(100))
|
||
|
||
'测试完成
|
||
RaiseEvent TestEnd(Me, New TestEndEventArgs(_testResult))
|
||
End Sub
|
||
|
||
|
||
''' <summary>
|
||
''' 流程修改后保存,更新模块索引
|
||
''' </summary>
|
||
''' <param name="sender"></param>
|
||
''' <param name="e"></param>
|
||
Public Sub StationEditStatusChanged(sender As Object, e As StationEditStatusChangedEventArgs)
|
||
If e.Status = StationEditStatusMonitor.StationEditStatusEnum.Saved Then
|
||
'更新测试流程所有函数入口
|
||
'UpdateTestModule(ProcessStation.Packet.StationPlan.HeadNode.RowNodes)
|
||
UpdateTestModule(CType(_processStation.Packet.StationPlan, StationTestPlan).RowNodes)
|
||
|
||
'测试将重新执行设置模块
|
||
_setupModuleExecuted = False
|
||
End If
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' 更新测试模块入库
|
||
''' </summary>
|
||
Public Sub UpdateTestModule(rowNodes As RowNodeCollection)
|
||
_testModules.Clear()
|
||
|
||
GetTestModule(_testModules, rowNodes)
|
||
End Sub
|
||
|
||
|
||
''' <summary>
|
||
''' 获取执行行节点集合中测试模块入口,并存储至内部模块入口集合
|
||
''' </summary>
|
||
''' <param name="modules">存储测试模块入口集合</param>
|
||
''' <param name="nodes">行节点集合</param>
|
||
Private Sub GetTestModule(modules As Dictionary(Of String, RowNode), nodes As RowNodeCollection)
|
||
For Each node As RowNode In nodes
|
||
If node.RowType = RowNode.RowTypeEnum.FixedModule OrElse node.RowType = RowNode.RowTypeEnum.Module Then
|
||
If String.IsNullOrWhiteSpace(node.Label) Then Continue For
|
||
If modules.ContainsKey(node.Label) Then Continue For
|
||
modules.Add(node.Label, node)
|
||
End If
|
||
|
||
If node.Label = $"{FixedModuleEnum.Custom}" Then
|
||
_customModules.Clear()
|
||
GetTestModule(_customModules, node.RowNodes)
|
||
End If
|
||
Next
|
||
End Sub
|
||
|
||
Public Function GetCustomModuleName() As String()
|
||
Return _customModules.Keys.ToArray()
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 执行内置模块函数
|
||
''' </summary>
|
||
''' <param name="moduleName"></param>
|
||
''' <returns></returns>
|
||
Public Function ExecuteFixedModule(moduleName As FixedModuleEnum) As TestCommandReturn
|
||
Dim result As TestCommandReturn
|
||
|
||
_testFixedModule = moduleName
|
||
If _testModules.ContainsKey(moduleName.ToString()) Then
|
||
Dim node As RowNode = _testModules(moduleName.ToString())
|
||
node.IsRetry = False '顶级节点最初重试状态为false
|
||
result = ExecutePlan(node, Nothing)
|
||
Else
|
||
result = New TestCommandReturn()
|
||
result.ExecuteResult = False
|
||
result.ExecuteResultTipString = $"未搜索到[{moduleName}]模块"
|
||
End If
|
||
|
||
_testFixedModule = FixedModuleEnum.None '重置测试固定模块
|
||
Return result
|
||
End Function
|
||
|
||
|
||
#Region "获取特殊情况返回"
|
||
''' <summary>
|
||
''' 获取用户退出测试的执行返回结果
|
||
''' </summary>
|
||
''' <returns></returns>
|
||
Private Function GetExitTestReturn() As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
|
||
result.ExecuteResult = False
|
||
result.ExecuteResultTipString = $"用户结束测试过程"
|
||
|
||
Return result
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' 获取不运行的节点的执行返回结果
|
||
''' </summary>
|
||
''' <returns></returns>
|
||
Private Function GetNotActionNodeResult() As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
|
||
result.ExecuteResult = True
|
||
result.ExecuteResultTipString = $"无需执行的测试节点"
|
||
|
||
Return result
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 获取未知的行节点类型的执行返回结果
|
||
''' </summary>
|
||
''' <param name="node">当前行节点</param>
|
||
''' <returns></returns>
|
||
Private Function GetUnknownTypeNodeResult(node As RowNode) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
|
||
result.ExecuteResult = False
|
||
result.ExecuteResultTipString = $"未知的节点类型:{node.RowType}"
|
||
|
||
Return result
|
||
End Function
|
||
|
||
Private Function GetNullControlTypeResult() As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
|
||
result.ExecuteResult = True
|
||
result.ExecuteResultTipString = $"无效的控制类型,默认跳过执行"
|
||
|
||
Return result
|
||
End Function
|
||
|
||
|
||
Private Function GetUnknownControlTypeResult(node As RowNode) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
|
||
result.ExecuteResult = False
|
||
result.ExecuteResultTipString = $"未知的控制类型:{node.ControlType}"
|
||
|
||
Return result
|
||
End Function
|
||
#End Region
|
||
|
||
#Region "执行流程"
|
||
Public Function ExecutePlan(node As RowNode, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommandReturn
|
||
Dim result As TestCommandReturn
|
||
If _exitTest Then Return GetExitTestReturn()
|
||
|
||
If node.Action = False Then Return GetNotActionNodeResult()
|
||
|
||
If TestStatus = TestStatusEnum.Testing Then _testNode = node
|
||
|
||
'节点测试开始
|
||
RaiseEvent TestNodeChanged(Me, New TestNodeChangedEventArgs(node))
|
||
|
||
'调试模式检测断点
|
||
If DebugMode Then
|
||
'断点调试
|
||
While node.Pause OrElse _nextPause
|
||
'已进入暂停状态
|
||
If _nodePaused = False Then
|
||
_nodePaused = True
|
||
RaiseEvent TestPause(Me, New TestPauseEventArgs(node))
|
||
End If
|
||
|
||
If _exitPaused Then Exit While
|
||
If _exitTest Then Return GetExitTestReturn()
|
||
|
||
Thread.Sleep(100)
|
||
End While
|
||
_nodePaused = False
|
||
_exitPaused = False
|
||
End If
|
||
|
||
'获取测试结果
|
||
Select Case node.RowType
|
||
Case RowNode.RowTypeEnum.FixedModule, RowNode.RowTypeEnum.Module
|
||
result = ExecuteModuleNode(node, localVariable)
|
||
Case RowNode.RowTypeEnum.Control
|
||
result = ExecuteControlNode(node, localVariable)
|
||
Case RowNode.RowTypeEnum.Flow
|
||
result = ExecuteFlowNode(node, localVariable)
|
||
Case Else
|
||
result = GetUnknownTypeNodeResult(node)
|
||
End Select
|
||
|
||
node.TestReturn = result
|
||
|
||
'节点测试完成
|
||
RaiseEvent TestNodeCompleted(Me, New TestNodeCompletedEventArgs(node, result))
|
||
|
||
Return result
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 执行模块流程
|
||
''' </summary>
|
||
''' <param name="node"></param>
|
||
''' <returns></returns>
|
||
Public Function ExecuteModuleNode(node As RowNode, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
|
||
For retry As Integer = 0 To node.Retry '最大执行总数为:1+重试次数
|
||
'退出执行检测
|
||
If _exitTest Then Return GetExitTestReturn()
|
||
|
||
'更新重试进度
|
||
Dim p As Double = CDbl(IIf(retry = 0, 100, (node.Retry - retry) / node.Retry * 100))
|
||
RaiseEvent RetryProgressChanged(Me, New TestProgressChangedEventArgs(p))
|
||
|
||
'判断节点是否为重试状态
|
||
If retry > 0 Then node.IsRetry = True
|
||
|
||
If localVariable IsNot Nothing AndAlso localVariable.ContainsKey("CH") Then
|
||
Console.WriteLine($"CH:{localVariable("CH")} Label:{node.Label} Desc:{node.Description} RetryCount:{retry} IsRetry:{node.IsRetry}")
|
||
End If
|
||
|
||
'重置模块测试结果
|
||
result.ExecuteResult = True
|
||
|
||
'测试子节点
|
||
For Each rowNode As RowNode In node.RowNodes
|
||
If _exitTest Then Return GetExitTestReturn() '退出执行检测
|
||
|
||
rowNode.IsRetry = node.IsRetry '将父节点的重试状态赋予子节点
|
||
If ExecutePlan(rowNode, localVariable).ExecuteResult = False Then result.ExecuteResult = False '节点测试失败则认为模块失败
|
||
If result.ExecuteResult Then Continue For '执行成功则执行下一流程
|
||
If TestFailMode = TestFailModeEnum.StepFail Then Exit For '单步失败模式下退出测试,不再执行
|
||
Next
|
||
|
||
'模块测试成功则退出重试
|
||
If result.ExecuteResult Then Exit For
|
||
Thread.Sleep(node.RetryInterval) '执行失败,休眠重试间隔
|
||
Next
|
||
|
||
node.IsRetry = True 'todo:临时解决call命令调用函数时多层级模块 节点变更与节点完成的非唯一节点bug
|
||
|
||
Return result
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 执行控制流程
|
||
''' </summary>
|
||
''' <param name="node"></param>
|
||
''' <returns>测试结果</returns>
|
||
Private Function ExecuteControlNode(node As RowNode, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommandReturn
|
||
If _exitTest Then Return GetExitTestReturn() '退出测试
|
||
If String.IsNullOrWhiteSpace(node.ControlType) Then Return GetNullControlTypeResult()
|
||
|
||
Dim result As New TestCommandReturn
|
||
Select Case node.ControlType
|
||
Case "If"
|
||
result.ExecuteResult = ExecuteIfControlNode(node).ExecuteResult
|
||
Case "While"
|
||
result.ExecuteResult = ExecuteWhileControlNode(node).ExecuteResult
|
||
Case Else
|
||
result = GetUnknownControlTypeResult(node)
|
||
End Select
|
||
|
||
Return result
|
||
End Function
|
||
|
||
Private Function ExecuteIfControlNode(node As RowNode, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommandReturn
|
||
'无子节点,默认通过
|
||
'判断成功,无Then节点,默认成功
|
||
'判断失败,无Else节点默认成功
|
||
'控制流程只有子节点失败才算失败,判断条件失败,忽略失败
|
||
|
||
Dim result As New TestCommandReturn
|
||
|
||
Dim tmpResult As TestCommandReturn 'if分支的判断结果
|
||
tmpResult = ExecuteControlCondition(node, localVariable) '获取If判断条件的结果
|
||
For Each rowNode As RowNode In node.RowNodes
|
||
If tmpResult.ExecuteResult Then
|
||
If rowNode.ControlType = "Then" Then
|
||
|
||
result = ExecuteModuleNode(rowNode, localVariable)
|
||
Exit For
|
||
End If
|
||
Else
|
||
Select Case rowNode.ControlType
|
||
Case "ElseIf" '执行判断条件命令成功则认为匹配成功,返回执行子节点的结果
|
||
|
||
tmpResult = ExecuteControlCondition(rowNode, localVariable)
|
||
If tmpResult.ExecuteResult Then '判断条件成立
|
||
result = ExecuteModuleNode(rowNode, localVariable)
|
||
Exit For
|
||
End If
|
||
|
||
Case "Else"
|
||
result = ExecuteModuleNode(rowNode, localVariable)
|
||
Exit For
|
||
End Select
|
||
End If
|
||
Next
|
||
|
||
Return result
|
||
End Function
|
||
|
||
|
||
Private Function ExecuteWhileControlNode(node As RowNode, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommandReturn
|
||
Dim result As TestCommandReturn
|
||
result = ExecuteControlCondition(node, localVariable) '执行while节点判断条件
|
||
If result.ExecuteResult Then
|
||
result = ExecuteModuleNode(node, localVariable) '执行While内部流程
|
||
|
||
'内部循环节点成功执行成功则递归调用本身,直至while条件不成立
|
||
If result.ExecuteResult Then result = ExecuteWhileControlNode(node)
|
||
Else
|
||
|
||
'执行判断条件失败则退出While,并认为执行成功
|
||
result.ExecuteResult = True
|
||
End If
|
||
|
||
Return result
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' 执行控制结构的条件部分
|
||
''' </summary>
|
||
''' <param name="node"></param>
|
||
''' <returns></returns>
|
||
Private Function ExecuteControlCondition(node As RowNode, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
If String.IsNullOrWhiteSpace(node.Command) Then Return result
|
||
|
||
|
||
Dim cmd As New TestCommand(node) '获取执行参数
|
||
ReplaceValue(cmd) '执行前变量替换
|
||
Dim executor As TestCommandExecutor = TestCommandManger.CreateExecutor(cmd) '创建执行器
|
||
result = executor.Execute() '获取执行返回
|
||
|
||
|
||
If String.IsNullOrWhiteSpace(node.RecordName) = False Then '处理需要入库的数据
|
||
Dim filedName As String = ReplaceString(node.RecordName, localVariable) '替换记录名称中变量
|
||
If _userVar.ContainsKey(filedName) Then
|
||
_userVar(filedName) = result.RecordValue
|
||
Else
|
||
_userVar.Add(filedName, result.RecordValue)
|
||
End If
|
||
|
||
If node.SaveToDb Then
|
||
'添加内容至数据库字段中
|
||
_testResult.AddCustomRecord(filedName, result.RecordValue)
|
||
End If
|
||
End If
|
||
|
||
Return result
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' 执行类型为普通流程的行节点
|
||
''' </summary>
|
||
''' <param name="node"></param>
|
||
''' <param name="localVariable"></param>
|
||
''' <returns></returns>
|
||
Public Function ExecuteFlowNode(node As RowNode, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
If String.IsNullOrWhiteSpace(node.Command) Then Return result
|
||
|
||
Dim watch As Stopwatch = Stopwatch.StartNew() '开启单步计时
|
||
Dim cmd As New TestCommand(node) '获取执行参数
|
||
ReplaceValue(cmd, localVariable) '执行前变量替换
|
||
Dim executor As TestCommandExecutor = TestCommandManger.CreateExecutor(cmd) '创建执行器
|
||
|
||
node.Desc4Record = ReplaceString(node.Description, localVariable) '替换记录名称中变量
|
||
|
||
'最大执行总数为:1+重试次数
|
||
For retry As Integer = 0 To node.Retry
|
||
If _exitTest Then Exit For
|
||
|
||
'更新重试进度
|
||
Dim p As Double = CDbl(IIf(retry = 0, 100, (node.Retry - retry) / node.Retry * 100))
|
||
RaiseEvent RetryProgressChanged(Me, New TestProgressChangedEventArgs(p))
|
||
|
||
'更新命令是否处于重试状态
|
||
If retry > 0 Then node.IsRetry = True
|
||
executor.IsRetry = node.IsRetry
|
||
|
||
'执行成功一次则判定成功,退出执行
|
||
result = executor.Execute()
|
||
RaiseEvent TestNodeResultChanged(Me, New TestNodeResultChangedEventArgs(node, result))
|
||
If result.ExecuteResult Then Exit For
|
||
|
||
'执行失败,休眠重试间隔
|
||
Thread.Sleep(node.RetryInterval)
|
||
Next
|
||
|
||
watch.Stop()
|
||
result.StepTimeSpan = watch.Elapsed
|
||
|
||
'进度修改
|
||
If node.RowListIndex > _startTestIndex AndAlso node.RowListIndex < _endTestIndex Then
|
||
Dim p As Double = (node.RowListIndex - _startTestIndex) / _testCount * 100
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(p))
|
||
End If
|
||
|
||
'todo:节点测试数据,考虑是否与节点测试完成事件合并
|
||
|
||
If String.IsNullOrWhiteSpace(node.RecordName) = False Then '处理需要入库的数据
|
||
Dim filedName As String = ReplaceString(node.RecordName, localVariable) '替换记录名称中变量
|
||
If _userVar.ContainsKey(filedName) Then
|
||
_userVar(filedName) = result.RecordValue
|
||
Else
|
||
_userVar.Add(filedName, result.RecordValue)
|
||
End If
|
||
|
||
If node.SaveToDb Then '添加内容至数据库字段中
|
||
_testResult.AddCustomRecord(filedName, result.RecordValue)
|
||
End If
|
||
End If
|
||
|
||
Return result
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' 获取指定变量名的变量值
|
||
''' </summary>
|
||
''' <param name="varName">变量名</param>
|
||
''' <param name="localVariable">调用模块时传入的局部变量</param>
|
||
''' <returns></returns>
|
||
Private Function ReplaceVar(varName As String, Optional localVariable As Dictionary(Of String, String) = Nothing) As String
|
||
'替换变量的逻辑顺序
|
||
'优先替换局部变量,也就是传进模块的变量
|
||
'其次使用用户变量,也就是记录入库的变量
|
||
'最后匹配系统变量,也就是预设带有特殊意义的字符串
|
||
If localVariable IsNot Nothing AndAlso localVariable.ContainsKey(varName) Then
|
||
Return localVariable(varName)
|
||
Else
|
||
If _userVar.ContainsKey(varName) Then
|
||
Return _userVar(varName)
|
||
Else
|
||
Select Case varName
|
||
Case "ResourceDir"
|
||
Return UtsPath.StationPacketResourceDirPath
|
||
Case "StartDir"
|
||
Return UtsPath.SystemDirPath
|
||
Case Else
|
||
Return String.Empty '返回空字符
|
||
End Select
|
||
End If
|
||
End If
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' 替换字符串中使用的变量,返回替换后的字符串
|
||
''' </summary>
|
||
''' <param name="sourceString">原字符串</param>
|
||
''' <param name="localVariable">调用模块时传入的局部变量</param>
|
||
''' <returns>替换后的字符串</returns>
|
||
Private Function ReplaceString(sourceString As String, Optional localVariable As Dictionary(Of String, String) = Nothing) As String
|
||
Dim strBuilder As New StringBuilder
|
||
Dim varName As New StringBuilder
|
||
Dim findVar As Boolean
|
||
|
||
For Each c As Char In sourceString
|
||
If c = "{"c Then
|
||
If findVar Then
|
||
findVar = False
|
||
strBuilder.Append("{")
|
||
Else
|
||
findVar = True
|
||
End If
|
||
ElseIf c = "}"c Then
|
||
If findVar Then
|
||
strBuilder.Append(ReplaceVar(varName.ToString(), localVariable))
|
||
varName.Clear()
|
||
findVar = False
|
||
Else
|
||
strBuilder.Append("}")
|
||
End If
|
||
Else
|
||
If findVar Then
|
||
varName.Append(c)
|
||
Else
|
||
strBuilder.Append(c)
|
||
End If
|
||
End If
|
||
Next
|
||
|
||
Return strBuilder.ToString
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' 替换测试命令参数中的变量(变量格式:{var}),待删除
|
||
''' </summary>
|
||
''' <param name="cmd"></param>
|
||
''' <returns></returns>
|
||
Private Function ReplaceValue(cmd As TestCommand, Optional localVariable As Dictionary(Of String, String) = Nothing) As TestCommand
|
||
Dim strBuilder As New StringBuilder
|
||
Dim varName As New StringBuilder
|
||
Dim findVar As Boolean
|
||
|
||
For i As Integer = 0 To cmd.Parameter.Count - 1
|
||
findVar = False
|
||
varName.Clear()
|
||
strBuilder.Clear()
|
||
For Each c As Char In cmd.Parameter(i)
|
||
If c = "{"c Then
|
||
If findVar Then
|
||
findVar = False
|
||
strBuilder.Append("{")
|
||
Else
|
||
findVar = True
|
||
End If
|
||
ElseIf c = "}"c Then
|
||
If findVar Then
|
||
strBuilder.Append(ReplaceVar(varName.ToString(), localVariable))
|
||
varName.Clear()
|
||
findVar = False
|
||
Else
|
||
strBuilder.Append("}")
|
||
End If
|
||
Else
|
||
If findVar Then
|
||
varName.Append(c)
|
||
Else
|
||
strBuilder.Append(c)
|
||
End If
|
||
End If
|
||
Next
|
||
cmd.Parameter(i) = strBuilder.ToString()
|
||
Next
|
||
Return cmd
|
||
End Function
|
||
|
||
Public Sub StepTest()
|
||
If TestStatus <> TestStatusEnum.Testing Then Return
|
||
_nextPause = True
|
||
If _nodePaused Then
|
||
_exitPaused = True
|
||
End If
|
||
End Sub
|
||
|
||
Public Sub ContinueTest()
|
||
If TestStatus <> TestStatusEnum.Testing Then Return
|
||
_nextPause = False
|
||
_exitPaused = True
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' 退出执行,测试结果为失败
|
||
''' </summary>
|
||
Public Sub ExitTest()
|
||
If TestStatus <> TestStatusEnum.Testing Then Return
|
||
_exitTest = True
|
||
|
||
_nextPause = False
|
||
_exitPaused = True
|
||
MsgBox($"{TestStatus}:{_exitTest}:{_nextPause}:{_exitPaused}")
|
||
End Sub
|
||
|
||
#End Region
|
||
|
||
#Region "测试函数集合"
|
||
|
||
''' <summary>
|
||
''' 测试主函数,测试Main模块,根据测试结果测试Pass/Fail模块
|
||
''' </summary>
|
||
Private Sub TestFunction()
|
||
_testResult.ResetTestResult() '重置测试结果信息
|
||
|
||
'初始化测试总项数据,用于进度条计算
|
||
_startTestIndex = _testModules(FixedModuleEnum.Main.ToString).RowListIndex
|
||
_endTestIndex = _startTestIndex + _testModules(FixedModuleEnum.Main.ToString).AllChildCount
|
||
_testCount = _testModules(FixedModuleEnum.Main.ToString).AllChildCount
|
||
|
||
TestStatus = TestStatusEnum.Testing
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
Dim result As TestCommandReturn
|
||
If _setupModuleExecuted = False Then '设定模块未执行
|
||
result = ExecuteFixedModule(FixedModuleEnum.Setup)
|
||
If result.ExecuteResult Then
|
||
_setupModuleExecuted = True
|
||
Else
|
||
result.ExecuteResultTipString &= $"[{FixedModuleEnum.Setup}]模块执行失败,{result.ExecuteResultTipString}"
|
||
|
||
TestStatus = TestStatusEnum.TestFail
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
'todo:结束测试
|
||
' TestEnd
|
||
Return
|
||
End If
|
||
End If
|
||
|
||
_testWatch.Restart()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
result = ExecuteFixedModule(FixedModuleEnum.Main)
|
||
If result.ExecuteResult Then '执行测试主模块
|
||
_testPassCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Pass
|
||
ExecuteFixedModule(FixedModuleEnum.Pass) '执行测试成功模块
|
||
RaiseEvent TestPass(Me, New EventArgs())
|
||
|
||
TestStatus = TestStatusEnum.TestPass
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
Else
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
_testResult.FailSteps.Add(_testNode)
|
||
_testResult.ErrCode = _testNode.ErrorCode
|
||
|
||
ExecuteFixedModule(FixedModuleEnum.Fail) '执行测试失败模块
|
||
RaiseEvent TestFail(Me, New TestFailEventArgs(_testNode))
|
||
|
||
TestStatus = TestStatusEnum.TestFail
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
End If
|
||
RaiseEvent TestCountChanged(Me, New TestCountChangedEventArgs(_testPassCount, _testFailCount))
|
||
|
||
_testWatch.Stop()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
_testResult.UserID = ProcessStation.UserId
|
||
_testResult.UsedTime = _testWatch.Elapsed
|
||
_testResult.OrderID = DbConnector.SearchOrderID(_processStation.ParentProject.Index, _testResult.DUT_SN)
|
||
End Sub
|
||
|
||
|
||
''' <summary>
|
||
''' 调试测试当前节点及其子节点
|
||
''' </summary>
|
||
''' <param name="obj">节点对象</param>
|
||
Public Sub TestNode(obj As Object)
|
||
Dim node As RowNode = CType(obj, RowNode)
|
||
|
||
DebugMode = True
|
||
'初始化测试总项数据,用于进度条计算
|
||
_startTestIndex = node.RowListIndex
|
||
_endTestIndex = _startTestIndex + node.AllChildCount
|
||
_testCount = node.AllChildCount
|
||
|
||
_exitTest = False
|
||
_testResult.ResetTestResult() '重置测试结果信息
|
||
|
||
RaiseEvent TestStart(Me, New EventArgs())
|
||
_userVar.Clear() '清空全局变量
|
||
|
||
TestStatus = TestStatusEnum.Testing
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testWatch.Restart()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
Dim result As TestCommandReturn = ExecutePlan(node, Nothing)
|
||
If result.ExecuteResult Then
|
||
TestStatus = TestStatusEnum.TestPass
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestPass(Me, New EventArgs())
|
||
Else
|
||
TestStatus = TestStatusEnum.TestFail
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestFail(Me, New TestFailEventArgs(_testNode))
|
||
End If
|
||
|
||
_testWatch.Stop()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
'进度修改百分百
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(100))
|
||
|
||
RaiseEvent TestEnd(Me, New TestEndEventArgs(_testResult))
|
||
|
||
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' 从当前节点调试测试,直到测试完当前顶级模块
|
||
''' </summary>
|
||
''' <param name="obj">节点对象</param>
|
||
Public Sub TestBeginWithNode(obj As Object)
|
||
Dim node As RowNode = CType(obj, RowNode)
|
||
|
||
|
||
'获取顶级节点
|
||
Dim tmpNode As RowNode = node
|
||
While tmpNode.RowLever > 0
|
||
tmpNode = tmpNode.ParentNode
|
||
End While
|
||
|
||
'初始化测试总项数据,用于进度条计算
|
||
_startTestIndex = node.RowListIndex
|
||
_endTestIndex = tmpNode.RowIndex + tmpNode.AllChildCount
|
||
_testCount = _endTestIndex - _startTestIndex
|
||
|
||
DebugMode = True
|
||
_exitTest = False
|
||
_testResult.ResetTestResult() '重置测试结果信息
|
||
|
||
RaiseEvent TestStart(Me, New EventArgs())
|
||
_userVar.Clear() '清空全局变量
|
||
|
||
TestStatus = TestStatusEnum.Testing
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testWatch.Restart()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
Dim result As TestCommandReturn = BeginWithNode(node)
|
||
If result.ExecuteResult Then
|
||
TestStatus = TestStatusEnum.TestPass
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestPass(Me, New EventArgs())
|
||
Else
|
||
TestStatus = TestStatusEnum.TestFail
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestFail(Me, New TestFailEventArgs(_testNode))
|
||
End If
|
||
|
||
_testWatch.Stop()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
'进度修改百分百
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(100))
|
||
|
||
RaiseEvent TestEnd(Me, New TestEndEventArgs(_testResult))
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' 测试单节点及之后的所有节点
|
||
''' </summary>
|
||
''' <param name="node"></param>
|
||
Private Function BeginWithNode(node As RowNode) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
While node IsNot Nothing
|
||
If _exitTest Then Return GetExitTestReturn()
|
||
|
||
result = ExecutePlan(node, Nothing)
|
||
If result.ExecuteResult = False Then
|
||
If TestFailMode = TestFailModeEnum.StepFail Then
|
||
Exit While '单步失败模式下退出测试,不再执行
|
||
End If
|
||
End If
|
||
|
||
If node.RowLever = 0 Then Exit While
|
||
If node.NextNode Is Nothing Then
|
||
|
||
node = node.ParentNode.NextNode
|
||
Else
|
||
node = node.NextNode
|
||
End If
|
||
End While
|
||
|
||
Return result
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 调试测试节点数组
|
||
''' </summary>
|
||
''' <param name="nodes"></param>
|
||
Public Sub TestNodes(nodes() As RowNode)
|
||
_exitTest = False
|
||
_testResult.ResetTestResult() '重置测试结果信息
|
||
|
||
RaiseEvent TestStart(Me, New EventArgs())
|
||
_userVar.Clear() '清空全局变量
|
||
|
||
TestStatus = TestStatusEnum.Testing
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testWatch.Restart()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
Dim result As TestCommandReturn = TestNodesFunction(nodes)
|
||
If result.ExecuteResult Then
|
||
TestStatus = TestStatusEnum.TestPass
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestPass(Me, New EventArgs())
|
||
Else
|
||
TestStatus = TestStatusEnum.TestFail
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestFail(Me, New TestFailEventArgs(_testNode))
|
||
End If
|
||
|
||
_testWatch.Stop()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
'进度修改百分百
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(100))
|
||
|
||
RaiseEvent TestEnd(Me, New TestEndEventArgs(_testResult))
|
||
End Sub
|
||
|
||
|
||
|
||
''' <summary>
|
||
''' 调试测试节点数组,包含其子节点
|
||
''' </summary>
|
||
''' <param name="nodes"></param>
|
||
Public Function TestNodesFunction(nodes() As RowNode) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
For Each node As RowNode In nodes
|
||
If _exitTest Then Return GetExitTestReturn() '退出测试
|
||
|
||
result = ExecutePlan(node, Nothing)
|
||
If result.ExecuteResult Then Continue For '执行成功则执行下一流程
|
||
If TestFailMode = TestFailModeEnum.StepFail Then Exit For '单步失败模式下退出测试,不再执行
|
||
Next
|
||
Return result
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 调试测试子节点集合
|
||
''' </summary>
|
||
''' <param name="nodes"></param>
|
||
Public Sub TestChildNodes(nodes As RowNodeCollection)
|
||
_exitTest = False
|
||
_testResult.ResetTestResult() '重置测试结果信息
|
||
|
||
RaiseEvent TestStart(Me, New EventArgs())
|
||
_userVar.Clear() '清空全局变量
|
||
|
||
TestStatus = TestStatusEnum.Testing
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testWatch.Restart()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
Dim result As TestCommandReturn = TestNodesFunction(nodes)
|
||
If result.ExecuteResult Then
|
||
TestStatus = TestStatusEnum.TestPass
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestPass(Me, New EventArgs())
|
||
Else
|
||
TestStatus = TestStatusEnum.TestFail
|
||
RaiseEvent TestStatusChanged(Me, New TestStatusChangedEventArgs(TestStatus))
|
||
|
||
_testFailCount += 1
|
||
_testResult.TestResult = TestResult.TestResultEnum.Fail
|
||
RaiseEvent TestFail(Me, New TestFailEventArgs(_testNode))
|
||
End If
|
||
|
||
_testWatch.Stop()
|
||
RaiseEvent TestTimeChanged(Me, New TestTimeEventArgs(_testWatch.Elapsed))
|
||
|
||
'进度修改百分百
|
||
RaiseEvent TestProgressChanged(Me, New TestProgressChangedEventArgs(100))
|
||
|
||
RaiseEvent TestEnd(Me, New TestEndEventArgs(_testResult))
|
||
End Sub
|
||
|
||
|
||
''' <summary>
|
||
''' 调试测试节点集合,及其子节点
|
||
''' </summary>
|
||
''' <param name="nodes"></param>
|
||
Public Function TestNodesFunction(nodes As RowNodeCollection) As TestCommandReturn
|
||
Dim result As New TestCommandReturn
|
||
For Each node As RowNode In nodes
|
||
If _exitTest Then Return GetExitTestReturn() '退出测试
|
||
|
||
result = ExecutePlan(node, Nothing)
|
||
If result.ExecuteResult Then Continue For '执行成功则执行下一流程
|
||
If TestFailMode = TestFailModeEnum.StepFail Then Exit For '单步失败模式下退出测试,不再执行
|
||
Next
|
||
Return result
|
||
End Function
|
||
|
||
Public Sub TestFixedModule([module] As FixedModuleEnum)
|
||
TestNode(_testModules($"{[module]}"))
|
||
End Sub
|
||
|
||
Public Sub TestSetupModule()
|
||
TestFixedModule(FixedModuleEnum.Setup)
|
||
End Sub
|
||
|
||
Public Sub TestMainModule()
|
||
TestFixedModule(FixedModuleEnum.Main)
|
||
End Sub
|
||
|
||
Public Sub TestPassModule()
|
||
TestFixedModule(FixedModuleEnum.Pass)
|
||
End Sub
|
||
|
||
Public Sub TestFailModule()
|
||
TestFixedModule(FixedModuleEnum.Fail)
|
||
End Sub
|
||
|
||
Public Sub TestCleanupModule()
|
||
TestFixedModule(FixedModuleEnum.Cleanup)
|
||
End Sub
|
||
#End Region
|
||
|
||
|
||
Enum TestFailModeEnum
|
||
''' <summary>
|
||
''' 单步测试失败后退出测试,判定测试失败
|
||
''' </summary>
|
||
StepFail
|
||
''' <summary>
|
||
''' 单步测试失败后继续测试,执行所有测试流程后,判定测试失败
|
||
''' </summary>
|
||
AllFail
|
||
End Enum
|
||
|
||
Enum NodeDebugMode
|
||
''' <summary>
|
||
''' 仅测试当前节点及其子节点
|
||
''' </summary>
|
||
OnlyNode
|
||
|
||
''' <summary>
|
||
''' 从节点开始往下测试
|
||
''' </summary>
|
||
BeginNode
|
||
End Enum
|
||
End Class
|
||
|
||
End Namespace |