I am supporting CandidateX

CandidateX is a startup that focuses on creating inclusion-focused hiring solutions, designed to increase access to job opportunities for underestimated talent. Check them out if you have a few minutes to spare. They need visibility!

One problem with running things from html service with google.script.run is that you don’t have access to logging and execution log, so it’s difficult to debug. I like to run my profile components inline first to make sure they work. Here’s how you can simulate running this stuff from google.script.run in the context of a normal apps script.
This function takes your profile and executes the named function, and passes over the data just as would happen if it was called from google.script.run.
/** 
 * from a profile, emulates running it from the sidebar
 * @param {object} profile the profile
 * @param {data} the data to pass
 * @return {object} whatever the function would return
 */
function inLineTest (profile,data) {
  var evalable = profile.functionName + "(" + JSON.stringify(profile.options) + (data ? ("," + JSON.stringify(data)) : "") + ")";
  return eval(evalable);  
}

We can call that, passing each of the individual run profiles, and emulate passing the data from the previous stage just as happens when being orchestrated by the html service. Of course you can only run one thing at once, but this allows you to test all your profiles in a much more visible environment.

function smallDbTest() {
  // i'll do properties
  var p = cUseful.clone(dbDataStoreParameters());

  // clear the sheet
  var d = inLineTest (dbAsyncClear (p.parameters, p.driver,p.clearProcess),null);

  // some test data
  var d = inLineTest (dbAsyncTestData (),null);

  // reduce
  var d = inLineTest (dbAsyncReduce(),[{results:d}]);

  // the tests
  var d = inLineTest (dbAsyncExecute (p.parameters,p.driver,0,1,p.process),[{results:d}]);

  // reduce
  var d = inLineTest (dbAsyncReduce(),[{results:d}]);
  
  // log
  var d = inLineTest (dbAsyncLog(p.driver),[{results:d}]);

}

Notice that I use functions to set up the profiles. I use exactly the same ones when running this for real. That way I can be sure I’m testing what I’m planning to use in real life. Here’s the example for the reduce function.

function dbAsyncReduce () {
  return {
    "name": "reduction",
    "functionName":"reduceTheResults",
    "debug":false,
    "options":{
    }
  };
}

Later on, when I run this for real, I put it all together like this

function dbAsyncProfiles(dbParameters, dbDriver, process, clearProcess) {
  
  var CHUNKS = 4;
  var profile = [];
  
  // clear the db
  var profileClear = [dbAsyncClear (dbParameters, dbDriver, clearProcess )];
  
 // get the test data
  var profileTest = [dbAsyncTestData ()];
  
  // reduce the test data
  var profileReduction = [dbAsyncReduce()];
    
  // get and process all the messages
  var profileSheets = [];
  for (var i =0; i <CHUNKS;i++ ) {
    profileSheets.push (dbAsyncExecute (dbParameters,dbDriver,i,CHUNKS,process));
  }
  
  //Log the results
  var profileLog= [dbAsyncLog (dbDriver)];

  profile.push(
    profileClear,
    profileTest,
    profileReduction,
    profileSheets,
    profileReduction,
    profileLog
  );
  
  return profile;
  
}

You may also find this post useful, if you have some unserializeable objects to deal with. How to pass non stringifyable objects to html service

For more snippets like this see Google Apps Scripts snippets