Search code examples
c++googletestfixtures

Parametrized tests with parametrized SetUp()/TearDown()


I have a test fixture that shares most of the test code. The variations are mostly from a parameter value. I would like to create SetUp() / TearDown() for them, but they (obviously) can't be called with a parameter. What would the best strategy to use SetUp() / TearDown() mechanisms while avoiding code duplication?

This is my original code :

class FileToolsTest : public testing::Test
{
   protected:

   void TestReadAndWrite(const wstring& filename, const wstring& content)
   {
      FileTools::RemoveFile(filename);

      // Test code there

      ok = FileTools::RemoveFile(filename);
      ASSERT_EQ(true, ok);
   }
};

//-------------------------------------------------------------------------

TEST_F(FileToolsTest, ReadAndWrite_case1)
{
   const wstring testFilename = L"testfile";
   const wstring testContent = L"This\nis\ndummy\ndata";
   TestReadAndWrite(testFilename, testContent);
}

TEST_F(FileToolsTest, ReadAndWrite_case2)
{
   const wstring testFilename = L"testfíle";
   const wstring testContent = L"This\nis\ndummy\n\nuníc@de datã éééé";
   TestReadAndWrite(testFilename, testContent);
}

TEST_F(FileToolsTest, Write_case3)
{
   const wstring testFilename = L"Micka\x00ebl/fileWithUnicodeFolderInPath2.txt";

   if (FileTools::FileExists(testFilename))
   {
      const bool ok = FileTools::RemoveFile(testFilename);
      ASSERT_TRUE(ok);
   }

   // Test code there

   FileTools::RemoveFile(testFilename);
}

As you can see, ::RemoveFile() is duplicated between TestReadAndWrite() and Write_case3(), both at test start and test end.


Solution

  • The example of Value-Parameterized Test.

    #include <string>
    #include <gtest/gtest.h>
    
    struct FileTools {
      static bool RemoveFile(const std::wstring&);
    };
    
    struct FileToolsTestParam {
      const std::wstring testFilename;
      const std::wstring testContent;
    } kFileToolsTestParam[] = {
      {
       L"testfile",
       L"This\nis\ndummy\ndata"
      },
      {
       L"testfíle",
       L"This\nis\ndummy\n\nuníc@de datã éééé"
      }
    };
    
    class FileToolsTest : public testing::TestWithParam<FileToolsTestParam> {
      protected:
       void SetUp() override {
         const auto& param = GetParam();
         FileTools::RemoveFile(param.testFilename);
       }
       void TearDown() override {
         const auto& param = GetParam();
         const bool ok = FileTools::RemoveFile(param.testContent);
         ASSERT_EQ(true, ok);
       }
    };
    
    INSTANTIATE_TEST_SUITE_P(FileTools, FileToolsTest, testing::ValuesIn(kFileToolsTestParam));
    
    TEST_P(FileToolsTest, ReadAndWrite) {
      // Test code there
    }