Abstract:
A method for testing programming interfaces including application program interfaces and command line utilities. Each interface may be called from a loop instruction in a test instruction a number of times corresponding to a number of parameter sets which are needed to test each interface. The parameter sets are maintained in a separate data file and are retrieved for each call being made to an interface. One or more return value are included in the parameter set. The operating system generates one or more return values which are compared with the stored return value. A judgment is made based on the comparison of the stored return values and the programming interface-generated return value. When this comparison is not as expected, the return values are written to a file along with the parameter set which produced the unexpected comparison.

Description:
The present invention relates to a method for efficiently testing the programming interfaces of a computer operating system or computer application. Specifically, a test method is described which provides a data structure, which includes parameter variations for each interface under test, separate from the execution commands of a programming interface. 
     Modern computer operating systems such as DOS and OS/2 provide various functions and sub-functions of the system hardware. These operating systems include a programming interface which provide function calls to all systems services under the control of the operating system. Most of the operating system functions are under the control of the application programming interface (API). 
     A C-language compiler, for example, used in the OS/2 environment, can issue calls to various application programming interfaces (APIs) which invoke various functions executable by the operating system. 
     As modern operating systems are capable of executing thousands of different functions, most of which are accessible through an interface such as an application program interface, command line utilities, or through a GUI dialogue, the various interfaces must be tested completely. All potential calls to the operating system via an interface must provide a predictable response or return code which indicates the status of the requested operation. 
     The various interfaces which call the functions of the operating, system require various sets of parameters. Certain parameter sets cause errors to be produced in the operating, system and/or result in execution-stopping events. Some of these parameter sets, known as trap and kill circumstances to the system designers, can only be discovered by extensively testing, each interface. Complete testing of some application program interfaces to identify these execution-stopping circumstances can require up to 60,000 different calls to the application program interface using a different parameter set in each call. 
     System designers have implemented test strategies for calling each programming interface used in the operating system, for each of the parameter sets necessary to test the interface, requiring upwards of 60,000 lines of code to test the more complex cases. Considering that there are thousands of application program interfaces as well as other interfaces to be checked, the test strategy becomes extremely cumbersome and code-intensive. 
     A further complication for making the numerous calls to each of the application interfaces, and other interfaces in the system, is that during design or revision of an operating system, certain parameters may be dropped or the interface itself may be changed, such that the number of parameters used in the call to invoke the interface actually changes. These types of systemic changes requires rewriting thousands of lines of test code in order to test the revised condition. 
     The present invention has been developed in an effort to efficiently test each programming interface of an operating system or application and to permit the parameter data of a call to be modified without requiring substantial rewriting of computer code. 
     SUMMARY OF THE INVENTION 
     It is an object of this invention to test computer programming interfaces. 
     It is a more specific object of this invention to provide a test methodology for testing computer operating system programming interfaces which avoids having to rewrite substantial amounts of computer test code when system parameters change. 
     It is a further object of this invention to provide a test methodology for testing computer operating systems which utilizes a testing program for calling an interface a multiple number of times, and a separate data file for providing a different parameter data set for each call. 
     These and other objects of the invention are provided for by a method which tests a defined interface of an operating system such as an application programming interface or command line utility. In accordance with the invention, a test program is compiled which includes instructions for calling each interface a multiple number of times. The data used for each call is stored in a separate data file which includes parameter values stored in parallel arrays. A complete set of parameter values for a single call to the API under test is obtained by taking the `i`th element of each array. The number of elements in each array corresponds with the number of sets of parameters which is the number of calls to be made to the API under test. 
     Each set of parameter data also includes one or more return values corresponding to the status which a call to the interface is expected to produce. As each call is made to an interface under test, the return value(s) produced by the call is compared with the expected return value stored in the parameter set, and the interface performance is judged based on this comparison. 
     The test method in accordance with the invention may be implemented with a test program which tests a single interface that calculates the length of a &#34;string&#34; of characters. 
    
    
     DESCRIPTION OF THE FIGURES 
     FIG. 1 illustrates a method for testing various interfaces of an operating system in accordance with a preferred embodiment of the invention. 
    
    
     DESCRIPTION OF THE INVENTION 
     The OS/2 operating system has thousands of application program interfaces for invoking the multiple functions of the computer system. The thousands of application program interfaces must be tested for various conditions and parameter sets. Complete testing of one API may require as many as 60,000 different parameter sets, each requiring an individual call to the API. The call function, using a given parameter set, when executed by the operating system, produces a return value indicating the status of the function which has been called and executed using the parameter set. The return value is significant in evaluating the API. 
     FIG. 1 illustrates a test organization in accordance with a preferred embodiment which facilitates the multiple calls to an API. For each application program interface to be tested, there is an associated data array containing sets of parameters, each representing data used in a call to the API. In accordance with the preferred embodiment of the invention, the call is made from a line of code contained in a test program 21, and sets of parameters for the call are contained in a data array 23(a)-23(i). Each data array 23(a)-23(i) comprises sets of parameters for testing a particular API and an expected return for each set of parameters. 
     The foregoing structure, linking parameter data for testing the API with the code for executing the call to the API permits modifying parameter data without requiring the recoding of thousands of lines of test program instructions. Thus, during the development of an operating system, parameters may be deleted from a particular API and subsequent tests to the modified system may be made by changing values in the respective data array without extensively recoding the test program. 
     The repetitive calling of an API occurs through a loop instruction given in the test program. The loop instruction includes a count number which is a function of the number of parameter sets representing the number of test variations within a data array. Thus, the sequence of calling the function a multiple number of times in order to test each test variation, requires the loop instruction to acquire a count number from the data array. The programming interface is called by the test program 21 a number of times equal to the count number. Each call results in execution of the same API function 25 with a different set of parameter data constituting one test variation. A return value is obtained from each call and compared with a return value contained in the parameter set used to make the call. Following the comparison of return values, a judgment is made as to whether or not the API functioned as expected under the set of API parameters. 
     In the event the return values do not compare as expected, the test program writes the resulting error, including the parameters that produced the resulting error, in a log for further analysis. Once the entire array of parameter variations has been the subject of a call to the API, the next API 26 to be tested is called under control of a test program 21 and its data array of sets of parameters is in the same way made the subject of a call to the API. 
     The foregoing describes the function carried out by the following C code language. As will be recognized by programmers skilled in C language, this call includes a description field for variation to describe what is being tested by the variation. 
     The foregoing example in C code is illustrative only and the method is not limited to C code programming. 
     Command line utilities may also be tested the same way that application program interfaces are tested. Command line utilities such as DIR or COPY, are invoked from a user call. A data structure for each set of test parameters similar to the foregoing data structure used to test an application program interface, is created. A loop instruction is used to make a call to the command line utility for each data structure, and an expected response is compared with the response produced from the called command line utility. 
     As an example of yet another test case which can be implemented using the invention, the STRLEN function is a &#34;C&#34; language construct that returns the number of characters in a character string. The single parameter to this function is a pointer to a string of characters. The return value is an integer representing the number of characters in the input string. The get data function is called with each iteration of the `for` loop and returns the &#34;l&#34;th input string and return value. The input string is used in the call to STRLEN and the resulting value is compared against the expected return value. 
     STRLN.sub.() can be used to determine the length of a string. It takes a string as an input parameter and it will return the length of the string excluding the terminating null character. Note that by definition in C language, a string is an array of characters terminated by a null character, i.e., string \&#34;AB\&#34; is an array of characters `A`, `B`, and a null character. Therefore, if you pass a string \&#34;ABCDE\&#34; to STRLEN.sub.(), STRLEN.sub.() will return a value of 5 because the string has a length of 5 characters, excluding the null character. 
     The testing of the function requires the programmer to establish a header file, data file and a test file. The header file includes the definitions of the data which is necessary to test the particular interface, as well as the methods for accessing the data. The data file contains the actual data structures for testing the program interface. The test file includes the code for conducting the actual call to the function under test. 
     
         ______________________________________/*definition of the data structure*/typedef struct.sub.-- data.sub.-- Struct { char **string;         /*parameter value for the only parameter*/ size.sub.-- t*exp.sub.-- RV;         /*expected return value*/ char **description;         /*description of this call*/}DATA, *pDATA;int get.sub.-- count(void);/* function which returns the number of data sets */DATA get.sub.-- data(int index);/* function which returns a single data set */  or data for a single variation______________________________________ 
    
     e.g., A parameter value with the corresponding expected RV and the description will represent a variation. 
     The TC.H is a file that contains the definitions of the necessary data structures for testing the programming interface STRLEN.sub.() as well as the methods for accessing them. 
     The TC --  DATA.C is a file that contains the necessary data structures for testing the programming interface STRLEN.sub.(). 
     In the following: 
     VARIATIONS is the count, or number of calls to be made to the *\ interface. This number is used to control the `for` loop. 
     char *string ARR --  SIZE! contains an array of five test strings. Each test string will be passed into STRLEN.sub.() and STRLEN.sub.() will determine the length of the test string and return the length as its return value of type size --  t. 
     size --  t exp --  RV ARR --  SIZE! contains an array of five expected return values. Each expected return value is decided according to the design of the programming interface and the test strings. These expected return values shall be used to compare with the actual return value from STRLEN.sub.() after STRLEN.sub.() has been called with the test string. 
     char *description contains an array of strings of text which describe the call to be made to the interface under test. 
     The order of array exp --  RV has to match with the order of test strings inside the array of *string ! to verify the result returned by STRLEN.sub.(). 
     
         ______________________________________#include &#34;TC.H&#34;#define VARIATIONS 5            /*define the size of the test*/            /*array*/char *string VARIATIONS! ={            /*an array of the test strings*/&#34;&#34;,              /*empty string with length of 0 */&#34;1&#34;,             /*string with length of 1*/&#34;2&#34;,             /*string with length of 2*/&#34;3&#34;,             /*string with length of 3*/&#34;4&#34;,             /*string with length of 4*/};size.sub.-- t exp.sub.-- RV VARIATIONS!={            /*array of the expected Return*/            /*Value from STRLEN( )*/0,               /*because test string has length of 0*/1,               /*because test string has length of 1*/2,               /*because test string has length of 2*/3,               /*because test string has length of 3*/4,               /*because test string has length of 4*/};char *description VARIATIONS!={ &#34;Testing a string of length 0&#34;, &#34;Testing a string of length 1&#34;, &#34;Testing a string of length 2&#34;, &#34;Testing a string of length 3&#34;, &#34;Testing a string of length 4&#34;};int get.sub.-- count( ) { return VARIATIONS};DATA get.sub.-- data(int index) { DATA d;  d.string = strings index!;  d.exp.sub.-- RV = exp.sub.-- RV index!;  d.description = description index!;  return d;};______________________________________ 
    
     The header file takes the form of: 
     
         ______________________________________#include studio.h     /*a header file that contains the definition of printf( )*/#include string.h     /*a header file that contains the definition of     STRLEN( )*/#include &#34;TC.h&#34;     /*a header file that contains the definition of test*/void intro( );void main( ) int actual.sub.-- RV;     /*represent actual Return Value from STRLEN( )*/ int index;     /*an index for the following for loop*/ intro( ); loop.sub.-- count = get.sub.-- count( ); for (index=( ); index loop.sub.-- count;index++) {/*looping through the test string array*/ data = get.sub.-- data(index); printf(&#34;Finding length of string\&#34;%s\&#34;\n&#34;,string index!);/*comment*/  Calling STRLEN( ) actual.sub.-- RV = strlen(data.string); /*printing the expected return value*/ printf(&#34;The expected return value is %d\n&#34;, actual.sub.--RV); /*Verifying the return value and report the test result*/ if(actual.sub.-- RV == data.exp.sub.-- RV) printf(&#34; Test PASSED|\n&#34;); else printf(&#34; Test FAILED|n&#34;); printf(&#34;\n&#34;);}/* endfor */printf(&#34;Test is done . . . \n&#34;);}void intro( )______________________________________ 
    
     Thus, there has been described with respect to several examples how programming interfaces may be conveniently tested and modified without extensive code changes to the test program. Those skilled in the art will recognize yet other embodiments defined more particularly by the claims which follow.