Как я могу проверить триггерную функцию в GAS?

Google Apps Script поддерживает триггеры, которые передают события для запуска функций. К сожалению, среда разработки позволит вам тестировать функции без передачи параметров, поэтому вы не можете смоделировать событие таким образом. Если вы попытаетесь, вы получите сообщение об ошибке:

ReferenceError: 'e' не определено.

Можно обработать событие как необязательный параметр и вставить значение по умолчанию в функцию триггера, используя любой из методов из " Есть ли лучший способ сделать необязательные параметры функции в JavaScript?". Но это создает риск того, что ленивый программист (подождите, если это вы!) Оставит этот код с непреднамеренными побочными эффектами.

Конечно, есть лучшие способы?

4 ответа

Решение

Вы можете написать тестовую функцию, которая передает смоделированное событие в вашу функцию триггера. Вот пример, который проверяет onEdit() триггерная функция. Он передает объект события со всей информацией, описанной для "События редактирования электронной таблицы" в разделе " Общие сведения о событиях".

Чтобы использовать его, установите точку останова в вашей цели onEdit функция, выберите функцию test_onEdit и ударил Debug,

/**
 * Test function for onEdit. Passes an event object to simulate an edit to
 * a cell in a spreadsheet.
 *
 * Check for updates: https://stackru.com/a/16089067/1677912
 *
 * See https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
 */
function test_onEdit() {
  onEdit({
    user : Session.getActiveUser().getEmail(),
    source : SpreadsheetApp.getActiveSpreadsheet(),
    range : SpreadsheetApp.getActiveSpreadsheet().getActiveCell(),
    value : SpreadsheetApp.getActiveSpreadsheet().getActiveCell().getValue(),
    authMode : "LIMITED"
  });
}

Если вам интересно, это было написано, чтобы проверить onEdit функция для Google Spreadsheet условно на три ячейки.

Вот тестовая функция для событий представления формы электронной таблицы. Он создает свое смоделированное событие, читая данные отправки формы. Это было изначально написано для получения TypeError в триггере onFormSubmit?,

/**
 * Test function for Spreadsheet Form Submit trigger functions.
 * Loops through content of sheet, creating simulated Form Submit Events.
 *
 * Check for updates: https://stackru.com/a/16089067/1677912
 *
 * See https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
 */
function test_onFormSubmit() {
  var dataRange = SpreadsheetApp.getActiveSheet().getDataRange();
  var data = dataRange.getValues();
  var headers = data[0];
  // Start at row 1, skipping headers in row 0
  for (var row=1; row < data.length; row++) {
    var e = {};
    e.values = data[row].filter(Boolean);  // filter: https://stackru.com/a/19888749
    e.range = dataRange.offset(row,0,1,data[0].length);
    e.namedValues = {};
    // Loop through headers to create namedValues object
    // NOTE: all namedValues are arrays.
    for (var col=0; col<headers.length; col++) {
      e.namedValues[headers[col]] = [data[row][col]];
    }
    // Pass the simulated event to onFormSubmit
    onFormSubmit(e);
  }
}

подсказки

При моделировании событий постарайтесь максимально точно сопоставить документированные объекты событий.

  • Если вы хотите проверить документацию, вы можете записать полученное событие из функции триггера.

    Logger.log( JSON.stringify( e , null, 2 ) );
    
  • В форме представления электронных таблиц события:

    • все значения namedValues ​​являются массивами.
    • Временные метки - это строки, и их формат будет локализован в соответствии с локалью формы. При чтении из электронной таблицы с форматированием по умолчанию* они являются объектами Date. Если ваша функция триггера основана на строковом формате отметки времени (что является плохой идеей), позаботьтесь о том, чтобы вы соответствующим образом смоделировали значение.
    • Если в вашей таблице есть столбцы, которых нет в вашей форме, методика этого сценария будет имитировать "событие" с включенными дополнительными значениями, а не то, что вы получите от отправки формы.
    • Как сообщается в выпуске 4335, values массив пропускает пустые ответы (в "новых формах" + "новых листах"). filter(Boolean) Метод используется для моделирования этого поведения.

* Ячейка в формате "обычный текст" сохранит дату в виде строки и не является хорошей идеей.

Обновление 2020:

Вам не нужно использовать какие-либо имитирующие события, как предлагалось в предыдущих ответах.

Как сказано в вопросе, если вы напрямую "запускаете" функцию в редакторе скриптов, ошибки вроде

TypeError: невозможно прочитать свойство ... из неопределенного

брошены. Это не настоящие ошибки. Эта ошибка возникает только потому, что вы запустили функцию без события. Если ваша функция работает не так, как ожидалось, вам нужно выяснить фактическую ошибку:

Чтобы проверить функцию триггера,

  1. Запустить соответствующее событие вручную: например, для проверки onEdit, отредактируйте ячейку на листе; Тестировать onFormSubmit, отправьте фиктивную форму ответа. Тестировать doGet, перейдите в браузере к опубликованному веб-приложению /exec URL.

  2. Если есть какие-либо ошибки, они записываются в stackdriver. Чтобы просмотреть эти журналы,

    • В редакторе сценариев> Просмотр> Выполнения.

    • Или щелкните здесь > щелкните интересующий вас проект> на панели управления "Сведения о проекте"> в правом верхнем углу щелкните меню с тремя точками> щелкните "Выполнения"

  3. Вы найдете список казней на странице казней. Обязательно отключите все фильтры, такие как "Ran as:Me" в левом верхнем углу, чтобы отобразить все казни. Нажмите на выполнение, которое вас интересует, оно покажет ошибку, которая привела к сбою триггера, красным цветом.

Примечание. Иногда журналы не отображаются из-за ошибок. Это особенно верно в случае, если веб-приложение запускается анонимными пользователями. В таких случаях рекомендуется переключить облачный проект Google по умолчанию на стандартный облачный проект Google и напрямую использовать "Просмотр"> "Ведение журнала Stackdriver". См. Здесь для получения дополнительной информации.

  1. Для дальнейшей отладки вы можете использовать отредактировать код, чтобы добавить console.log(/*object you're interested in*/)после любой строки, которая вас интересует, чтобы увидеть детали этого объекта. Он настоятельно рекомендуется, что вы stringify объект, который вы ищете: console.log(JSON.stringify(e))поскольку у программы просмотра журналов есть свои особенности. После добавления console.log(), повторите, начиная с шага 1. Повторяйте этот цикл, пока не решите проблему.

Поздравляю! Вы успешно решили проблему и преодолели первое препятствие.

Обновление 2017 года: отладка объектов событий с помощью ведения журнала Stackdriver для скрипта Google Apps. Из строки меню в редакторе скриптов перейдите: View > Stackdriver Logging просматривать или транслировать логи.

console.log () напишет DEBUG сообщения уровня

Пример onEdit ():

function onEdit (e) {
  var debug_e = {
    authMode:  e.authMode,  
    range:  e.range.getA1Notation(),    
    source:  e.source.getId(),
    user:  e.user,   
    value:  e.value,
    oldValue: e. oldValue
  }

  console.log({message: 'onEdit() Event Object', eventObject: debug_e});
}

Пример onFormSubmit ():

function onFormSubmit (e) {
  var debug_e = {
    authMode:  e.authMode,  
    namedValues: e.namedValues,
    range:  e.range.getA1Notation(),
    value:  e.value
  }

  console.log({message: 'onFormSubmit() Event Object', eventObject: debug_e});
}

Пример onChange ():

function onChange (e) {
  var debug_e = {
    authMode:  e.authMode,  
    changeType: changeType,
    user:  e.user
  }

  console.log({message: 'onChange() Event Object', eventObject: debug_e});
}

Затем проверьте журналы в пользовательском интерфейсе Stackdriver, помеченные как message строка, чтобы увидеть вывод

В дополнение к методу, упомянутому выше (Обновление 2020) в пункте 4. Вот небольшая процедура, которую я использую для отслеживания срабатывающего кода и которая уже сэкономила мне много времени. Также у меня открыто два окна: одно с драйвером стека (исполнения) и одно с кодом (который в основном находится в библиотеке), поэтому я легко могу определить виновника.

Другие вопросы по тегам