GTest parametrizado para pruebas de HAL

En el caso de una interfaz HAL, puede haber varias implementaciones. Para probar cada instancia de una implementación de HAL, la forma estándar es escribir una GTest parametrizada por valores.

Configuración básica de la prueba

El GTest debe heredar la clase base testing::TestWithParam, en la que el parámetro es el nombre de cada instancia. En el método SetUp, el servicio se puede crear una instancia según el nombre de la instancia, como se muestra en el siguiente fragmento de código.

// The main test class for the USB hidl HAL
class UsbHidlTest : public testing::TestWithParam<std::string> {

 virtual void SetUp() override {
   usb = IUsb::getService(GetParam());
   ASSERT_NE(usb, nullptr);
...
 }

Para cada método de prueba, usa la macro TEST_P como se muestra en el siguiente ejemplo:

TEST_P(UsbHidlTest, setCallback) {
...
}

Crea una instancia del conjunto con la macro INSTANTIATE_TEST_SUITE_P, como se muestra en el siguiente ejemplo:

INSTANTIATE_TEST_SUITE_P(
       PerInstance, UsbHidlTest,
       testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)),
       android::hardware::PrintInstanceNameToString);

Los argumentos son:

  1. InstantiationName, que puede ser cualquier elemento que coincida con tu prueba. PerInstance es un nombre común.

  2. Es el nombre de la clase de prueba.

  3. Es una colección de nombres de instancias que se pueden recuperar del método integrado, por ejemplo, getAllHalInstanceNames.

  4. Es el método para imprimir el nombre del método de prueba. PrintInstanceNameToString es un nombre integrado que puedes usar para compilar un nombre de prueba basado en el nombre de la instancia y el nombre del método de prueba.

Prueba con varias entradas

GTest admite tuplas para las pruebas parametrizadas por valores. Cuando una prueba de HAL requiere pruebas con varias entradas (por ejemplo, una prueba con varias interfaces), puedes escribir una prueba de GTest con tuple como parámetro de prueba. Puedes encontrar el código completo en VtsHalGraphicsMapperV2_1TargetTest.

En comparación con GTest con un solo parámetro de prueba, esta prueba debe usar tuple como parámetro de prueba, como se muestra en el siguiente ejemplo:

class GraphicsMapperHidlTest
   : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
 protected:
   void SetUp() override {
       ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
                                                                    std::get<1>(GetParam())));

}

Si se necesitan parámetros más complicados, se recomienda usar una estructura y funciones ToString personalizadas de GTest.

Para crear una instancia del conjunto de pruebas, también se usa la macro INSTANTIATE\_TEST\_CASE\_P, con dos diferencias:

  • El tercer argumento es una colección de tuplas (en lugar de una colección de cadenas en el caso básico).
  • El método para compilar un nombre de prueba debe admitir tuple. Puedes usar el método integrado PrintInstanceTupleNameToString, que puede controlar tuplas de cadenas, como se muestra en el siguiente ejemplo:
INSTANTIATE_TEST_CASE_P(
       PerInstance, GraphicsMapperHidlTest,
       testing::Combine(
               testing::ValuesIn(
                       android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
           testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
       android::hardware::PrintInstanceTupleNameToString<>);