- set up
- add new tests
- explain to the other developers
- ?
- profit
Our unit tests are part of our project's Visual Studio solution file. Each unit test's project is setup to run the unit test as a post-build step. So far, it's caught a number of 'simple' fixes that broke some.
I've also setup a Hudson server to automatically build our project... But, I didn't want it to fail the build if the tests failed. And, I wanted to collect the XML reports when it's built from the continuous integration server.
So, rather than always just blindly calling UnitTest::RunAllTests() in the unit tests's main() function, I made a utility library that'll look at an environment variable to determine how it should run the tests.
In the unit tests's main() :
int main(int, char const *[])
{
return myUnitTest_runAllTests("my_test");
}
The utility function:
#include "cstdlib"
#include "fstream"
#include "iostream"
#include "boost/filesystem.hpp"
#include "UnitTest++/UnitTest++.h"
#include "UnitTest++/XmlTestReporter.h"
namespace bfs = boost::filesystem;
struct True
{
bool operator()(const UnitTest::Test* const) const
{
return true;
}
};
DLLExport int myUnitTest_runAllTests(const char* const testName)
{
char* xmlDir = 0;
size_t len;
errno_t err = _dupenv_s(&xmlDir,&len,"UNITTEST_XML_DIR");
if (err || len == 0)
{
// env var not set, just run the test w/ standard mechanism
return UnitTest::RunAllTests();
}
else
{
bfs::path p = bfs::path(xmlDir);
// free memory from _dupenv_s
free(xmlDir);
// if necessary, create output directory
if (! bfs::exists(p) || ! bfs::is_directory(p))
{
if (!bfs::create_directories(p))
{
std::cerr << "Problem creating directory " << p << std::endl;
return -1;
}
}
std::string fname(testName);
fname += ".xml";
// use / operator to append filename onto path
bfs::path fpath = p / fname;
std::ofstream f(fpath.file_string().c_str());
UnitTest::XmlTestReporter reporter(f);
UnitTest::TestRunner runner(reporter);
// if we're outputting to XML, don't return failure as return code
// this way tests can fail without it making the automated build think the build failed.
int ret = runner.RunTestsIf(UnitTest::Test::GetTestList(),NULL,True(),0);
return 0;
}
}
And then you just point Hudson's xUnit plugin at the generated reports. Came together suprisingly easy
No comments:
Post a Comment