Parametrisierter GTest für HAL-Tests

Für eine HAL-Schnittstelle kann es mehrere Implementierungen geben. Um jede Instanz für eine HAL-Implementierung zu testen, wird standardmäßig ein wertparametrierter GTest geschrieben.

Grundlegende Testeinrichtung

Der GTest muss die Basisklasse testing::TestWithParam erben, deren Parameter der Name jeder Instanz ist. In der Methode SetUp kann der Dienst basierend auf dem Instanznamen instanziiert werden, wie im folgenden Code-Snippet gezeigt.

// 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);
...
 }

Verwenden Sie für jede Testmethode das Makro TEST_P, wie im folgenden Beispiel gezeigt:

TEST_P(UsbHidlTest, setCallback) {
...
}

Instanzieren Sie die Suite mit dem Makro INSTANTIATE_TEST_SUITE_P, wie im folgenden Beispiel gezeigt:

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

Die Argumente sind:

  1. InstantiationName, das kann alles sein, was zu Ihrem Test passt. PerInstance ist ein gängiger Name.

  2. Der Name der Testklasse.

  3. Eine Sammlung von Instanznamen, die über die integrierte Methode abgerufen werden können, z. B. getAllHalInstanceNames.

  4. Die Methode zum Drucken des Namens der Testmethode. PrintInstanceNameToString ist ein vordefinierter Name, mit dem Sie einen Testnamen basierend auf dem Instanznamen und dem Namen der Testmethode erstellen können.

Mit mehreren Eingaben testen

GTest unterstützt Tupel für wertparametrisierte Tests. Wenn für einen HAL-Test mehrere Eingaben erforderlich sind (z. B. ein Test mit mehreren Schnittstellen), können Sie einen GTest mit tuple als Testparameter schreiben. Den vollständigen Code finden Sie unter VtsHalGraphicsMapperV2_1TargetTest.

Im Vergleich zum GTest mit einem einzelnen Testparameter muss für diesen Test tuple als Testparameter verwendet werden, wie im folgenden Beispiel gezeigt:

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())));

}

Wenn komplexere Parameter erforderlich sind, wird empfohlen, eine Struktur und benutzerdefinierte GTest-ToString-Funktionen zu verwenden.

Zum Instanziieren der Testsuite wird auch das Makro INSTANTIATE\_TEST\_CASE\_P verwendet, jedoch mit zwei Unterschieden:

  • Das dritte Argument ist eine Sammlung von Tupeln (im Vergleich zu einer Sammlung von Strings im Basisfall).
  • Die Methode zum Erstellen eines Testnamens muss tuple unterstützen. Sie können die integrierte Methode PrintInstanceTupleNameToString verwenden, die Tupel von Strings verarbeiten kann, wie im folgenden Beispiel gezeigt:
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<>);