diff --git a/flang/unittests/Frontend/FrontendActionTest.cpp b/flang/unittests/Frontend/FrontendActionTest.cpp
--- a/flang/unittests/Frontend/FrontendActionTest.cpp
+++ b/flang/unittests/Frontend/FrontendActionTest.cpp
@@ -8,6 +8,7 @@
 
 #include "gtest/gtest.h"
 #include "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/CompilerInvocation.h"
 #include "flang/Frontend/FrontendOptions.h"
 #include "flang/FrontendTool/Utils.h"
 #include "llvm/Support/FileSystem.h"
@@ -17,119 +18,111 @@
 
 namespace {
 
-TEST(FrontendAction, PrintPreprocessedInput) {
-  std::string inputFile = "test-file.f";
-  std::error_code ec;
+class FrontendActionTest : public ::testing::Test {
+protected:
+  // AllSources (which is used to manage files inside every compiler
+  // instance), works with paths. So we need a filename and a path for the
+  // input file.
+  std::string inputFile_ = "test-file.f";
+  std::string inputFilePath_;
+  // The output stream for the input file.
+  std::unique_ptr<llvm::raw_fd_ostream> inputFileOs_;
 
-  // 1. Create the input file for the file manager
-  // AllSources (which is used to manage files inside every compiler instance),
-  // works with paths. This means that it requires a physical file. Create one.
-  std::unique_ptr<llvm::raw_fd_ostream> os{
-      new llvm::raw_fd_ostream(inputFile, ec, llvm::sys::fs::OF_None)};
-  if (ec)
-    FAIL() << "Fail to create the file need by the test";
+  std::error_code ec_;
 
-  // Populate the input file with the pre-defined input and flush it.
-  *(os) << "! test-file.F:\n"
-        << "#ifdef NEW\n"
-        << "  Program A \n"
-        << "#else\n"
-        << "  Program B\n"
-        << "#endif";
-  os.reset();
-
-  // Get the path of the input file
-  llvm::SmallString<64> cwd;
-  if (std::error_code ec = llvm::sys::fs::current_path(cwd))
-    FAIL() << "Failed to obtain the current working directory";
-  std::string testFilePath(cwd.c_str());
-  testFilePath += "/" + inputFile;
-
-  // 2. Prepare the compiler (CompilerInvocation + CompilerInstance)
   CompilerInstance compInst;
-  compInst.CreateDiagnostics();
-  auto invocation = std::make_shared<CompilerInvocation>();
-  invocation->frontendOpts().programAction_ = PrintPreprocessedInput;
-
-  compInst.set_invocation(std::move(invocation));
-  compInst.frontendOpts().inputs_.push_back(
-      FrontendInputFile(testFilePath, Language::Fortran));
-
-  // 3. Set-up the output stream. Using output buffer wrapped as an output
+  std::shared_ptr<CompilerInvocation> invocation;
+
+  void SetUp() override {
+    // Create the input file.
+    inputFileOs_ = std::make_unique<llvm::raw_fd_ostream>(
+        inputFile_, ec_, llvm::sys::fs::OF_None);
+    if (ec_)
+      FAIL() << "Fail to create the file need by the test";
+
+    // Get the path of the input file
+    llvm::SmallString<64> cwd;
+    if (std::error_code ec_ = llvm::sys::fs::current_path(cwd))
+      FAIL() << "Failed to obtain the current working directory";
+    inputFilePath_ = cwd.c_str();
+    inputFilePath_ += "/" + inputFile_;
+
+    // Prepare the compiler (CompilerInvocation + CompilerInstance)
+    compInst.CreateDiagnostics();
+    invocation = std::make_shared<CompilerInvocation>();
+
+    compInst.set_invocation(std::move(invocation));
+    compInst.frontendOpts().inputs_.push_back(
+        FrontendInputFile(inputFilePath_, Language::Fortran));
+  }
+
+  void TearDown() override {
+    // Clear the input file.
+    llvm::sys::fs::remove(inputFile_);
+
+    // Clear the output files. Note that these tests use an output buffer (as
+    // opposed to an output file), hence there are no physical output files to
+    // delete. Also, some actions don't generated output (e.g.
+    // ParseSyntaxOnly), but it's safe to call this anyway.
+    compInst.ClearOutputFiles(/*EraseFiles=*/false);
+  }
+};
+
+TEST_F(FrontendActionTest, PrintPreprocessedInput) {
+  // Populate the input file with the pre-defined input and flush it.
+  *(inputFileOs_) << "! test-file.F:\n"
+                  << "#ifdef NEW\n"
+                  << "  Program A \n"
+                  << "#else\n"
+                  << "  Program B\n"
+                  << "#endif";
+  inputFileOs_.reset();
+
+  // Set-up the action kind.
+  compInst.invocation().frontendOpts().programAction_ = PrintPreprocessedInput;
+
+  // Set-up the output stream. We are using output buffer wrapped as an output
   // stream, as opposed to an actual file (or a file descriptor).
   llvm::SmallVector<char, 256> outputFileBuffer;
   std::unique_ptr<llvm::raw_pwrite_stream> outputFileStream(
       new llvm::raw_svector_ostream(outputFileBuffer));
   compInst.set_outputStream(std::move(outputFileStream));
 
-  // 4. Run the earlier defined FrontendAction
+  // Execute the action.
   bool success = ExecuteCompilerInvocation(&compInst);
 
-  // 5. Validate the expected output
+  // Validate the expected output.
   EXPECT_TRUE(success);
   EXPECT_TRUE(!outputFileBuffer.empty());
   EXPECT_TRUE(
       llvm::StringRef(outputFileBuffer.data()).startswith("program b\n"));
-
-  // 6. Clear the input and the output files. Since we used an output buffer,
-  // there are no physical output files to delete.
-  llvm::sys::fs::remove(inputFile);
-  compInst.ClearOutputFiles(/*EraseFiles=*/true);
 }
 
-TEST(FrontendAction, ParseSyntaxOnly) {
-  std::string inputFile = "test-file.f";
-  std::error_code ec;
-
-  // 1. Create the input file for the file manager
-  // AllSources (which is used to manage files inside every compiler instance),
-  // works with paths. This means that it requires a physical file. Create one.
-  std::unique_ptr<llvm::raw_fd_ostream> os{
-      new llvm::raw_fd_ostream(inputFile, ec, llvm::sys::fs::OF_None)};
-  if (ec)
-    FAIL() << "Fail to create the file need by the test";
-
+TEST_F(FrontendActionTest, ParseSyntaxOnly) {
   // Populate the input file with the pre-defined input and flush it.
-  *(os) << "! if_stmt.f90:\n"
-        << "IF (A > 0.0) IF (B < 0.0) A = LOG (A)\n"
-        << "END";
-  os.reset();
-
-  // Get the path of the input file
-  llvm::SmallString<64> cwd;
-  if (std::error_code ec = llvm::sys::fs::current_path(cwd))
-    FAIL() << "Failed to obtain the current working directory";
-  std::string testFilePath(cwd.c_str());
-  testFilePath += "/" + inputFile;
-
-  // 2. Prepare the compiler (CompilerInvocation + CompilerInstance)
-  CompilerInstance compInst;
-  compInst.CreateDiagnostics();
-  auto invocation = std::make_shared<CompilerInvocation>();
-  invocation->frontendOpts().programAction_ = ParseSyntaxOnly;
+  *(inputFileOs_) << "! if_stmt.f90:\n"
+                  << "IF (A > 0.0) IF (B < 0.0) A = LOG (A)\n"
+                  << "END";
+  inputFileOs_.reset();
 
-  compInst.set_invocation(std::move(invocation));
-  compInst.frontendOpts().inputs_.push_back(
-      FrontendInputFile(testFilePath, Language::Fortran));
+  // Set-up the action kind.
+  compInst.invocation().frontendOpts().programAction_ = ParseSyntaxOnly;
 
-  // 3. Set-up the output stream for the semantic diagnostics.
+  // Set-up the output stream for the semantic diagnostics.
   llvm::SmallVector<char, 256> outputDiagBuffer;
   std::unique_ptr<llvm::raw_pwrite_stream> outputStream(
       new llvm::raw_svector_ostream(outputDiagBuffer));
   compInst.set_semaOutputStream(std::move(outputStream));
 
-  // 4. Execute the ParseSyntaxOnly action
+  // Execute the action.
   bool success = ExecuteCompilerInvocation(&compInst);
 
-  // 5. Validate the expected output
+  // Validate the expected output.
   EXPECT_FALSE(success);
   EXPECT_TRUE(!outputDiagBuffer.empty());
   EXPECT_TRUE(
       llvm::StringRef(outputDiagBuffer.data())
           .startswith(
               ":2:14: error: IF statement is not allowed in IF statement\n"));
-
-  // 6. Clear the input files.
-  llvm::sys::fs::remove(inputFile);
 }
 } // namespace