Is it appropriate to use the Assert() function in a Visual Studio C test project for bugs WITHIN the test project? The Visual Studio test projects for C use namespace Microsoft::VisualStudio::CppUnitTestFramework
For instance, I have a function that builds a vector full of random char value strings, how should I handle the case in which the user of the class uses it with the wrong arguments? Would it be appropriate to add a Assert::IsTrue(myVec.size() > 0) and then have the possibility of the test project it's self cause a test to fail?
An example:
/// <summary>
/// Returns a vector of std::string with randomized content.
/// count is the number of entries in the returned vector, length is the max length of the strings.
/// </summary>
/// <returns> a vector of std::string with randomized content. Empty vector on error. </returns>
std::vector<std::string> BuildRandomStringVector(const int count, const int length, const int minLength = 3)
{
//arg error checking, returns empty vector as per description
if (minLength >= length || (length <= 0) || (count <=0) || (minLength <=0))
{
return std::vector<std::string>();
}
//Test all kinds of random character possibilities.
std::uniform_int_distribution<int> distCharPossibility
(std::numeric_limits<char>::min(),
std::numeric_limits<char>::max());
std::uniform_int_distribution<int> distLengthPossibility(minLength, length);
std::random_device rd;
std::mt19937 stringGenerator(rd());
std::vector<std::string> ret;
//the distribution uses the generator engine to get the value
for (int i = 0; i < count; i )
{
const int tLength = distLengthPossibility(stringGenerator);
std::string currentBuiltString = "";
for (int j = 0; j < tLength; j )
{
char currentBuiltChar = distCharPossibility(stringGenerator);
currentBuiltString = currentBuiltChar;
}
ret.push_back(currentBuiltString);
}
return ret;
}
CodePudding user response:
I would not reccommend using any form of assertions in tests. The rationale is as follows. Assertion is a diagnostic code that is normally executed in "Debug" mode and skipped in "Release". You don't intend to run tests in two different modes, do you? And you are not going to test tests. Verification of the condition in your code should not have any measurable impact on the test execution time. In such a case prefer reliability: always perform the test sanity, for you can certainly afford a few microseconds longer tests. If violation of the condition should be considered an error, don't return an empty vector: will you be checking its size at the caller each time? Throw an exception. In short, rather then an assertion, use std::invalid_argument
or something similar. Fire and forget.
From another viewpoint: in principle we could embed a lot of self-testing in production code, but we prefer external tests so that the production code is really slim and fast. This concern is not that important for tests: if you're afraid they can be used improperly, test the correctness of their usage explicitly and unconditionally. Use the common sense to tell when the overhead is still acceptable.