Consistent approach for whole-program tests
authorTeemu Murtola <teemu.murtola@gmail.com>
Fri, 31 Mar 2017 19:34:02 +0000 (22:34 +0300)
committerMark Abraham <mark.j.abraham@gmail.com>
Mon, 17 Apr 2017 10:32:01 +0000 (12:32 +0200)
All tests that essentially execute one command-line program as the test
are now using CommandLineTestBase, which makes them much simpler, easier
to read, and a better source for copy-pasting new tests.  Move the
functionality of IntegrationTestFixture to a helper class that can be
used in any kind of test and not excluding other types of useful
fixtures from tests that need that functionality.

Tests that execute mdrun are not changed here to keep the scope limited.

Change-Id: Ic49593d6e27c48be43021e4fc9b1fcd685d43ffd

15 files changed:
src/gromacs/energyanalysis/tests/legacyenergy.cpp
src/gromacs/energyanalysis/tests/refdata/DhdlTest_ExtractDhdl.xml
src/gromacs/energyanalysis/tests/refdata/ViscosityTest_EinsteinViscosity.xml
src/gromacs/energyanalysis/tests/refdata/ViscosityTest_EinsteinViscosityIntegral.xml
src/gromacs/gmxana/tests/gmx_traj.cpp
src/gromacs/gmxana/tests/gmx_trjconv.cpp
src/gromacs/trajectoryanalysis/tests/clustsize.cpp
src/programs/mdrun/tests/moduletest.cpp
src/programs/mdrun/tests/moduletest.h
src/testutils/CMakeLists.txt
src/testutils/cmdlinetest.cpp
src/testutils/cmdlinetest.h
src/testutils/stdiohelper.cpp [moved from src/testutils/integrationtests.cpp with 87% similarity]
src/testutils/stdiohelper.h [moved from src/testutils/integrationtests.h with 62% similarity]
src/testutils/testutils-doc.h

index 3722065dcbaf600268f72885bf8867000687a792..e906db1bb693774b05cfe979325ee6d6e5ee1a62 100644 (file)
 #include <string>
 
 #include "gromacs/gmxana/gmx_ana.h"
-#include "gromacs/utility/filestream.h"
-#include "gromacs/utility/path.h"
 
 #include "testutils/cmdlinetest.h"
-#include "testutils/integrationtests.h"
-#include "testutils/refdata.h"
+#include "testutils/stdiohelper.h"
 #include "testutils/testasserts.h"
+#include "testutils/textblockmatchers.h"
 #include "testutils/xvgtest.h"
 
 namespace gmx
@@ -65,34 +63,22 @@ namespace test
 namespace
 {
 
-class DhdlTest : public IntegrationTestFixture
+class DhdlTest : public CommandLineTestBase
 {
     public:
-        DhdlTest() : data_(), checker_(data_.rootChecker()) {}
-
         void runTest()
         {
-            CommandLine caller;
-            caller.append("energy");
-
-            caller.addOption("-s", fileManager_.getInputFilePath("dhdl.tpr"));
-            caller.addOption("-f", fileManager_.getInputFilePath("dhdl.edr"));
+            auto &cmdline = commandLine();
+            cmdline.append("energy");
 
-            std::string xvgFileName = fileManager_.getTemporaryFilePath("dhdl.xvg");
-            caller.addOption("-odh", xvgFileName);
+            setInputFile("-s", "dhdl.tpr");
+            setInputFile("-f", "dhdl.edr");
+            setOutputFile("-odh", "dhdl.xvg", XvgMatch());
 
-            EXPECT_EQ(0, gmx_energy(caller.argc(), caller.argv()));
+            ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv()));
 
-            EXPECT_TRUE(Path::exists(xvgFileName));
-            TextInputFile    xvgFile(xvgFileName);
-            XvgMatchSettings settings;
-            auto             outputFilesChecker = checker_.checkCompound("OutputFiles", "Files");
-            auto             fileChecker        = outputFilesChecker.checkCompound("File", "-o");
-            checkXvgFile(&xvgFile, &fileChecker, settings);
+            checkOutputFiles();
         }
-
-        TestReferenceData    data_;
-        TestReferenceChecker checker_;
 };
 
 TEST_F(DhdlTest, ExtractDhdl)
@@ -100,34 +86,23 @@ TEST_F(DhdlTest, ExtractDhdl)
     runTest();
 }
 
-class EnergyTest : public IntegrationTestFixture
+class EnergyTest : public CommandLineTestBase
 {
     public:
-        EnergyTest() : data_(), checker_(data_.rootChecker()) {}
-
         void runTest(const char *stringForStdin)
         {
-            CommandLine caller;
-            caller.append("energy");
+            auto &cmdline = commandLine();
+            cmdline.append("energy");
 
-            caller.addOption("-f", fileManager_.getInputFilePath("ener.edr"));
+            setInputFile("-f", "ener.edr");
+            setOutputFile("-o", "energy.xvg", XvgMatch());
 
-            std::string xvgFileName = fileManager_.getTemporaryFilePath("energy.xvg");
-            caller.addOption("-o", xvgFileName);
+            StdioTestHelper stdioHelper(&fileManager());
+            stdioHelper.redirectStringToStdin(stringForStdin);
+            ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv()));
 
-            redirectStringToStdin(stringForStdin);
-            EXPECT_EQ(0, gmx_energy(caller.argc(), caller.argv()));
-
-            EXPECT_TRUE(Path::exists(xvgFileName));
-            TextInputFile    xvgFile(xvgFileName);
-            XvgMatchSettings settings;
-            auto             outputFilesChecker = checker_.checkCompound("OutputFiles", "Files");
-            auto             fileChecker        = outputFilesChecker.checkCompound("File", "-o");
-            checkXvgFile(&xvgFile, &fileChecker, settings);
+            checkOutputFiles();
         }
-
-        TestReferenceData    data_;
-        TestReferenceChecker checker_;
 };
 
 TEST_F(EnergyTest, ExtractEnergy)
@@ -145,86 +120,52 @@ TEST_F(EnergyTest, ExtractEnergyMixed)
     runTest("Pressu\n7\nbox-z\nvol\n");
 }
 
-class ViscosityTest : public IntegrationTestFixture
+class ViscosityTest : public CommandLineTestBase
 {
     public:
-        ViscosityTest() : data_(), checker_(data_.rootChecker()) {}
-
-        std::string addFileToTest(CommandLine *caller,
-                                  const char  *optionName,
-                                  const char  *outputFileName)
-        {
-            std::string xvgFileName = fileManager_.getTemporaryFilePath(outputFileName);
-            caller->addOption(optionName, xvgFileName);
-            return xvgFileName;
-        }
-
-        void runTest(const char *optionName,
-                     const char *outputFileName)
+        void runTest()
         {
-            CommandLine caller;
-            caller.append("energy");
-
-            caller.addOption("-f", fileManager_.getInputFilePath("ener.edr"));
-            caller.addOption("-vis", fileManager_.getTemporaryFilePath("visco.xvg"));
-
-            std::string xvgFileNameToTest;
+            auto &cmdline = commandLine();
+            setInputFile("-f", "ener.edr");
+            setOutputFile("-vis", "visco.xvg", NoTextMatch());
+            setOutputFile("-o", "energy.xvg", NoTextMatch());
 
             /* -vis can write a lot of non-conditional output files,
                 so we use temporary paths to clean up files that are
                 not the ones being tested in this test */
-            if (0 == std::strcmp(optionName, "-evisco"))
+            if (!cmdline.contains("-evisco"))
             {
-                xvgFileNameToTest = addFileToTest(&caller, optionName, outputFileName);
+                setOutputFile("-evisco", "evisco.xvg", NoTextMatch());
             }
-            else
+            if (!cmdline.contains("-eviscoi"))
             {
-                caller.addOption("-evisco", fileManager_.getTemporaryFilePath("evisco"));
+                setOutputFile("-eviscoi", "eviscoi.xvg", NoTextMatch());
             }
-            if (0 == std::strcmp(optionName, "-eviscoi"))
+            if (!cmdline.contains("-corr"))
             {
-                xvgFileNameToTest = addFileToTest(&caller, optionName, outputFileName);
-            }
-            else
-            {
-                caller.addOption("-eviscoi", fileManager_.getTemporaryFilePath("eviscoi"));
-            }
-            if (0 == std::strcmp(optionName, "-corr"))
-            {
-                xvgFileNameToTest = addFileToTest(&caller, optionName, outputFileName);
-            }
-            else
-            {
-                caller.addOption("-corr", fileManager_.getTemporaryFilePath("enecorr"));
+                setOutputFile("-corr", "corr.xvg", NoTextMatch());
             }
 
-            caller.addOption("-o", fileManager_.getTemporaryFilePath("energy"));
+            ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv()));
 
-            EXPECT_EQ(0, gmx_energy(caller.argc(), caller.argv()));
-
-            EXPECT_TRUE(Path::exists(xvgFileNameToTest));
-            TextInputFile    xvgFile(xvgFileNameToTest);
-            XvgMatchSettings settings;
-            settings.tolerance = relativeToleranceAsFloatingPoint(1e-4, 1e-5);
-            auto             outputFilesChecker = checker_.checkCompound("OutputFiles", "Files");
-            auto             fileChecker        = outputFilesChecker.checkCompound("File", "-o");
-            checkXvgFile(&xvgFile, &fileChecker, settings);
+            checkOutputFiles();
         }
-
-        TestReferenceData    data_;
-        TestReferenceChecker checker_;
 };
 
 TEST_F(ViscosityTest, EinsteinViscosity)
 {
-    runTest("-evisco", "evisco.xvg");
+    auto tolerance = relativeToleranceAsFloatingPoint(1e-4, 1e-5);
+    setOutputFile("-evisco", "evisco.xvg", XvgMatch().tolerance(tolerance));
+    runTest();
 }
 
 TEST_F(ViscosityTest, EinsteinViscosityIntegral)
 {
-    runTest("-eviscoi", "eviscoi.xvg");
+    auto tolerance = relativeToleranceAsFloatingPoint(1e-4, 1e-5);
+    setOutputFile("-eviscoi", "eviscoi.xvg", XvgMatch().tolerance(tolerance));
+    runTest();
 }
 
 } // namespace
-} // namespace
-} // namespace
+} // namespace test
+} // namespace gmx
index 994a0b6aa454d809ef269291562cd7f06a8da69f..f75bef2f2ff1f3ebf4f32e1af044a97d456883cd 100644 (file)
@@ -2,7 +2,7 @@
 <?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
 <ReferenceData>
   <OutputFiles Name="Files">
-    <File Name="-o">
+    <File Name="-odh">
       <XvgLegend Name="Legend">
         <String Name="XvgLegend"><![CDATA[
 title "dH/d\xl\f{} and \xD\f{}H"
index e25077a5f75fe948e83f2e3f676fafbe64eecff4..59131e9769c8fe9f558b243ea77e0011fca2e167 100644 (file)
@@ -2,7 +2,7 @@
 <?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
 <ReferenceData>
   <OutputFiles Name="Files">
-    <File Name="-o">
+    <File Name="-evisco">
       <XvgLegend Name="Legend">
         <String Name="XvgLegend"><![CDATA[
 title "Shear viscosity using Einstein relation"
@@ -126,5 +126,9 @@ TYPE xy
         </Sequence>
       </XvgData>
     </File>
+    <File Name="-vis"></File>
+    <File Name="-o"></File>
+    <File Name="-eviscoi"></File>
+    <File Name="-corr"></File>
   </OutputFiles>
 </ReferenceData>
index 9d19a3006d83cb6f31ba8e779cef114c7805558e..ee97d8d189ebfd0ebd145247cb17c632053d3706 100644 (file)
@@ -2,7 +2,7 @@
 <?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
 <ReferenceData>
   <OutputFiles Name="Files">
-    <File Name="-o">
+    <File Name="-eviscoi">
       <XvgLegend Name="Legend">
         <String Name="XvgLegend"><![CDATA[
 title "Shear viscosity integral"
@@ -126,5 +126,9 @@ TYPE xy
         </Sequence>
       </XvgData>
     </File>
+    <File Name="-vis"></File>
+    <File Name="-o"></File>
+    <File Name="-evisco"></File>
+    <File Name="-corr"></File>
   </OutputFiles>
 </ReferenceData>
index 93bff45d1ad7afa278c498c53bd342f99860f448..4163bfa3170672b14a3a42238dc66a205eef9916 100644 (file)
 #include "gromacs/gmxana/gmx_ana.h"
 
 #include "testutils/cmdlinetest.h"
-#include "testutils/integrationtests.h"
+#include "testutils/stdiohelper.h"
+#include "testutils/textblockmatchers.h"
 
 namespace
 {
 
-class GmxTraj : public gmx::test::IntegrationTestFixture,
+class GmxTraj : public gmx::test::CommandLineTestBase,
                 public ::testing::WithParamInterface<const char *>
 {
     public:
-        GmxTraj() : groFileName(fileManager_.getInputFilePath("spc2.gro")),
-                    xvgFileName(fileManager_.getTemporaryFilePath("spc2.xvg"))
+        void runTest(const char *fileName)
         {
-        }
-
-        int runTest(const char *fileName)
-        {
-            gmx::test::CommandLine caller;
-            caller.append("traj");
+            auto &cmdline = commandLine();
+            cmdline.append("traj");
+            setInputFile("-s", "spc2.gro");
+            setInputFile("-f", fileName);
+            setOutputFile("-ox", "spc2.xvg", gmx::test::NoTextMatch());
 
-            caller.addOption("-s",  groFileName);
-            caller.addOption("-ox", xvgFileName);
+            gmx::test::StdioTestHelper stdioHelper(&fileManager());
+            stdioHelper.redirectStringToStdin("0\n");
 
-            std::string inputTrajectoryFileName = fileManager_.getInputFilePath(fileName);
-            caller.addOption("-f", inputTrajectoryFileName);
-
-            redirectStringToStdin("0\n");
-
-            return gmx_traj(caller.argc(), caller.argv());
+            ASSERT_EQ(0, gmx_traj(cmdline.argc(), cmdline.argv()));
         }
-
-        std::string groFileName;
-        std::string xvgFileName;
 };
 
 /* TODO These tests are actually not very effective, because gmx-traj
index 4d82156c7f706229e563d2706759fe56ecb4036b..eccd8ccaa47a6dea7a777e89ad45b187f6c19787 100644 (file)
 #include "gromacs/gmxana/gmx_ana.h"
 
 #include "testutils/cmdlinetest.h"
-#include "testutils/integrationtests.h"
+#include "testutils/stdiohelper.h"
+#include "testutils/textblockmatchers.h"
 
 namespace
 {
 
-class TrjconvWithIndexGroupSubset : public gmx::test::IntegrationTestFixture,
+class TrjconvWithIndexGroupSubset : public gmx::test::CommandLineTestBase,
                                     public ::testing::WithParamInterface<const char *>
 {
     public:
-        int runTest(const char *fileName)
+        void runTest(const char *fileName)
         {
-            gmx::test::CommandLine caller;
-            caller.append("trjconv");
+            auto &cmdline = commandLine();
+            cmdline.append("trjconv");
 
-            caller.addOption("-s", fileManager_.getInputFilePath("spc2.gro"));
+            setInputFile("-s", "spc2.gro");
+            setInputFile("-f", fileName);
+            setInputFile("-n", "spc2.ndx");
+            setOutputFile("-o", "spc-traj.tng", gmx::test::NoTextMatch());
 
-            std::string inputTrajectoryFileName = fileManager_.getInputFilePath(fileName);
-            caller.addOption("-f", inputTrajectoryFileName);
-
-            std::string ndxFileName = fileManager_.getInputFilePath("spc2.ndx");
-            caller.addOption("-n", ndxFileName);
-
-            caller.addOption("-o", fileManager_.getTemporaryFilePath("spc-traj.tng"));
-
-            redirectStringToStdin("SecondWaterMolecule\n");
+            gmx::test::StdioTestHelper stdioHelper(&fileManager());
+            stdioHelper.redirectStringToStdin("SecondWaterMolecule\n");
 
             /* TODO Ideally, we would then check that the output file
                has only 3 of the 6 atoms (which it does), but the
                infrastructure for doing that automatically is still
                being built. This would also fix the TODO below. */
-            return gmx_trjconv(caller.argc(), caller.argv());
+            ASSERT_EQ(0, gmx_trjconv(cmdline.argc(), cmdline.argv()));
         }
 };
 /* TODO These tests are actually not very effective, because trjconv
index 7f853e817c9e113e848e79cd9a8bbcb4a5d0c379..471d32887cdf02e2841d3b7e68a8c780f053ec36 100644 (file)
@@ -54,7 +54,6 @@
 #include "gromacs/utility/path.h"
 
 #include "testutils/cmdlinetest.h"
-#include "testutils/integrationtests.h"
 #include "testutils/refdata.h"
 #include "testutils/testasserts.h"
 #include "testutils/xvgtest.h"
index b3e46c18740e958e7832dd56a65a313ddd2ef942..3ab59a3b74cfebf65784edec717d8bfd9717fd20 100644 (file)
@@ -58,8 +58,8 @@
 #include "programs/mdrun/mdrun_main.h"
 
 #include "testutils/cmdlinetest.h"
-#include "testutils/integrationtests.h"
 #include "testutils/mpitest.h"
+#include "testutils/testfilemanager.h"
 #include "testutils/testoptions.h"
 
 namespace gmx
@@ -91,18 +91,18 @@ GMX_TEST_OPTIONS(MdrunTestOptions, options)
 
 }
 
-SimulationRunner::SimulationRunner(IntegrationTestFixture *fixture) :
-    fixture_(fixture),
+SimulationRunner::SimulationRunner(TestFileManager *fileManager) :
     topFileName_(),
     groFileName_(),
     fullPrecisionTrajectoryFileName_(),
     ndxFileName_(),
-    mdpInputFileName_(fixture_->fileManager_.getTemporaryFilePath("input.mdp")),
-    mdpOutputFileName_(fixture_->fileManager_.getTemporaryFilePath("output.mdp")),
-    tprFileName_(fixture_->fileManager_.getTemporaryFilePath(".tpr")),
-    logFileName_(fixture_->fileManager_.getTemporaryFilePath(".log")),
-    edrFileName_(fixture_->fileManager_.getTemporaryFilePath(".edr")),
-    nsteps_(-2)
+    mdpInputFileName_(fileManager->getTemporaryFilePath("input.mdp")),
+    mdpOutputFileName_(fileManager->getTemporaryFilePath("output.mdp")),
+    tprFileName_(fileManager->getTemporaryFilePath(".tpr")),
+    logFileName_(fileManager->getTemporaryFilePath(".log")),
+    edrFileName_(fileManager->getTemporaryFilePath(".edr")),
+    nsteps_(-2),
+    fileManager_(*fileManager)
 {
 #if GMX_LIB_MPI
     GMX_RELEASE_ASSERT(gmx_mpi_initialized(), "MPI system not initialized for mdrun tests");
@@ -144,15 +144,15 @@ SimulationRunner::useStringAsNdxFile(const char *ndxString)
 void
 SimulationRunner::useTopGroAndNdxFromDatabase(const char *name)
 {
-    topFileName_ = fixture_->fileManager_.getInputFilePath((std::string(name) + ".top").c_str());
-    groFileName_ = fixture_->fileManager_.getInputFilePath((std::string(name) + ".gro").c_str());
-    ndxFileName_ = fixture_->fileManager_.getInputFilePath((std::string(name) + ".ndx").c_str());
+    topFileName_ = fileManager_.getInputFilePath((std::string(name) + ".top").c_str());
+    groFileName_ = fileManager_.getInputFilePath((std::string(name) + ".gro").c_str());
+    ndxFileName_ = fileManager_.getInputFilePath((std::string(name) + ".ndx").c_str());
 }
 
 void
 SimulationRunner::useGroFromDatabase(const char *name)
 {
-    groFileName_ = fixture_->fileManager_.getInputFilePath((std::string(name) + ".gro").c_str());
+    groFileName_ = fileManager_.getInputFilePath((std::string(name) + ".gro").c_str());
 }
 
 int
@@ -225,7 +225,7 @@ SimulationRunner::callMdrun(const CommandLine &callerRef)
     caller.addOption("-o", fullPrecisionTrajectoryFileName_);
     caller.addOption("-x", reducedPrecisionTrajectoryFileName_);
 
-    caller.addOption("-deffnm", fixture_->fileManager_.getTemporaryFilePath("state"));
+    caller.addOption("-deffnm", fileManager_.getTemporaryFilePath("state"));
 
     if (nsteps_ > -2)
     {
@@ -289,7 +289,7 @@ MdrunTestFixtureBase::~MdrunTestFixtureBase()
 
 // ====
 
-MdrunTestFixture::MdrunTestFixture() : runner_(this)
+MdrunTestFixture::MdrunTestFixture() : runner_(&fileManager_)
 {
 }
 
index a7a608d426d47782e54fa9697f1bf5aa3c213844..c7649b6d47befc253b6bc30d99d5d02441e1bda9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 
 #include <gtest/gtest.h>
 
+#include "gromacs/utility/classhelpers.h"
+
 #include "testutils/cmdlinetest.h"
-#include "testutils/integrationtests.h"
+#include "testutils/testfilemanager.h"
 
 namespace gmx
 {
-
 namespace test
 {
 
@@ -86,9 +87,8 @@ namespace test
 class SimulationRunner
 {
     public:
-        /*! \brief Constructor, which establishes the fixture that
-         * will own each object */
-        explicit SimulationRunner(IntegrationTestFixture *fixture_);
+        //! Initializes a runner with given manager for temporary files.
+        explicit SimulationRunner(TestFileManager *fileManager);
 
         //! Use an empty .mdp file as input to grompp
         void useEmptyMdpFile();
@@ -116,10 +116,6 @@ class SimulationRunner
          * with default command line */
         int callMdrun();
 
-    private:
-        //! Provides access to the test fixture, e.g. for the TestFileManager
-        IntegrationTestFixture *fixture_;
-    public:
         //@{
         /*! \name Names for frequently used grompp and mdrun output files
          *
@@ -146,6 +142,11 @@ class SimulationRunner
         std::string swapFileName_;
         int         nsteps_;
         //@}
+
+    private:
+        TestFileManager &fileManager_;
+
+        GMX_DISALLOW_COPY_AND_ASSIGN(SimulationRunner);
 };
 
 /*! \internal
@@ -172,7 +173,7 @@ class SimulationRunner
  *
  * \ingroup module_mdrun_integration_tests
  */
-class MdrunTestFixtureBase : public IntegrationTestFixture
+class MdrunTestFixtureBase : public ::testing::Test
 {
     public:
         MdrunTestFixtureBase();
@@ -187,12 +188,14 @@ class MdrunTestFixtureBase : public IntegrationTestFixture
  *
  * \ingroup module_mdrun_integration_tests
  */
-class MdrunTestFixture : public IntegrationTestFixture
+class MdrunTestFixture : public ::testing::Test
 {
     public:
         MdrunTestFixture();
         virtual ~MdrunTestFixture();
 
+        //! Manages temporary files during the test.
+        TestFileManager  fileManager_;
         //! Helper object to manage the preparation for and call of mdrun
         SimulationRunner runner_;
 };
index 0f1afabcebae4ec4b9d9835c97eca874ef83e15a..e48e716e5560fc2966e51e2448ff5a377e3db845 100644 (file)
@@ -41,13 +41,13 @@ include_directories(BEFORE SYSTEM ${GMOCK_INCLUDE_DIRS})
 set(TESTUTILS_SOURCES
     cmdlinetest.cpp
     conftest.cpp
-    integrationtests.cpp
     interactivetest.cpp
     loggertest.cpp
     mpi-printer.cpp
     mpitest.cpp
     refdata.cpp
     refdata-xml.cpp
+    stdiohelper.cpp
     stringtest.cpp
     testasserts.cpp
     testfilemanager.cpp
index ca6804b570259c399abfd93d5c00b755e971ddf0..0bc6376dc8b0c7f0b2469c4ff699a89f68ead0b2 100644 (file)
@@ -227,6 +227,18 @@ std::string CommandLine::toString() const
     return CommandLineProgramContext(argc(), argv()).commandLine();
 }
 
+bool CommandLine::contains(const char *name) const
+{
+    for (int i = 0; i < impl_->argc_; ++i)
+    {
+        if (std::strcmp(arg(i), name) == 0)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 /********************************************************************
  * CommandLineTestHelper::Impl
  */
index 7bdeed3e136e4b4c61f1b8fef283d7e5d793e855..589cdc22150325155f43b90bd786097bb75cc34c 100644 (file)
@@ -183,6 +183,9 @@ class CommandLine
         //! Returns the command line formatted as a single string.
         std::string toString() const;
 
+        //! Whether the command line contains the given option.
+        bool contains(const char *name) const;
+
     private:
         class Impl;
 
similarity index 87%
rename from src/testutils/integrationtests.cpp
rename to src/testutils/stdiohelper.cpp
index 41582553f30c013abb56f07fe5763c4e0537fc67..60b95cf6eb43049b16224f8e7a389b158475aa59 100644 (file)
  */
 /*! \internal \file
  * \brief
- * Implements classes in integrationtests.h.
+ * Implements classes in stdiohelper.h.
  *
  * \author Mark Abraham <mark.j.abraham@gmail.com>
  * \ingroup module_testutils
  */
 #include "gmxpre.h"
 
-#include "integrationtests.h"
+#include "stdiohelper.h"
 
-#include <stdio.h>
+#include <cerrno>
+#include <cstdio>
 
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/textwriter.h"
 
+#include "testutils/testfilemanager.h"
+
 namespace gmx
 {
 namespace test
 {
 
 /********************************************************************
- * IntegrationTestFixture
+ * StdioTestHelper
  */
 
-IntegrationTestFixture::IntegrationTestFixture()
-{
-}
-
-IntegrationTestFixture::~IntegrationTestFixture()
-{
-}
-
 void
-IntegrationTestFixture::redirectStringToStdin(const char* theString)
+StdioTestHelper::redirectStringToStdin(const char *theString)
 {
-    std::string fakeStdin("fake-stdin");
+    const std::string fakeStdin = fileManager_.getTemporaryFilePath(".stdin");
     gmx::TextWriter::writeFileFromString(fakeStdin, theString);
     if (nullptr == std::freopen(fakeStdin.c_str(), "r", stdin))
     {
similarity index 62%
rename from src/testutils/integrationtests.h
rename to src/testutils/stdiohelper.h
index 426f5c08c3143815d464c3add46ef5610e626400..c111476ce44e7d9b7e81ca189650f1ba04dfd2d1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2017, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
  */
 /*! \libinternal \file
  * \brief
- * Declares test fixture for integration tests
+ * Declares gmx::test::StdioTestHelper.
  *
  * \author Mark Abraham <mark.j.abraham@gmail.com>
  * \inlibraryapi
  * \ingroup module_testutils
  */
-#ifndef GMX_INTEGRATION_TESTS_MODULETEST_H
-#define GMX_INTEGRATION_TESTS_MODULETEST_H
+#ifndef GMX_TESTUTILS_STDIOHELPER_H
+#define GMX_TESTUTILS_STDIOHELPER_H
 
-#include <gtest/gtest.h>
-
-#include "testutils/testfilemanager.h"
+#include "gromacs/utility/classhelpers.h"
 
 namespace gmx
 {
-
 namespace test
 {
 
+class TestFileManager;
+
 /*! \libinternal \brief
- * Test fixture for integration tests.
+ * Helper class for tests where code reads directly from `stdin`.
  *
  * Any method in this class may throw std::bad_alloc if out of memory.
  *
  * \inlibraryapi
  * \ingroup module_testutils
  */
-class IntegrationTestFixture : public ::testing::Test
+class StdioTestHelper
 {
-    protected:
-        IntegrationTestFixture();
-        virtual ~IntegrationTestFixture();
+    public:
+        //! Creates a helper using the given file manager.
+        explicit StdioTestHelper(TestFileManager *fileManager)
+            : fileManager_(*fileManager)
+        {
+        }
 
         /*! \brief Accepts a string as input, writes it to a temporary
          * file and then reopens stdin to read the contents of that
@@ -73,29 +75,12 @@ class IntegrationTestFixture : public ::testing::Test
          *
          * \throws FileIOError  when the freopen() fails
          */
-        void redirectStringToStdin(const chartheString);
+        void redirectStringToStdin(const char *theString);
 
-        /*! \brief Discards stdout while running a test
-         *
-         * \todo Implement this when the output routines are
-         * sufficiently modular to permit it to work. */
-        void redirectStdoutToDevNull();
-        /*! \brief Discards stderr while running a test
-         *
-         * \todo Implement this when the output routines are
-         * sufficiently modular to permit it to work. */
-        void redirectStderrToDevNull();
-
-        /* TEST_F() constructs derived classes, and those classes and
-         * their member objects might need to access implementation
-         * details, so we cannot use the private access specifer
-         * here. */
-    public:
+    private:
+        TestFileManager &fileManager_;
 
-        /*! \brief Object that manages finding input files, writing
-         * temporary output files and cleaning up files.
-         */
-        ::gmx::test::TestFileManager fileManager_;
+        GMX_DISALLOW_COPY_AND_ASSIGN(StdioTestHelper);
 };
 
 } // namespace test
index 184ebfbfdd3b3f95cef0444f2eb9ab9804394736..eb111256d0d3adc34e59f78658b75f38d410da94 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015, by the GROMACS development team, led by
+ * Copyright (c) 2015,2017, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
  *    See \ref page_refdata for more details.
  *  - gmx::test::CommandLine and related classes (in cmdlinetest.h) provide
  *    utilities for constructing command line argument arrays for use in tests
- *    that invoke actual commands.
+ *    that invoke actual commands.  The same header also provides
+ *    gmx::test::CommandLineTestHelper and gmx::test::CommandLineTestBase
+ *    for easily creating tests that execute essentially full command-line
+ *    programs, including checking the output files produced.
  *  - gmx::test::StringTestBase provides a test fixture for tests that need to
  *    test long strings for correctness.
- *  - gmx::test::IntegrationTestFixture provides a test fixture for tests that
- *    execute legacy code where `stdin` reading etc. cannot be easily mocked.
+ *  - gmx::test::StdioTestHelper provides a helper class for tests that need to
+ *    execute legacy code where `stdin` reading cannot be easily mocked.
  *
  * Additionally, testinit.h and mpi-printer.h, and their corresponding source
  * files, provide functionality that is not visible on the API level: they