51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 9157|回复: 22
打印 上一主题 下一主题

[原创] 轻量级qtp自动化测试框架

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2009-4-2 20:36:05 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
转贴: http://bbs.51testing.com/viewthread.php?tid=142508

下载了mklodoss改良的轻量级qtp自动化测试框架, 无法在公司看, 所以贴出来方便公司不允许下载的朋友阅读, 原文地址:http://bbs.51testing.com/viewthread.php?tid=142508

Driver.vbs:

Call driver()

Function driver()
        '初始化环境,包括获得project所在的本地目录。
        projectPath = getProjectPath()
        sourceDataFile = projectPath&"\testCases.xls"
        sourceDataSheet = "TestCases"
       
        Dim qtApp 'As QuickTest.Application ' Declare the Application object variable
        Dim qtTest 'As QuickTest.Test ' Declare a Test object variable
        Dim qtResultsOpt 'As QuickTest.RunResultsOptions ' Declare a Run Results Options object variable
       
        Set qtApp = CreateObject("QuickTest.Application") ' Create the Application object
        qtApp.Launch ' Start QuickTest
        qtApp.Visible = True ' Make the QuickTest application visible
        ' Set QuickTest run options
        qtApp.Options.Run.CaptureForTestResults = "OnError"
        qtApp.Options.Run.RunMode = "Fast"
        qtApp.Options.Run.ViewResults = False
       
        ' 打开入口的测试脚本,并且加载testCase的脚本
        qtApp.Open projectPath&"\Driver", False, False  ' 打开入口的测试脚本,可写,不保存
        Set qtTest = qtApp.Test
       
                ' set run settings for the test
                Set qtResultsOpt = CreateObject("QuickTest.RunResultsOptions")
                qtResultsOpt.ResultsLocation = projectPath&"\result" '运行结果保存到临时文件夹中
                qtTest.Run qtResultsOpt, True   

       
        qtTest.Close
        Set qtResultsOpt = Nothing ' Release the Run Results Options object
        Set qtTest = Nothing ' Release the Test object
        qtApp.quit
        Set qtApp = Nothing ' Release the Application object
End Function


Function getProjectPath()
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set objFile = objFSO.GetFile(wscript.scriptfullname)
        getProjectPath = objFSO.GetParentFolderName(objFile)
        Set objFSO = Nothing
        Set objFile = Nothing
End Function
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

23#
发表于 2014-6-16 17:09:40 | 只看该作者
楼主,你好,问个地方,我在XP环境下运行QTP10+IE8,QTP的addsheet没有在datatable页新新增一个页,也就是qtp的datatable没有新增sheet页成功
回复 支持 反对

使用道具 举报

该用户从未签到

22#
发表于 2014-6-16 17:09:17 | 只看该作者
楼主,你好,问个地方,我在XP环境下运行QTP10+IE8,QTP的addsheet没有在datatable页新新增一个页,也就是qtp的datatable没有新增sheet页成功
回复 支持 反对

使用道具 举报

该用户从未签到

21#
发表于 2012-4-17 10:40:27 | 只看该作者
If  err.number = 0 Then
                                   testSets.Add testsetName, setArray
                           else
                                Msgbox  "检查TestSets.xls表中的字段IDX, name, table, sheet 字段是否有错."
                           End If

请问各位大侠上面语句中
testSets.Add testsetName, setArray
这个语句是什么意思,有什么作用啊??
回复 支持 反对

使用道具 举报

  • TA的每日心情
    郁闷
    2018-11-15 14:58
  • 签到天数: 2 天

    连续签到: 2 天

    [LV.1]测试小兵

    20#
    发表于 2011-10-28 14:17:54 | 只看该作者
    这个框架有个问题:当有2个TASK以上时,如果都有参数,就会执行不下去的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    19#
    发表于 2011-8-10 14:46:12 | 只看该作者
    想知道tempArray = split(curPath,"\")这句是什么意思
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    18#
    发表于 2011-4-26 15:08:27 | 只看该作者
    回复 9# Jay-Yang84

    能留个联系方式吗?方便进一步探讨
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    17#
    发表于 2010-12-22 16:47:56 | 只看该作者
    看不懂,学习中
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    16#
    发表于 2010-12-20 18:54:17 | 只看该作者
    能多来点注释就好多了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    15#
    发表于 2010-4-16 16:14:13 | 只看该作者
    还是不太理解~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    14#
    发表于 2010-4-2 12:08:17 | 只看该作者
    LZ辛苦
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    13#
    发表于 2010-4-2 09:50:47 | 只看该作者
    大侠
    正在研究中。。。。。。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    12#
     楼主| 发表于 2009-4-2 20:47:51 | 只看该作者
    Demo.xls

    Dome.sheet:
    1. IDX
    2. bizName: 业务名称,对应task的脚本文件名称。并且脚本文件中有一个同名的class。脚本务必保证名称完全相同。暂时没有实现中英文名称的对照。业务流程的名字不能重复。
    3. taskName: 具体task的名称。这个操作是需要写脚本来实现的。对应于各个function的名称,不过暂时没有实现中英文的对照。
    4. bizDataTable: 数据所在Sheet的名称。如果引用的是其它Excel文件,需要在Sheet名称前面加上excel文件名。
    5. filter: 数据执行条件。仅执行复核此条件的数据。如果有多个条件,用分号";"隔开,也可以是中文的分号。身份=制单,其中“身份”是字段名称,“制单”是字段的值。此处不区分大小写。支持 >=, <= , <> ,> ,< ,= 这6种比较运算符。
    6. description: 描述该行步骤的一些备注信息。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    11#
     楼主| 发表于 2009-4-2 20:45:47 | 只看该作者
    TestSet.xls:

    TestCases sheet:
    1. IDX;
    2. name: 测试用例的中文名称,暂时没有做中英文对照。可以不填。
    3. table: 测试用例所在的Excel文件名,可以带后缀xls,也可以不带。这个Excel文件只需要放到project\testData文件夹下即可。子文件夹无所谓。
    4. sheet:测试用例所在的Sheet名称。如果不填,就默认为第一个Sheet。如果填了,就使用该值。
    5. prority: 测试用例的执行优先级别,暂未实现。
    6. description: 对该测试用例的一些描述。

    option sheet:
    执行        执行中        成功
    不执行        已完成        失败
    未知        出现异常        未知
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    10#
     楼主| 发表于 2009-4-2 20:42:29 | 只看该作者
    TestScript:
    Dome.vbs

    Class Demo

    Function login(Sheet_Name)
         address = DataTable("address", Sheet_Name)
         Systemutil.run "C:\Program Files\Internet Explorer\IEXPLORE.EXE"
         wait(3)
         Browser("micclass:=browser").close
         msgbox address
    End Function

    Function logout()
         msgbox "logout"
    End Function

    End Class
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    9#
     楼主| 发表于 2009-4-2 20:41:45 | 只看该作者
    Log.vbs

    Public Function logPrint(ByVal logMessage)
            
            Dim fso, logFile
            Set fso = CreateObject("Scripting.FileSystemObject")
            Set logFile = fso.OpenTextFile(Environment("Log_Dir")&"\runtime.log", 8, True) 'Open a file and write to the end of the file and open as Unicode
            
            logFile.WriteLine(date() & " " & hour(now) & ":" & minute(now) & ":" & second(now) & ": " & logMessage)
       
            logFile.Close
    End Function

    Public Function ErrorHandle()
            If Err.Number <> 0 Then
                    logPrint "Error Num: " & Err.Number & "; Error Src: " & Err.Source & "; Error Desc: " & Err.Description
                    Err.Clear
            End If
    End Function


    Public Function xmlLogPrint(ByVal logMessage)
    Dim fso, xmlfile
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set xmlfile = fso.OpenTextFile(Environment("Log_Dir")&"\runtime.xml", 8, True)
    xmlfile.WriteLine logMessage
    xmlfile.Close
    Set xmlfile = nothing
    Set fso = nothing
    End Function

    Public  Function taskLogPrints (taskname)
    Dim fso, xmlfile, str1, str2, str3
    str1 = "<task>"
    str2 = "<"&"/"&"task>"

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set xmlfile = fso.OpenTextFile(Environment("Log_Dir")&"\runtime.xml", 8, True)
    xmlfile.WriteLine str1&"执行步骤 "&taskname&"成功"&str2
    xmlfile.Close
    Set xmlfile = nothing
    Set fso = Nothing
    End Function


    Public  Function taskLogPrint (taskname)
    Dim fso, xmlfile, str1, str2, str3
    str1 = "<"
    str2 = ">"
    str3 = "/"
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set xmlfile = fso.OpenTextFile(Environment("Log_Dir")&"\runtime.xml", 8, True)
    xmlfile.WriteLine str1&taskname&str2&"执行步骤 "&taskname& Environment("bResult")&str1&str3&taskname&str2
    xmlfile.Close
    Set xmlfile = nothing
    Set fso = Nothing
    End Function

    Public  Function ErrorXmlPrint()
    Dim fso, xmlfile, str1, str2, str3
    strTemp = " 错误描述: " & Err.Description
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set xmlfile = fso.OpenTextFile(Environment("Log_Dir")&"\runtime.xml", 8, True)
    If Err.Number <> 0 then
    xmlfile.WriteLine "<Error>"&strTemp&"</Error>"
    End IF
    xmlfile.Close
    Set xmlfile = nothing
    Set fso = Nothing
    End Function
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8#
     楼主| 发表于 2009-4-2 20:41:12 | 只看该作者
    Function.vbs

    Function PressEnter
      wait(2)
      Set WshShell = CreateObject("WScript.Shell")
      WshShell.SendKeys "~"
      Set WshShell = nothing
    End Function
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    7#
     楼主| 发表于 2009-4-2 20:40:51 | 只看该作者
    DiverUtil.vbs

    '################################'
    '---------------通用方法--------------------------'
    '################################'
    Function pathFind( searchingFolder,searchingFileName,fileType)
    '根据传入的根目录,查找该目录下的指定名称,以及指定文件类型的文件,并返回其绝对路径。
            tempArray = Split(searchingFileName,".")
            fileName = tempArray(0)&"."&fileType
            Set fso=CreateObject( "Scripting.FileSystemObject" )
            Set objFolder = fso.GetFolder( searchingFolder )
            Set objFileCollection = objFolder.Files
            for each objFile in objFileCollection
                    If objFile.Name = fileName Then
                            i=i+1
                            searchedFilePath = objFile.Path
                            Exit for
                    End If
            Next
           
            If i=0 then
                    '遍历子文件夹
                    Set objSubFoldersCollection = objFolder.SubFolders
                    For each objInputSubFolder in objSubFoldersCollection
                            searchedFilePath= pathFind(objInputSubFolder,searchingFileName,fileType)
                            If searchedFilePath<>"" Then
                                    Exit For
                            End if
                    Next
            End If
            pathFind = searchedFilePath
    End Function

    Function getParentFolderPath(curPath)
       '输入一个路径的字符串,获得其上级目录的字符串,主要目的是根据QTP脚本所在文件夹,找到工程所在的文件夹
       tempArray = split(curPath,"\")
       tempStr =""
       For i=LBound(tempArray) to UBound(tempArray)-1
                    tempStr = tempStr&tempArray(i)&"\"
       Next
       getParentFolderPath = tempStr
    End Function


    Function generateFilterExp(Sheet_Name,filterExp)
       ''解析条件语句,只支持 >= ,<= , <>, >, <, = 这6种表达式
       '对表达式作了处理,支持中文的分号,不区分英文的大小写。
            If filterExp<>"" Then
                                    If InStr(filterExp,";")>0 Then
                                            filterExp = Replace(filterExp,";",";")
                                    End If
                                    expressArray = Split(LCase(filterExp),";")
                                    For i=LBound(expressArray) To UBound(expressArray)
                                            If InStr(expressArray(i),">=") Then
                                                    tempArray = Split(expressArray(i),">=")
                                                    If i=LBound(expressArray) Then
                                                            expressStr = "DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&">="&chr(34)&tempArray(1)&chr(34)
                                                    else
                                                            expressStr = expressStr&" and "&"DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&">="&chr(34)&tempArray(1)&chr(34)
                                                    End If
                                            ElseIf InStr(expressArray(i),"<=") Then
                                                    tempArray = Split(expressArray(i),"<=")
                                                    If i=LBound(expressArray) Then
                                                            expressStr =  "DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"<="&chr(34)&tempArray(1)&chr(34)
                                                    else
                                                            expressStr = expressStr&" and "&"DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"<="&chr(34)&tempArray(1)&chr(34)
                                                    End If
                                            ElseIf InStr(expressArray(i),"<>") Then
                                                    tempArray = Split(expressArray(i),"<>")
                                                    If i=LBound(expressArray) Then
                                                            expressStr =  "DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"<>"&chr(34)&tempArray(1)&chr(34)
                                                    else
                                                            expressStr = expressStr&" and "&"DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"<>"&chr(34)&tempArray(1)&chr(34)
                                                    End If
                                            ElseIf InStr(expressArray(i),"<") Then
                                                    tempArray = Split(expressArray(i),"<")
                                                    If i=LBound(expressArray) Then
                                                            expressStr =  "DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"<"&chr(34)&tempArray(1)&chr(34)
                                                    else
                                                            expressStr = expressStr&" and "&"DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"<"&chr(34)&tempArray(1)&chr(34)
                                                    End If
                                            ElseIf InStr(expressArray(i),">") Then
                                                    tempArray = Split(expressArray(i),">")
                                                    If i=LBound(expressArray) Then
                                                            expressStr =  "DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&">"&chr(34)&tempArray(1)&chr(34)
                                                    else
                                                            expressStr = expressStr&" and "&"DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&">"&chr(34)&tempArray(1)&chr(34)
                                                    End If
                                            ElseIf InStr(expressArray(i),"=") Then
                                                    tempArray = Split(expressArray(i),"=")
                                                    If i=LBound(expressArray) Then
                                                            expressStr =  "DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"="&chr(34)&tempArray(1)&chr(34)
                                                    else
                                                            expressStr = expressStr&" and "&"DataTable("&Chr(34)&tempArray(0)&Chr(34)&","&Chr(34)&Sheet_Name&Chr(34)&")"&"="&chr(34)&tempArray(1)&chr(34)
                                                    End If
                                            Else
                                                    MsgBox("不支持此表达式")
                                            End If
                                    Next
                            Else
                                    expressStr = "DataTable( 1 "&","&Chr(34)&Sheet_Name&Chr(34)&")"&"<>"&chr(34)&chr(34)
                            End If
                            'logPrint("在generateFilterExp方法中,条件语句解析结果:"&expressStr)
                            generateFilterExp = expressStr
    End Function
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    6#
     楼主| 发表于 2009-4-2 20:39:55 | 只看该作者
    Private Function ExecuteTask(taskDataSheetName, TaskDataFilePath)
                        DataTable.AddSheet(taskDataSheetName)
                                             On Error Resume Next
                                         DataTable.ImportSheet TaskDataFilePath,taskDataSheetName,taskDataSheetName
                                             If  Err.number = 0 Then
                                                test_data_row_count = DataTable.GetSheet(taskDataSheetName).GetRowCount
                                            '   msgbox  test_data_row_count
                                                For j=1 To test_data_row_count
                                                    DataTable.GetSheet(taskDataSheetName).SetCurrentRow( j )
                                                            'msgbox taskDataSheetName
                                                        'msgbox taskFilter
                                                        If Eval(generateFilterExp(taskDataSheetName,taskFilter)) Then
                                                                  'Eval(generateFilterExp(Sheet_Name,filterExp)) ,解析测试数据的条件语句,符合此条件的,则执行该行测试数据,否则不执行
                                        str = "obj"&classoftesttask&"."&testtaskName&" "&chr(34)&taskDataSheetName&chr(34)
                                        Execute str
                                                                            ErrorXmlPrint   '如果有错误则输出。
                                                                            If  not err.number = 0 Then
                                             Environment("bResult") = "失败"
                                                                            End If
                                                                       Err.Clear
                                    End If
                            Next  
                                                    sheetName =taskDataSheetName
                                        DataTable.DeleteSheet  sheetName
                                            else
                                                   Msgbox "检查"&TaskDataFilePath&"中是否有表"&taskDataSheetName
                                             End if
                                On Error Goto 0
    End Function
            
    Public Function StartTestTask(TestTaskArray)
                  InitTestTask TestTaskArray
                              Environment("bResult") = "成功"  '默认开始执行每一个的步骤为成功
                  If Not TestScriptObject.Exists (classoftesttask)  then
                                           taskFilePath = pathFind(Environment("testScriptFolderName"),classoftesttask,"vbs")
                                                On Error Resume Next
                                        ExecuteFile taskFilePath   'executefile  qtp独有的加载外部的vbs 文件.
                                                    If Err.Number = 0Then
                                                            TestScriptObject.add classoftesttask,taskFilePath
                                 Execute "Set obj"&classoftesttask&" = new "&classoftesttask
                                                             If  not Err.Number = 0 Then
                                       msgbox "查看"&taskFilePath&"中是否有"& classoftesttask&"类"
                                                                       Err.Clear
                                                             End If
                                Else
                                                        msgbox "请查看"&taskFilePath&"是否存在或者taskFilePath中有错误!"
                           End If   
                                             On Error Goto 0
                   End If
                     
                          '开始执行task
                       If Not tableOfTask="" Then
                         tempArray = split(tableOfTask,".")
                     If UBound(tempArray)=0 Then
                                         TaskDataFilePath = pathFind(Environment("testDataFolderName"), Environment("TestSetsTable"),"xls")
                                                     ExecuteTask tempArray(0), TaskDataFilePath
                                      else
                                      '如果是引用的外部Excel的sheet,那么。。。
                                      TaskDataFilePath = pathFind(Environment("testDataFolderName"),tempArray(0),"xls")
                                      
                        ExecuteTask tempArray(1), TaskDataFilePath

                                  End If
                                 
                        Else
                                        '如果Sheet名称为空则不加载
                                 str = "Call obj"&classoftesttask&"."&testtaskName&"()"
                                    On error resume Next
                                     Execute str
                                     ErrorXmlPrint
                                     If  not err.number = 0 Then
                        Environment("bResult") = "失败"
                                     End If
                                    On error Goto 0
                        End If
                            '计算成功和失败的用例数
                            If   Environment("bResult") = "成功" Then
                       Environment("numSuccess") =  Environment("numSuccess") +1
                         else
                                Environment("numErrors") =  Environment("numErrors")+1
                            End If
                           
    End Function
                           

    Private classoftesttask
    Private  testtaskName
    Private tableOfTask
    Private taskFilter

    End Class

      '******************************************TestTask类******************************************************

    '*******************************************以上类的声明和全局变量 的定义************************************************************************
      
    Set objtestProject = New TestProject                                               '构造一个自动化测试项目
    objtestProject.StartTestProject  "testSets.xls"
    Set objtestProject = nothing
    Set TestScriptObject = nothing
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    5#
     楼主| 发表于 2009-4-2 20:39:36 | 只看该作者
    Public  Function StartTestCase(TestCaseArray)
         
                  InitTestCase TestCaseArray
                  For i = 0 To testTasks.Count-1
                      Set objTestTask = new TestTask
                      TestTaskArrays = testTasks.Items
                      TestTaskArray = TestTaskArrays(i)
                     objTestTask.StartTestTask(TestTaskArray)
                                     taskLogPrint TestTaskArray(1)
                                     Set objTestTask = nothing
                  Next
                  
         End Function
         
    Private  Function InitTestCase(TestCaseArray)
                 testcaseName = TestCaseArray(0)
                 casestartRow = TestCaseArray(1)
                 caseendRow   = TestCaseArray(2)
                 Set testTasks = CreateObject("Scripting.Dictionary")
                 'task所在的数据表已经导入,TestCases表
                 MyTestTasks = "TestCases"
                 Dim j
                 j = 0
                             Dim taskArray(4)
                              On Error Resume Next
                 For i = casestartRow To caseendRow
                    DataTable.GetSheet(MyTestTasks).SetCurrentRow(i)
                    isRun = DataTable.Value("IDX", MyTestTasks)
                       If isRun = "√" Then
                        classoftesttask = DataTable.Value("bizName", MyTestTasks)
                        testtaskName = DataTable.Value("taskName", MyTestTasks)
                        tableOfTask = DataTable.Value("bizDataTable", MyTestTasks)
                        taskFilter = DataTable.Value("filter", MyTestTasks)
                        taskArray(0) = classoftesttask
                        taskArray(1) = testtaskName
                        taskArray(2) = tableOfTask
                        taskArray(3) = taskFilter
                                            If   Err.Number = 0 Then
                        testTasks.Add j, taskArray
                        j = j+1
                                            else
                                                 msgbox   "请检查"&MyTestCases&"表中IDX, bizName, description, filter,taskName各字段有没有错!"
                       End If
                                   Err.Clear
                                    End If             
                 Next
                              On Error Goto 0

    End Function


    Private   testcaseName
    Private   casestartRow
    Private   caseendRow
    Private   testTasks

    End Class

      '******************************************TestCase类,这个类中很多个Tasks******************************************************

      '******************************************TestTask类******************************************************
    Class TestTask
    Private Function InitTestTask(TestTaskArray)
                  classoftesttask = TestTaskArray(0)
                  testtaskName = TestTaskArray(1)
                             ' msgbox testtaskName
                  tableOfTask  = TestTaskArray(2)
                              'msgbox tableOfTask
                   taskFilter  = TestTaskArray(3)
                               ' msgbox taskFilter
    End Function
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-13 19:47 , Processed in 0.075376 second(s), 27 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表