Some questions/notes:

1. Why are you not using relationships?

2. If you have an object, which references another object in a property and you save a base object all it's properties-objects are also saved automatically. Have you thought about setting all references before save and after that only calling %Save() once?

3. I'd really recommend against relying on auto-incremental ID matches. They are NOT guaranteed to be equal.

4. The answer to your original question depends on where the failure was. %OnAfterSave is in transaction and is rolled back. However $Increment  used to get hew IDs is not rolled back (as per documentation).

If you want it stored, make it triggered computed like this:

Property LabCode As %Library.String(MAXLEN = 64) [
  SqlColumnNumber = 5,
  SqlComputeCode = { set {*}= $EXTRACT({LabName},0,3)_" "_{LabID}},
  SqlComputed,
  SqlComputeOnChange = LabName ];

Docs.

Note that it wouldn't recalc LabCode values for existing rows. If you need that, trigger recalculation with trivial update.

Use {%%ID}.

Here's an example:

Class util.Calc Extends %Persistent
{
Property calc As %String [ Calculated, SqlComputeCode = {set {*} = {%%ID}}, SqlComputed ];

/// do ##class(util.Calc).Test()
ClassMethod Test()
{
    set obj = ..%New()
    set sc = obj.%Save()
    do ..AllFunc().%Display()
}

Query All() As %SQLQuery
{
SELECT *
FROM util.Calc
}
}

Calling:

do ##class(util.Calc).Test()

Returns:

ID      calc
1       1

Docs.

There are many ways to do what you need.

  • Copy CACHE.DAT / IRIS.DAT
  • Export globals and code
  • Use ASYNC mirror or backup

Here's the questions you need to answer to choose the best path:

  • Is downtime OK or not?
  • Do you need a whole database or some part?
  • What's the size of your DB?
  • Are there mirrors/backups available?
  • Are your code/data in separate DBs?
  • Do you need to run the pipeline once or do you need to stay somewhat up to date?

You'll need a SQL procedure to return status. I haven't found it already SQL enabled.

ClassMethod ItemStatuses(pName, pIsRunning, pEnabled, pID) As %String [ CodeMode = expression, SqlProc ]
{
##class(EnsPortal.Utils).ItemStatuses(pName, pIsRunning, pEnabled, pID)
}

After that just query Ens_Config.Item:

SELECT
  ID,
  ClassName,
  Name,
  Enabled,
  ItemStatuses(Name, 1, Enabled, Id) Status
FROM Ens_Config.Item

Parameter pIsRunning means a running production.

Procedure returns comma-separated info about host status and io status.

Do you use an alternative or framework built around this native Unit Testing tool ?

Not really.

What is your experience with %UnitTest if you use it ?

Except lack of test parallelization it's actually quite good. Also would be great to be able to skip some tests natively.

Is there a tool you would recommend for your UI (I know this is not specifically an InterSystems' related question)

@Sergey.Sarkisyan any comments?

What process do you use to routinely run tests on your application ? 

You can read about that in my series of articles on GitLab.