Populating test/initial data

How do you populate and update test/initial data for you classes?

CSV tables? Globals export? And how do you update test data?

Here's one way I found useful for small projects.

Class utils.Test Extends (%Persistent, %XML.Adaptor)
{

Parameter XDATA = "Data";

Property PropertyA As %String;

/// set sc = ##class(utils.Test).Export()
ClassMethod Export() As %Status
{
    quit:$classmethod($classname(), "%Extends", "%XML.Adaptor")=0 $$$ERROR($$$GeneralError, "Class " _ $classname() _ " should extend %XML.Adaptor")
    
    if ##class(%Dictionary.XDataDefinition).IDKEYExists($classname(), ..#XDATA) {
        set xdata = ##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), ..#XDATA)
    } else {
        set xdata = ##class(%Dictionary.XDataDefinition).%New($classname() _  ":" _ ..#XDATA)
    }
    
    #dim stream As %Stream.TmpCharacter
    set stream = xdata.Data
    
    do stream.Clear()
    do stream.WriteLine("<xml>")
    
    for i=1:1:$g(@##class(utils.Test).GetIdGlobal(), 0) {
        set obj = ..%OpenId(i)
        do obj.XMLExportToStream(.stream)
        do stream.WriteLine("")
    }
    do stream.WriteLine("</xml>")
    quit xdata.%Save()
}

/// do ##class(utils.Test).Import()
ClassMethod Import(killExtent As %Boolean = {$$$YES}) As %Status
{
    #dim sc As %Status = $$$OK
    set xdata = ##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), ..#XDATA,,.sc)
    quit:$$$ISERR(sc) sc
    
    #dim stream As %Stream.TmpCharacter
    set stream = xdata.Data
    
    set reader = ##class(%XML.Reader).%New()
    set sc = reader.OpenStream(stream)
    quit:$$$ISERR(sc) sc
    do reader.Correlate(..GetXMLName(), $classname())
    
    do:killExtent ..%KillExtent()
    while reader.Next(.obj, .sc) {
        quit:$$$ISERR(sc)
        
        set sc = obj.%Save()
        quit:$$$ISERR(sc)
    }
    
    quit sc
}

/// Get class XMLName
/// w ##class(utils.Test).GetXMLName()
ClassMethod GetXMLName(class As %Dictionary.CacheClassname = {$classname()}) As %String
{
    set xmlname = ..#XMLNAME
    set:xmlname="" xmlname = $$$ClassShortName(class)
    quit xmlname
}

/// Get the name of Id global from active storage.
/// w ##class(utils.Test).GetIdGlobal()
ClassMethod GetIdGlobal(class As %Dictionary.CacheClassname = {$classname()}) As %String
{
    quit:'$$$comClassDefined(class) ""
    set strategy = $$$comClassKeyGet(class, $$$cCLASSstoragestrategy)
    quit $$$defMemberKeyGet(class, $$$cCLASSstorage, strategy, $$$cSDEFidlocation)
}

}

When you want to save class data (i.e. for project release) you call Export method and it creates XData definition that holds serialized objects:

XData Data
{
<xml>
  <Test><PropertyA>1</PropertyA></Test>
  <Test><PropertyA>2</PropertyA></Test>
</xml>
}

And to load data you need to call Import method, which would read XData and save the objects found there.

If you have a lot of classes, you can move all these methods to a separate class, and add it as a superclass to the persistent classes you want to save.

It could also have ExportAll/ImportAll methods iterating over results of %Dictionary.ClassDefinitionQuery:SubclassOf query.

What's your approach?

This approach obviously can't hold a lot of data.

  • + 1
  • 0
  • 98
  • 2
  • 1

Answers

Comments

We are still somewhat old school eGate folks in this sense. We send all of our transactions to flat files, then we can use those files to feed in data into the test system if needed. We did this when we moved from eGate to Ensemble to make sure we were getting the same transactions and counts.