company logo

OSI script for data exchange

There are many ways for defining data exchanges. Here, some examples are provided in order to illustrate several possibilities. In order to provide OSI functions overloading default implementations in TestBrowser, those have to be provided in one or more files which are stored in the same directory.

When running TestBrowser, those function are loaded automatically, when the directory path has been provided in ODABA option or environment variable OSI_Library. In order to provide user defined OSI functions in OShell, one has to load those functions in addition as shown below.

In order to refer to external data sources, a file description for import/export may be defined. This setting is optional, since TestBrowser does provide dummy functions for Import/export, only, which have to be overloaded in any case. Those import/export functions define the way to refer to external files. The setting for IMPEXP_DEF is required for the example, only.

OSI script language provides many other features, which cannot be illustrated here. For more information see ODABA Script Interface.

// set OSI library path

set OSI_Library=%cd%/TestBrowser/osi/*.osi

// set external file description

set IMPEXP_DEF=%cd%/TestBrowser/osi/Imports.fsc

// OShell laoding user-defined OSI functions

// data source has to be opened first

  cd TBDat

// activate user defined osi functions from OSILibrary path (OShell.ini)

  osi do

    dictionary.loadOSILibraries;

  end

Example for simple export function

The export example creates a simple CSV output file filled with data from different levels in the test case hierarchy.

// the function overwrites the default implementation in TestBrowser resource database

// and is called when pressing the export button in the Test Browser application

// (above test suite tree).

collection bool DirEntry::ExportToCSV (string sPath )

{

VARIABLES

  SET < VOID >       exp;

PROCESS

  exp.openExtern(objectSpace,sPath,Option("IMPEXP_DEF").toString,"",odaba::AccessModes::Write,false);

  ExportToCSV_intern(exp);

  exp.closeAll;

FINAL

  return(true);

};

collection bool DirEntry::ExportToCSV_intern (set< VOID > &exp )

{

  top;

  while ( next ) {

    if ( test )

      ExportEntry(exp);

    entries.ExportToCSV_intern(exp);

  }

  return(true);

};

collection bool DirEntry::ExportEntry (set< VOID > &exp)

{

  exp.initializeInstance;

  if ( !selected ) {

    exp.test = "test";

    exp.isTest= "isTest";

    exp.dataRequirements= "dataRequirements";

    exp.result= "result";

    exp.testDescription= "testDescription";

    exp.testCase = "testCase";

    exp.caseDescription= "caseDescription";

    exp.suiteDescription = "suiteDescription";

    exp.suiteDescription = "suiteDescription";

    exp.comment = "comment";

    exp.save;      

  } else {

    exp.test = displayname;

    exp.isTest= "true";

    exp.dataRequirements=(GetAttribute("Data"));

    exp.result=GetAttribute("Result");

    exp.testDescription=ReadData("suite");

    exp.testCase = par(0).displayname;

    exp.caseDescription = par(0).ReadData("suite");

    exp.testSuite = par(0).par(0).displayname;

    exp.suiteDescription = par(0).par(0).ReadData("suite");

    exp.comment = GetAttribute("Comment");

    exp.save;      

  }

Import written in OSI code

The import example loads data from an CSV file, which defines a hierarchical structure for grouping test cases in test suites. Tests cases are provided based on software requirements, e.g. this is an example for requirement driven test. It is a bit more complex than the export example, but it demonstrates several features provided by OSI.

// The function overwrites the default implementation in TestBrowser resource database

// and is called when pressing the import button in the Test Browser application

// (above test suite tree).

//

// The function imports test cases from a requirements csv file with following columns:

//  id           - requirement identifier

//  description  - requirement description

//  testCatecory - coded test category (see description below)

//  reviewState  - Requirement review state

//  lastModified  - last modification of requirement

// This names ate taken from CSV file head line or from external file description file.fsc

// The test suite hietarchy is setup according to testCategory value, which is defined

// for each line in the import file:

//  Hn_title - Heading level (n) with optional title (title)

//  Tn       - Test case with test priority (n)

//  TH       - table heading column (number of table columns results from number of following

//             TH records. Each line in a table defines a test case

//  TCn      - Table cell data, where the first column in a table line defines the test case

//             priority (n)

// Table lines result in one test case, but information is stored for all cells in the test

// intend, which is filled with requirement description(s).

collection bool DirEntry::ImportFromCSV (string sPath )

{

VARIABLES

  extern ImportProgress   importProgress;

  SET < VOID >       imp;

  SET < DirEntry >  &curSuite = self;

  String             sCategory();

  string             description;

  string             title;

  string             category;

  string             id;

  string             str;

  string             type;

  string             sType;

  string             sTotal;

  int32              current;

  int32              priority = 0;

  int32              level = 0;

  int32              curLevel = 0;

  int32              colCount;

  int32              curColumn;

  string(100)        colTitle[20];

  bool               bTableHeader = false;

  bool               bTable = false;

  bool               bHeader = false;

  bool               bTest = false;

PROCESS

  imp.openExtern(objectSpace,sPath,Option("IMPEXP_DEF").toString,"",odaba::AccessModes::Read,true);

  sTotal = '/' + (string)imp.count;

  

  while ( imp.next ) {

    ++current;

    if ( current%10 == 0 )

      importProgress.Progress((string)current + sTotal);

    sCategory.assign(imp.testCategory);

    category = sCategory.splitTop('_');

    title = sCategory;

    type = category.left(1);

    sType = category.mid(1,1);

    switch ( type ) {

      case 'H'  : level = category.mid(1).toInteger;;

                  while ( level > curLevel + 1 ) {

                    curSuite &= curSuite.entries;

                    ++curLevel;

str = "Missing headline level " + (string)curLevel;

                    curSuite.CreateSuite("",0,curLevel,str,"",imp);

                    Message(str);

                  }

                  if ( level == curLevel + 1 ) {

                    curSuite &= curSuite.entries;

                    curLevel = level;

                  } else while ( level < curLevel ) {

                    curSuite &= curSuite.parent;

                    --curLevel;

                  }

                  id = imp.id;

                  description = imp.description;

                  priority = 0;

                  bTable = false;

                  bTableHeader = false;

                  bTest = false;

                  bHeader = true;

                  break;

      case 'T'  : if ( !bTest ) {

                    curSuite &= curSuite.entries;

                    ++curLevel;

                    bTest = true;

    if ( !curSuite.positioned ) curSuite.tryGet(0);

                  }

                  bHeader = false;

                  sType = category.mid(1,1);

                  switch ( sType ) {

                    case 'H' : if ( !bTableHeader ) {

                                 bTableHeader = true;

                                 colCount = 0;

                                 bTable = false;

if ( curSuite.positioned ) {

   if ( curSuite.entries.tryGet("0") )

     curSuite.entries.Delete;

   if ( curSuite.entries.tryGet("1") )

     curSuite.entries.Delete;

}

                               }

                               colTitle[colCount] = imp.description;

                               ++colCount;

                               break;

                    case 'C' : if ( bTableHeader || bTable ) {

                                 bTableHeader = false;

                                 bTable = true;

                                 if ( curColumn == 0 ) {

                                   id = imp.id;

                                   priority = category.mid(2).toInteger;

                                 }

                                 description += colTitle[curColumn] + ': ' + imp.description + '\n';

                                 ++curColumn;

                               } else

                                 Message("Missing table header before column with ID: " + imp.id);

                               break;

                    default  : priority = category.mid(1).toInteger;

                               id = imp.id;

                               description = imp.description;

                               bTable = false;

                               bTableHeader = false;

                  }                  

                  break;

    }  

    if ( type == 'H' || type == 'T' ) {

     if ( bHeader ||

           (bTest && !bTable && !bTableHeader) ||

           (bTable && curColumn == colCount)     )

      {

        if ( bTable )

          curSuite &= curSuite.entries;

        curSuite.CreateSuite(id,priority,curLevel,title,description,bHeader,imp);

        if ( bTable )

          curSuite &= curSuite.parent;

        description = "";

        title = "";

        id = "";

        curColumn = 0;

      }

}

  }

  imp.closeAll;

FINAL

  return(true);

};

collection bool DirEntry::CreateSuite (string id, int32 priority, int32 level, string title, string description, bool bHeader, set< VOID > &imp )

{

    top;

    while ( next )

      if ( GetAttribute("ID") == id )

        break;

    if ( !positioned ) {

      Create(parent.FullPath,(string)NextNumber(count-2),true,false);

      if ( !bHeader ) {

        entries.Create(FullPath,"0",true,true);

        entries.SetAttribute("Result","success");

        entries.Create(FullPath,"1",true,true);

        entries.SetAttribute("Result","error");

      }

    }

    WriteData("suite",description);

    if ( id != "" ) {

      SetAttribute("ID",id);

  if ( bHeader )

        SetAttribute("Header",(string)level);

      else

        SetAttribute("Priority",(string)priority);

      if ( title != "" )

        SetAttribute("Title",title);

      SetAttribute("ReviewState",imp.reviewState);

      SetAttribute("LastModified",imp.lastModified);

}

displayname = DisplayName;

    return(true);

};