… Пишите лучшие тесты

Это вторая часть серии статей о тестировании Apex. В Части 1 были рассмотрены некоторые основные рекомендации и рекомендации по написанию лучших тестов Apex. Мы закончили введением шаблона Упорядочить, действовать, утвердить, чтобы использовать его для написания более качественных тестов.

В этой части будет кратко рассмотрено, что Salesforce рекомендует тестировать, а также различные типы тестов. Мы также увидим несколько примеров кода шаблона «Упорядочить, действовать, утвердить». Пожалуйста, обратитесь к ссылкам в разделе «Полезные ссылки» для документации и дополнительных примеров.

Что тестировать?

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

Одно действие

Протестируйте, чтобы убедиться, что одна запись дает правильный ожидаемый результат.

Массовые действия

Любой код Apex, будь то триггер, класс или расширение, может быть вызван для 1–200 записей. Вы должны протестировать не только единичный случай записи, но и объемные случаи. Их часто называют массовыми тестами.

Положительное поведение

Протестируйте, чтобы убедиться, что ожидаемое поведение происходит при каждой ожидаемой перестановке, то есть что пользователь заполнил все правильно и не вышел за пределы. Это называется положительные тесты.

Положительные тесты используются для подтверждения того, что ваш код работает правильно при правильном вводе. Например, вы можете написать положительный тест, чтобы убедиться, что метод правильно вычисляет общую стоимость заказа при наличии действительного списка позиций.

Отрицательное поведение

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

Отрицательные тесты, также известные как тесты-исключения, используются для проверки того, что ваш код правильно обрабатывает недопустимый ввод. Например, вы можете написать отрицательный тест, чтобы убедиться, что метод выдает исключение, когда ему предоставляется пустой список элементов строки.

Ограниченный пользователь

Проверьте, видит ли пользователь с ограниченным доступом к объектам sObject, используемым в вашем коде, ожидаемое поведение. То есть могут ли они запускать код или получать сообщения об ошибках. Их также иногда называют тестами на основе разрешенийилитестами запуска от имени.

Тесты System.runAs(). Метод System.runAs() позволяет тестировать код с использованием различных разрешений пользователя. Это полезно для тестирования триггеров и другого кода, который может вести себя по-разному в зависимости от разрешений пользователя. Например, вы можете написать тест System.runAs(), чтобы убедиться, что триггер срабатывает только для пользователей с правильными разрешениями.

Вот пример положительного теста для простого метода Apex, который вычисляет общую стоимость заказа:

@isTest
public static void testCalculateTotalCost() {
    // Arrange
    List<OrderLineItem> lineItems = new List<OrderLineItem> {
        new OrderLineItem(Quantity = 3, Price = 10.0),
        new OrderLineItem(Quantity = 2, Price = 20.0)
    };
    
    // Act
    Decimal totalCost = OrderUtils.calculateTotalCost(lineItems);
    
    // Assert
    System.assertEquals(70.0, totalCost, 'Total cost should be correct');
}

А вот пример отрицательного теста для того же метода:

@isTest
public static void testCalculateTotalCost_EmptyLineItems() {
    // Arrange
    List<OrderLineItem> lineItems = new List<OrderLineItem>();
    
    // Act and assert
    Test.assertThrows(IllegalArgumentException.class,
        () -> OrderUtils.calculateTotalCost(lineItems),
        'Empty line items should throw an exception');
}

Расширенные типы тестов

Помимо «что тестировать» в приведенном выше коде,

Существуют определенные уникальные проблемы, связанные с определенными расширенными классами, использующими интерфейсы, связанные сасинхронными, пакетными вершинами, вызовами веб-сервисови т. д.

Те требуют следующих методов.

  1. Имитационные тесты веб-службы. Пробные тесты веб-службы позволяют тестировать код Apex, который вызывает веб-службу, имитируя ответ веб-службы. Это полезно для тестирования кода, который зависит от внешних служб, без фактического вызова службы. Например, вы можете написать пробный тест веб-службы, чтобы убедиться, что ваш код Apex может правильно обрабатывать ответ веб-службы, когда она возвращает определенный код ошибки.

2. Пакетный Apex и асинхронный Apex могут быть немного сложнее, чем тестирование синхронного кода Apex, поскольку эти типы кода могут выполняться асинхронно и могут иметь сложные зависимости. Ниже приведены некоторые рекомендации по разработке тестовых классов для тестирования пакетного Apex и асинхронного Apex.

Используйте методы Test.startTest() и Test.stopTest() для управления выполнением асинхронного кода. Эти методы позволяют указать блок кода, который должен быть выполнен. асинхронно, и они гарантируют, что любые асинхронные процессы, запущенные в этом блоке, будут завершены до завершения метода тестирования.

Используйте методы System.assert() для проверки результатов вашего пакетного или асинхронного кода Apex. Методы System.assert() можно использовать для проверки того, что ваш пакетный или асинхронный код Apex дает правильные результаты.

Используйте метод Test.isRunningTest(), чтобы обойти или изменить поведение пакетного или асинхронного кода Apex в методах тестирования.

Метод Test.isRunningTest() возвращает значение true, когда выполняется тестовый метод, и значение false в производственной среде. Этот метод можно использовать для обхода или изменения поведения пакетного или асинхронного кода Apex в методах тестирования, чтобы упростить его тестирование.

Используйте объекты AsyncApexJob и BatchApexJob для проверки состояния пакетных или асинхронных заданий Apex. Эти объекты позволяют проверить состояние пакетных или асинхронных заданий Apex и убедиться, что они завершаются успешно.

Вот пример тестового метода для пакетного класса Apex, обрабатывающего список учетных записей:

@isTest
private static void testBatchAccountProcessor() {
    // Arrange
    List<Account> accounts = new List<Account> {
        new Account(Name = 'Test Account 1'),
        new Account(Name = 'Test Account 2')
    };
    insert accounts;
    
    Test.startTest();
    BatchAccountProcessor batch = new BatchAccountProcessor(accounts);
    ID batchId = Database.executeBatch(batch);
    Test.stopTest();
    
    // Act
    AsyncApexJob job = [SELECT Status FROM AsyncApexJob WHERE Id = :batchId];
    
    // Assert
    System.assertEquals('Completed', job.Status, 'Batch job should complete successfully');
}

Полезные ссылки