RSS
 

Archive for July, 2010

#17: Reformat data in Excel (sheet A to Array x to Array y to sheet B)

25 Jul



This post is an example for you to practice post#9 and post#16. The 2 images on the right hand side are illustrations to show what I am tyring to do in this post:

In the excel file “MeasurementTab”, I created 2 sheets, one is called “Raw” and the other is called “ModeCategoryUnit”. I copied all the protocol tables from our Software Specifications, and paste them one by one to the “Raw” sheet. There are less than 50 Protocols, so it is okay to copy them manually. However, each Protocol table contains 2 to 20 measurements, so there are about 500 measurements in-total, and I want to rearrange all these measurements in another format/order and save them in the “ModeCategoryUnit” sheet, which will take days if I do it manually.

I decide to automate the data process. I will export the data from “Raw” sheet to an array called Raw(). By using the array Raw() and another small array ModeArray(1 To 9), I will rearrange the data in a new order, and save the data to an array called ModeCategoryUnit(). Finally, data in array ModeCategoryUnit() will be exported to sheet “ModeCategoryUnit” in the Excel file.

'Convert "Raw" sheet (populated directed from software specification - word version) to "ModeCategoryUnit" sheet in "Measurement.xlsx"
'If handle all the Packages/Protocols/Measurments, then need to increase ModeCategoryUnit's size and size parameters in Function_SaveArrayAsExcelSheet

'$TPinclude "Declaration_GlobalConstants"

Sub Main()

'Store Data from the "Raw" Sheet to array Raw()
Dim RowCount As Integer
Dim ColumnCount As Integer
Dim Raw() As String

RowCount = Function_ExcelSheetRowCount.ExcelSheetRowCount(ExcelFilePath_Measurement, "Raw")
ColumnCount = Function_ExcelSheetColumnCount.ExcelSheetColumnCount(ExcelFilePath_Measurement, "Raw")

ReDim Raw(1 To RowCount, 1 To ColumnCount) As String
Raw() = Function_GetExcelSheetData.GetExcelSheetData(ExcelFilePath_Measurement, "Raw")

'Delete extra space (if any) for each cell of array Raw()
Dim TrimRaw() As String
ReDim TrimRaw(1 To RowCount, 1 To ColumnCount) As String
Dim i As Integer    'row number of array Raw()
Dim j As Integer    'column number of array Raw()

For j = 1 To ColumnCount
    For i = 1 To RowCount
    TrimRaw(i, j) = Trim(Raw(i, j))
    Next
Next

'Convert data from array TrimRaw() to array ModeCategoryUnit()
Dim ModeCategoryUnit(1 To 15, 1 To 60) As String    'Size should be increased if handle all the Packages/Protocols/Measurments

'First, write the header section (top 3 rows) of array ModeCategoryUnit()
'Including Package (1st row), Protocol (2nd row) and Mode (3rd row)
Dim Package As String
Dim Protocol As String
Dim ModeArray(1 To 9) As String
Dim ModeList As String
Dim Counter As Integer
Dim Column As Integer

Column = 1
For j = 1 To ColumnCount
    If TrimRaw(1, j) <> "" Then
        Package = TrimRaw(1, j)
        If TrimRaw(2, j) <> "" Then
            Protocol = TrimRaw(2, j)
            'Reset Counter, Clearn ModeList and ModeArray for the FOR loop
            Counter = 1
            ModeList = ""
            Erase ModeArray
            For i = 3 To RowCount
                If TrimRaw(i, j + 3) <> "" Then
                    'If TrimRaw(i, j + 3) doesn't exist in ModeList
                    If InStr(ModeList, TrimRaw(i, j + 3)) = 0 Then
                        ModeArray(Counter) = TrimRaw(i, j + 3)
                        'ModeList looks like "ModeArray(Counter),ModeArray(Counter+1),,,,,,,,"
                        ModeList = Join(ModeArray, ", ")
                        Counter = Counter + 1
                    End If
                Else: Exit For
                End If
            Next
            'Reset Counter for the DO loop
            Counter = 1
            Do While Counter <= UBound(ModeArray) And ModeArray(Counter) <> ""
                ModeCategoryUnit(1, Column) = Package
                ModeCategoryUnit(2, Column) = Protocol
                ModeCategoryUnit(3, Column) = ModeArray(Counter)
                Counter = Counter + 1
                Column = Column + 3
            Loop
        End If
    End If
Next

'Second, write the rest section of array ModeCategoryUnit()
'including Measurement, and its Category and Unit (same row)
Dim Measurement As String
Dim Category As String
Dim Unit As String
Dim Mode As String
Dim k As Integer    'row number of array ModeCategoryUnit()
Dim l As Integer    'column number of array ModeCategoryUnit()

For j = 1 To ColumnCount
    If TrimRaw(1, j) <> "" Then
        Package = TrimRaw(1, j)
        If TrimRaw(2, j) <> "" Then
            Protocol = TrimRaw(2, j)
            For i = 3 To RowCount
                If TrimRaw(i, j) <> "" Then
                    Measurement = TrimRaw(i, j)
                    Unit = TrimRaw(i, j + 1)
                    Catergory = TrimRaw(i, j + 2)
                    Mode = TrimRaw(i, j + 3)
                    'Search all the columns of array ModeCategoryUnit()
                    For l = LBound(ModeCategoryUnit, 2) To UBound(ModeCategoryUnit, 2)
                        If ModeCategoryUnit(1, l) = Package And ModeCategoryUnit(2, l) = Protocol And ModeCategoryUnit(3, l) = Mode Then
                            For k = 4 To UBound(ModeCategoryUnit)
                                If ModeCategoryUnit(k, l) = "" Then
                                    ModeCategoryUnit(k, l) = Measurement
                                    ModeCategoryUnit(k, l + 1) = Catergory
                                    ModeCategoryUnit(k, l + 2) = Unit
                                    Exit For
                                End If
                            Next
                            Exit For
                        End If
                    Next
                Else
                    If TrimRaw(i, j + 3) <> "" Then
                        Mode = TrimRaw(i, j + 3)
                        For l = LBound(ModeCategoryUnit, 2) To UBound(ModeCategoryUnit, 2)
                            If ModeCategoryUnit(1, l) = Package And ModeCategoryUnit(2, l) = Protocol And ModeCategoryUnit(3, l) = Mode Then
                                For k = 4 To UBound(ModeCategoryUnit)
                                    If ModeCategoryUnit(k, l) = "" Then
                                        ModeCategoryUnit(k, l) = Measurement
                                        ModeCategoryUnit(k, l + 1) = Catergory
                                        ModeCategoryUnit(k, l + 2) = Unit
                                        Exit For
                                    End If
                                Next
                                Exit For
                            End If
                        Next
                    Else: Exit For
                    End If
                End If
            Next
        End If
    End If
Next

'Use shared module "Function_SaveArrayAsExcelSheet" to write data from array to Excel
a = Function_SaveArrayAsExcelSheet.SaveArrayAsExcelSheet(ModeCategoryUnit, 15, 60, ExcelFilePath_Measurement, "ModeCategoryUnit")

'Erase arrays
Erase ModeCategoryUnit
Erase TrimRaw
Erase Raw

End Sub

From the above script, we practiced the following:
1, Use a module “”Declaration_GlobalConstants”" to define a globe constants “ExcelFilePath_MeasurementTab”. (for more details see post#10)
2, Call Function_GetExcelSheetData to transfer data from the “Raw” sheet to array Raw(). (for more details see post#9)
3, Use Trim function to remove spaces on both sides of a string.
4, Join array elements to a string (ModeList = Join(ModeArray, “, “))
5, Call Function_SaveArrayAsExcelSheet to transfer data from array ModeCategoryUnit() to “ModeCategoryUnit” sheet. (for more details see post#16)
6, Erase array (e.g., Erase Raw)

There are an potential improvement for the above script. Currently, I hard coded the size of array “ModeCategoryUnit”, so when there are more measurements added, then I need to change the size in the script. However, there is a solution: “Adding New Elements to array on the Fly” . I didn’t do this because that the logic of the script is already complected, and I do not want to confuse you, but you can try this out by yourself!

 
1 Comment

Posted by Jia Qi in TestPartner (TP)

 

#16: Export data from Two-Dimensional Array (2D array) to an Excel Sheet

25 Jul

In Post#9, we talked about how to import data from Excel (with multiple sheets) to an Array.

In this post, we will discuss that how to export data from a Two-Dimensional Array (2D array) to an Excel sheet.

Function SaveArrayAsExcelSheet(ArrayData() As String, ArrayRowCount As Integer, ArrayColumnCount As Integer, ExcelFilePath As String, SheetName As String)

'On error jump to "Error Handler:" line
On Error GoTo ErrorHandler

'Variable declaration
Dim SheetCount As Integer

'Open the Excel file
Set ObjExcel = CreateObject("Excel.Application")
Set ObjWorkBook = ObjExcel.Workbooks.Open(ExcelFilePath)

'Count how many sheets in the Excel file
SheetCount = ObjWorkBook.WorkSheets.Count

'If the sheet named "SheetName" exists, delete it
For i = 1 To SheetCount
    If ObjWorkBook.WorkSheets(i).Name = SheetName Then
        ObjExcel.DisplayAlerts = False  'Disable the delete confirmation message
        ObjWorkBook.WorkSheets(i).Delete
        ObjExcel.DisplayAlerts = True   'Enable the delte confirmation message
        Exit For
    End If
Next

'Create a new sheet in the Excel file and name this sheet as "SheetName"
ObjWorkBook.WorkSheets.Add.Name = SheetName

'Transfer data from an array to a Excel sheet
Dim ObjRange As Excel.Range
For i = 1 To SheetCount
    If ObjWorkBook.WorkSheets(i).Name = SheetName Then
        Set ObjRange = ObjWorkBook.WorkSheets(i).Range(ObjWorkBook.WorkSheets(i).Cells(1, 1), ObjWorkBook.WorkSheets(i).Cells(ArrayRowCount, ArrayColumnCount))
        ObjRange.Value = ArrayData()
    End If
Next

'Save and Close the Excel file
ObjWorkBook.Save
ObjWorkBook.Close

Exit Function

ErrorHandler: ' This is a normal VBA line label
    MsgBox Err.Description
    ObjWorkBook.Close

End Function

The VBA script above solves the problem (it will add or overwrite a sheet in the Excel file to receive data). The script should be saved as an shared module in TestPartner. To make the script work, you need to go to Tools->Reference to check the reference for Microsoft Excel, otherwise, TestPartner will give you an error on line “Dim ObjRange As Excel.Range”. (see Chapter 8 page 96 of “TestPartner Advanced Training Guide.pdf for Test Partner 5.2” listed in post#8 for more details.)

If you want to apply the script in QTP which uses VBScript instead of VBA, you need to make some minor modifications:

A, The function script needs to be created in the QTP Function Library (File – New – Function Library);

B, In the function script, delete anything related to the ErrorHandler (2 paragraphs);

C, In the function script, delete any definition for variable type, e.g., modify “SheetName As String” to “SheetName”, and change “Dim SheetCount As Integer” to “Dim SheetCount”.

D, Create a Test/Action to execute the function script, and the test/action will look like this (compare to TestPartner test script, no “Sub” nor “End Sub”, no need to assign the function to a variable, and no function file name nor brackets, i.e.,
in Testpartner (In TestPartner, if the function does not have a return value, but it has more than 1 input values, then in order to execute the function, you still need to define a variable in your test script, and assign the function to the variable.):

Sub Main()
a = Function_SaveArrayAsExcelSheet.SaveArrayAsExcelSheet(ArrayName, 15, 60, "C:\...\MeasurementTab.xlsx", "Sheet2")
End Sub

in QTP:

SaveArrayAsExcelSheet ArrayName, 15, 60, "C:\...\MeasurementTab.xlsx", "Sheet2")

E, Associate the Function file with the Test/Action file (right click on the Function file script and choose “Associate…” on the pop up menu), then you can run the function by running the test/action.

The script above should be fast enough to handle 10,000 data, but if your data is more than 50,000, then you may experience some slowness (depends on your computer speed too). There are two ways to solve the speed problem:
1, export the data from array to csv, then convert csv to Excel.
2, use ExcelCreator.NET instead of Excel Object, which is more efficient.
For more details, please refer to this website (you need to understand Chinese) .

 

#15: Automated Testing for Real-Time Embedded Medical Systems

20 Jul

As you know, I am working in an ultrasound company. Our testing can be divided into 2 parts: system testing and workstation testing.

The workstation is pure software, and you have seen some automation testing examples in the previous posts, such as post#10, post#12 and post#14.

The system testing is very different and done manually. Our ultrasound system contains an computer, a monitor, a custom designed keyboard, and a card cage. Inside the card cage, there are hardware – multiple electronic boards. FPGA is on one of the board, which does all the calculation. Also, the system will be connected to a transducer, which send and receive ultrasound signals.

What I am trying to say here is, the ultrasound system has its own hardware, and it is a Real-Time system.

I always think automation testing (such as using QTP, RFT, and TestPartner) is designed for software testing only, and it is not appropriate to automate system testing involves hardware. However, one of my colleague think if we can develop portable scripts (i.e., not based on any automation testing tools such as QTP, RFT and TestPartner), then we can automate system testings.

I think it is a great idea to use portable scripts to test software, in this way, you do not need to pay thousands of dollars to buy the automation testing tools. I already mentioned similar idea before in post#9.
Quote from myself:
“From this post, you may have a better understanding of QTP and TestPartner… Beside the object identifier, all the other features that you need for automation testing actually can be achieved by writing VB scripts in notepad, and save them as .vbs files…”
Even though this is a good idea for software testing, but I doubt that this idea will work for system testing involves hardware, don’t even mention it is also a Real-time system.

I could be wrong, since I didn’t have experience on this, but my colleague could be wrong too, since he is a developer who didn’t have experience on automation testing for hardware systems neither. The good thing is he sold his idea to my boss (VP QA) in the men’s room, which allows us to get a chance to see how the thing will go and learn from the process.

We will have a group meeting to discuss this topic soon, and before that I did some research on this. The results show there are 2 ways to automate system testing involves hardware:

1, invent an Automated Test Systems (ATS), which is a separate system. Quote from a company called ATS TEST SYSTEMS at Woodbridge, Ontario: “ATS Test Systems provides turnkey solutions in the design, manufacture and support of test and information systems for large-scale repetitive manufacturing.” Since it is a separate system, it not only includes software, it will have its own hardware, etc. For the software side, I guess scripting won’t do the job, coding languages such as C++, C# are needed.

2, embed testing scripts into the system software, and start from here to see what we can do. Refer to the article below (found in China Medical Device Manufacturer), which was written by an outsourcing company named as Foliage which specialized in this area:

Automated Testing for Real-Time Embedded Medical Systems
By: Amit Shah and Tim Bosch

Automated testing can help device companies gain a competitive advantage in the industry by reducing time to market, and increase the quality level of an embedded real-time medical device product.

Medical device companies, especially those with real-time embedded-system products, are often burdened with lengthy verification cycles. Even small development efforts can result in months of verification. There are numerous reasons for such extended verification efforts, but chief among these are

* Complexity due to permutations of input or system configuration.
* Complexity due to the system environment or system setup required for testing.
* The number of external system possibilities for connectivity and interoperability.
* A reliance on manual execution of tests for all aspects of verification (e.g., functional testing and system behavior testing).
* A lack of support for test automation in the product itself (e.g., the absence of hooks or callable application programming interfaces (APIs) necessary for the scripts or code that drive automation).

Manual testing is time-consuming and error prone, with functional and system testing that starts late in the software development cycle. Relying on manual testing alone can increase the risk of late defect discovery and often leads to delays in product release. A lack of test automation can also cause delays in manufacturing and support.

Although there are proven automated test tools and techniques for unit and integration testing, most medical device companies have yet to embrace an overall automated testing strategy for embedded real-time devices. These firms must understand the challenges of testing embedded real-time medical systems and examine strategies to improve quality and reduce verification cycle time and costs.

Embedded systems come in many variations, but in general they share the following characteristics:

* Special-purpose control logic, designed to support a few dedicated functions.
* Part of a complete device including electrical and mechanical parts.
* Varying complexity, from a single microcontroller to multiple processors, units, and peripherals.
* An optional user interface and connectivity with external systems.

These characteristics differ from a general-purpose computing platform, like a desktop or enterprise system, which can perform multiple functions depending only on programming. However, many test automation approaches for general computing can be applied to real-time embedded systems. These approaches include determining which testing to automate, demonstrating a return on investment (ROI) to gain management buy-in, formulating the automation strategy, and identifying test tools needed. The approaches also include constructing the test framework and addressing regulatory requirements.

Embedded systems do present some unique testing challenges, such as parallel development of hardware and user-interface availability restrictions. Parallel development of hardware requires the use of emulators and simulators until later-stage system testing, once the actual hardware becomes available. For those systems with a user interface, it is also often developed in parallel, rendering it available only for later-stage system testing.

Because of such challenges, test hooks need to be built into the software to support testability as identified in an overall test automation strategy. This embedded test code simulates actions normally begun through a user interface or other command-control trigger (pressing a button on the device, confirming an action, selecting a value, etc.). A test case can be constructed by invoking a sequence of these actions via the callable test hooks. Furthermore, if target hardware is absent, these test cases can be executed by using a suite of emulators and simulators as part of the automated test environment. This approach enables testing software early in the development cycle, in advance of both user interface and hardware dependencies.

Benefits of Automated Testing

Automated testing can reduce the amount of manual testing, shorten the process schedule, and reduce cost. Testing is often viewed as a bottleneck in the software and system development process. By automating testing, a test team can help ensure that the software development, as well as the overall development, meets its schedule and budget goals.

Automated testing can increase efficiency in the software development process. Because automated tests consistently repeat and document a specific sequence of steps, the development team can reproduce defects found by an automated test case. This leads to quicker defect resolution early in the software development cycle. Furthermore, automated tests can be executed before source code check-in, which prevents defects from making it into the code base.

Test coverage is also increased. Comprehensive automated tests can be executed, unattended, 24 hours a day. This allows the test team to focus on safety-critical or complex parts of the product.

Automated testing can improve consistency and repeatability of testing over manual testing. Manual testing can be time-consuming and monotonous, resulting in mistakes by even the most conscientious testers. Automated tests repeat the same sequence of steps and record results with each execution, thereby ensuring overall accuracy of regression, integration, and system testing.

The process also facilitates performance and stress testing, which can be difficult or impractical to perform manually.

Early-stage test automation helps isolate problems encountered in the software, because hardware is often unavailable in early-development-stage testing. The early identification of software problems can ease integration with hardware. In addition, the embedded test code can also be used to support manufacturing and field-service system test needs.

Limitations of Automated Testing

If the automated test results are to be used for formal verification and validation evidence, the automated tests need to be executed on the actual target hardware against the software that is a candidate for final release. The additional code may increase the complexity of the code base and become a burden for development and maintenance. Also, because it will be included in the software released as part of the embedded real-time system, the test code needs to be validated to ensure that it has no undesired side effects on the intended use of the product.

Another drawback is that emulators and simulators, used as part of the automated test environment, may not accurately represent the behavior of the actual device and can give a false sense of application usability and system performance. In such cases, the emulators and simulators should be evaluated for accuracy relative to the actual device.

Embedded software development is complex. Changes to software interfaces and hardware are common, which makes testing especially challenging. Modular and extensible automated test environments can significantly reduce the influence of these changes. However, such a development effort requires careful design and continual maintenance.

Medical device OEMs often use independent test teams to develop and execute manual tests. Automated testing requires specialized programming skills that often require additional training. Depending on the automated test framework, the test team can use a programming language such as Perl to design and develop test cases.

Strategies for Effective Automated Testing

To articulate the strategies for effective test automation, this article uses a patient monitor as an example of a real-time embedded medical device. A patient monitor is a portable device used for standard physiological parameters such as ECG, heart rate, SpO2, NIBP, and temperature. The monitor is applied outside the body. It automatically analyzes the patient’s waveforms and warns clinicians if a parameter is out of range via a visual or audible alarm.

First, designers need to decide what to automate. They must consider the performance implications on the system. A monitor displays waveforms on an LCD. Embedded test code that supports the verification of the integrity of this real-time signal may artificially add to the schedulability and resource load of the system. In this case, the designer would likely decide not to automate the testing of this functionality. Instead, it would be better to focus on automating functionality for which the embedded test code would have no effect on device performance, such as device configuration.
Figure 1. (click to enlarge)
The test automation environment. Application programming interfaces (APIs) define the set of actions to construct the test case.

The next step is to design the test automation environment. The environment consists of APIs, a framework used to invoke the APIs and execute a defined set of actions to construct the test case, and, potentially, emulators and simulators (see Figure 1). Working with the development team, APIs are added to the code to simulate user actions such as button presses on the device. These APIs create a layer between the user interface and the control logic code, effectively creating an alternate externally callable interface that can be invoked by the framework. In addition to adding the callable interface, the APIs add logging capabilities that record input values and results, capture start and stop times, and log other data that may be needed.

The framework, in this case, consists of a set of scripts used to call the APIs and execute the sequence of actions defined in the test cases. These test cases will have been defined by test engineers and were previously executed manually. Once established, the test automation environment can be integrated with a build system to provide regular verification of implemented functionality. The integration facilitates regression testing and continuous feedback during the software development cycle.

Unlike test automation tools for general computing platforms, there are few tools available for system-level and functional testing of embedded real-time systems because these tools often need to be compatible with the technology (i.e., RTOS) for the application under test. Therefore, there is usually a need to create custom automated tools. The cost of development, testing, and qualification of these tools is part of the investment in test automation.

There are some third-party products that can be used as part of a test environment or within an overall test strategy, such as QualiSystems TestShell and National Instruments LabVIEW, among others. Designers still need to develop test scripts, though, and the license cost for such tools should be factored into any investment considerations. Remember that it is likely that these tools still need to be qualified to comply with regulatory guidelines.

Return on Investment

Automation requires an investment with a justifiable, and potentially significant, payback. In the patient monitor example, the costs may include the following:

* Purchasing or development of automated test tools.
* Training staff on automated test tools and scripting.
* Qualifying automated test tools, simulators, and emulators for their intended use, as required by FDA.
* Developing modular test frameworks to support automated test case creation, execution, and results reporting.
* Building and maintaining testability in the application (i.e., embedded test code).
* Developing, debugging, peer reviewing, and maintaining automated test cases.

The savings are determined by the amount of manual test execution time saved in functional, regression, and system testing. The savings also come from early discovery of defects through unattended and repeated execution of automated test cases. Industry data suggest that the cost of finding and fixing a defect during the system-testing phase is seven times the cost of finding and fixing a defect during the coding phase.1 For subsequent releases of the product, there can be additional savings in early stages of development if standardized tests are made part of the development effort.

The initial investment is usually recouped by the second release, after which savings are seen for subsequent releases. Upfront ROI analysis is essential to get management support.

Complying With Regulatory Guidelines

FDA’s General Principles of Software Validation: Final Guidance for Industry and FDA Staff, provides guidance for medical device manufacturers related to software verification and validation.2

Automated Test Tool Validation. Section 6.3 (Validation of Off-the-Shelf Software and Automated Equipment) of the guidance recommends that medical device manufacturers are responsible for validation of off-the-shelf software for its intended use. This requirement applies to any software used to automate device testing. Automated test tools purchased from third-party vendors are used to generate automated test cases and test results that may be used for formal verification evidence for the product. In this case, these tools need to function as expected and should be validated for their intended use. Artifacts that should be reviewed, approved, and collected as a record of validation include requirements documentation, qualification procedures, and qualification results for automated test tools.

Note that third-party vendors may be able to supply automated test tool qualification documentation if they have qualified the tool. In this case, the medical device manufacturer may be able to use this qualification documentation to satisfy FDA’s validation requirement for off-the-shelf software.

Software Verification and Validation Plan. Section 5.2.1 (Quality Planning) of the guidance suggests that verification and validation activities should be planned and documented. The automated test strategy and related activities must be documented, reviewed and approved as part of the overall software verification and validation plan for the product.

Automated Test Cases and Test Results. Section 5.2.5 (Testing by the Software Developer) of the guidance says “test procedures, test data, and test results should be documented in a manner permitting objective pass-fail decisions to be reached.” The creation of automated test cases using a scripting language is a development effort and, therefore, requires processes and standards similar to the development of application code. Automated test code must be source-controlled, appropriately commented, peer-reviewed (for both quality and adherence to predefined coding standards) and approved. Test results generated by automated test cases as a result of executing automated test cases must be reviewed and approved if they are to be used as formal verification evidence for the product.

Conclusion

Automated software testing is not right for everyone. It requires upfront investment and proper due diligence to ensure that it is right for the organization. Otherwise, adopting automation can be expensive and frustrating. Once the benefits of automation are understood, it is important to establish expectations and present management with sufficient data to support a program so that they may plan accordingly.

Implementing an automated software-testing program requires a structured approach. It requires a test strategy specifically tailored to a product and its regulatory requirements. It also requires that designers build or select the right automated test tools and that the environment use automated test frameworks and appropriate emulators and simulators.

By following the approach presented here, device firms can realize a significant ROI for automated software testing, gain a competitive advantage in the industry by reducing time to market, and increase the quality level of an embedded real-time medical device product.

Amit Shah is test engineering manager for Foliage, and he can be reached at ashah@foliage.com. Tim Bosch is chief architect in the medical division of Foliage. He is available at tbosch@foliage.com.

References

1. Case Study: Finding Defect Earlier Yields Enormous Savings, [online] (Dulles, VA: Cigital [cited 8 July 2008]); available from Internet: www.cigital.com/solutions/roi-cs2.php.

2. “General Principles of Software Validation; Final Guidance for Industry and FDA Staff,” (Rockville MD: FDA) January 11, 2002.

 

#14: Test checkboxes for all the measurements from different protocols and packages

11 Jul

In post#10, we have tested the Checkboxes for packages, and in post#12, Checkboxes for protocols are tested. As I said before, there are 3 layers to organize the workstation measurements. The first layer is the package, and the second layer is the protocol. Today, we will use TestPartner test the Checkboxes for the third layer, i.e., the measurement.

From the script below, you can practice the following things again, which you have learned from previous posts:
1, Post#9: Get data from Excel
2, Post#11: Test Windows TreeView with Checkbox
3, Post#13: Error handling in VBA

For number 3, you will also see an improvement compare to the script in post #12: A better place to put the “On Error GoTo 0″ to capture all the errors except the scroll-bar error.

'Testing condition: After clean install.
'Check all the measurements from all the measurement packages - protocols are enabled in the Preference panel - Measurement tab

'$TPinclude "Declaration_GlobalConstants"

Sub Main()

Dim RowCount As Integer
Dim ColumnCount As Integer
Dim SheetData() As String 'Dynamic array

'Use Shared Modules "Function_ExcelSheetRowCount" and "Function_ExcelSheetColumnCount"
'to get how many rows and columns in the Measurement sheet of "MeasurementTab.xlsx"
RowCount = Function_ExcelSheetRowCount.ExcelSheetRowCount(ExcelFilePath_MeasurementTab, "Measurement")
ColumnCount = Function_ExcelSheetColumnCount.ExcelSheetColumnCount(ExcelFilePath_MeasurementTab, "Measurement")

'Array is sized dynamically
ReDim SheetData(RowCount, ColumnCount) As String

'Use Shared Module "Function_GetExcelSheetData" to store data from the Measurement sheet of "MeasurementTab.xlsx" in the array
SheetData() = Function_GetExcelSheetData.GetExcelSheetData(ExcelFilePath_MeasurementTab, "Measurement")

'Open the workstation
    ProgramManagerWindow("Application=EXPLORER.EXE Caption='Program Manager'").Attach
        ListView("Index=1").Select "the workstation", tpMouseDoubleClick

'In the workstation, open Preference panel, then open the Measurement tab
    Window("Application=VSIAPP.EXE Caption=the workstation").Attach
        Button("Caption=Prefs").Click
        TabControl("Parent.Caption=Preferences").Select "    Measurement    "

        'Select different Packages from the ComboBox, expand Protocol nodes, and check their measurements are enabled
        For i = 1 To ColumnCount
            For j = 1 To RowCount
                If j = 1 Then   'First row in the Measurement sheet is package name
                    ComboBox("Parent.Caption=Preferences").Select SheetData(1, i)   'Select the package
                    Dim Package As String
                    Package = SheetData(1, i)
                ElseIf j = 2 Then    'Second row in the Measurement sheet is protocol name
                    Dim ProtocolPath As String
                    ProtocolPath = "\Measurements\" & SheetData(j, i)
                    'Report error if the protocol name read from Excel sheet
                    'does NOT match the protocol name displayed in the workstation
                    On Error GoTo 0    'Disables error handling in the current procedure
                    TreeView("Parent.Caption=Preferences").SelectItem ProtocolPath, , tpTreeButton  'Expand Protocol nodes
                Else
                    'If the Excel cell is not empty, check all the CheckBoxes beside measurement nodes
                    If SheetData(j, i) <> "" Then
                    Dim MeasurementPath As String
                    MeasurementPath = ProtocolPath & "\" & SheetData(j, i)
                        'Report error if the measurement name read from Excel sheet
                        'does NOT match the measurement name displayed in the workstation
                        'On Error GoTo 0    'Disables error handling in the current procedure
                        TreeView("Parent.Caption=Preferences").SelectItem (MeasurementPath)

                        'Store the mouse y position after "SelectItem", which is always
                        'in the middle of the first charactor of the measurement name
                        Dim y As Integer
                        y = TreeView("Parent.Caption=Preferences").MouseY

                        'Handle the situation when the measurement name is longer than the width of the treeview window
                        On Error Resume Next    'Handle the situation when there is no scroll bar
                        TreeView("Parent.Caption=Preferences").Scroll 0, tpScrollHorizontal
                        On Error GoTo 0        'This is a better place

                        'Search if the CheckBoxInTreeView.bmp (13*13 pixels) exists or not
                        'Write the results to result summary.
                        If TreeView("Parent.Caption=Preferences").BitmapExists("CheckBoxInTreeView", 58, y - 8, 17, 17) Then
                            UserCheck "CheckBoxInTreeView", True, "The " & Package & MeasurementPath & " CheckBox is checked"
                        Else
                            UserCheck "CheckBoxInTreeView", False, "The " & Package & MeasurementPath & " CheckBox is NOT checked"
                        End If
                    End If
                End If
            Next
        Next

    'Close application to reset its original state
    Window.Close

End Sub
 
No Comments

Posted by Jia Qi in TestPartner (TP)

 

#13: Error handling in VBA (TestPartner)_Part1

01 Jul

There are 3 error handling statements in Visual Basic of Application (VBA), which can be used in TestPartner. However, not all of these statements can be used in QTP, since QTP uses the Visual Basic Scripting Edition (VBScript) scripting language (refer to post#26 for error handling in VBScript).

The 3 error handling statements in VBA are:

1, On Error GoTo line (see post#23 for using “On Error GoTo line” in a loop with “Resume Line“)
This statement has been used in post#9.
This statement enables the error-handling routine that starts at line specified in the required line argument. The line argument is any line label or line number. If a run-time error occurs, control branches to line, making the error handler active. The specified line must be in the same procedure as the On Error statement; otherwise, a compile-time error occurs.

2, On Error Resume Next
This statement has been used in post#12.
This statement specifies that when a run-time error occurs, control goes to the statement immediately following the statement where the error occurred where execution continues. Use this form rather than On Error GoTo when accessing objects.

3, On Error GoTo 0
This statement has been used in post#12.
This statement disables any enabled error handler in the current procedure (It doesn’t specify line 0 as the start of the error-handling code, even if the procedure contains a line numbered 0.).

============================================

In the script of post#12, there is a line to move the scroll bar inside the TreeView window horizontally: “TreeView(“Parent.Caption=Preferences”).Scroll 0, tpScrollHorizontal”. This line of script is necessary when a protocol name is longer than the TreeView window width.

However, when all the protocols names are shorter than the TreeView window width, then there will be no scroll bar, which is an expected situation, but since the script can not find the scroll bar, it will pop up an error message to stop the script from running.

In order to handle the above situation, I wrote “On Error Resume Next” right above “TreeView(“Parent.Caption=Preferences”).Scroll 0, tpScrollHorizontal” line. In this way, if there is a scroll bar, then the script will scroll the scroll bar horizontally to position x=0, and if there is no scroll bar, then the script will skip the scroll step, and run the next step.

Everything looks perfect until I found out this: even though the “On Error Resume Next” is right above “TreeView(“Parent.Caption=Preferences”).Scroll 0, tpScrollHorizontal” line, it does NOT only affect the “TreeView(“Parent.Caption=Preferences”).Scroll 0, tpScrollHorizontal” line, it will affect all the lines after “On Error Resume Next”, which means, if there is an error happens after “On Error Resume Next” is executed, then the error will be ignored anyway.

If LOOP is used, when an error happens at a line above “On Error Resume Next”, the error could still be ignored, as long as the error doesn’t happen at the first iteration of the loop and before “On Error Resume Next” is executed. See the example below from post#12:

For i = 1 to Imax
     ...
     TreeView("Parent.Caption=Preferences").SelectItem (ProtocolPath)
     ...
     On Error Resume Next
     TreeView("Parent.Caption=Preferences").Scroll 0, tpScrollHorizontal
     ...
Next

Real/unexpected error may happen at line “TreeView(“Parent.Caption=Preferences”).SelectItem (ProtocolPath)”, and the script needs to alert me about these errors, but since the existence of “On Error Resume Next”, most errors happen at “TreeView(“Parent.Caption=Preferences”).SelectItem (ProtocolPath)” will be ignored, unless it happens when i=1, i.e., when “On Error Resume Next” haven’t been reached.

How to solve this issue? It is simple, you just need to add the “On Error GoTo 0″ line right above “TreeView(“Parent.Caption=Preferences”).SelectItem (ProtocolPath)”. The script will looks like this:

For i = 1 to Imax
     ...
     On Error GoTo 0
     TreeView("Parent.Caption=Preferences").SelectItem (ProtocolPath)
     ...
     On Error Resume Next
     TreeView("Parent.Caption=Preferences").Scroll 0, tpScrollHorizontal
     ...
Next

In conclusion, to ignore expected error, use “On Error Resume Next”; to alert unexpected error, use “On Error GoTo 0″ if “On Error Resume Next” has been used in the script (same level).

 
No Comments

Posted by Jia Qi in TestPartner (TP)