我正在编写一组算法来创建一个简单的单元测试框架。类 UnitTest
被实例化为一个字符串 strng
,该字符串描述了所进行的测试。数据类型在对象实例化时也被传递,这使得编译器知道正在传递哪些数据类型。下面是 main.cpp
文件和 unit_test.hpp
文件:
// main.cpp file
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include "unit_test.hpp"
int main(int argc, const char * argv[]) {
std::vector<int> array_one = {1, 2, 3, 4};
std::vector<float> array_two = {0.99, 1.99, 2.99, 3.99};
std::string c ("Vector Test");
UnitTest<int, float> q(c);
double unc = 0.1;
q.vectors_are_close(array_two, array_four, unc);
return 0;
}
// unit_test.hpp file
#ifndef unit_test_hpp
#define unit_test_hpp
#endif /* unit_test_hpp */
#include <string>
#include <typeinfo>
#include <iostream>
#include <cmath>
template <class type1, class type2> class UnitTest
{
public:
unsigned long remain;
std::string str;
UnitTest(std::string strng) {
str = strng;
remain = 50 - str.length();
};
void vectors_are_close(std::vector<type1>& i, std::vector<type2>& j, double k);
// ----------------------------------------------------------------
private:
void is_close(type1& i, type2& j, double k);
};
template <class type1, class type2> void UnitTest<type1, type2>::
vectors_are_close(std::vector<type1>& i, std::vector<type2>& j, double k)
{
if (i.size() != j.size())
{
std::cout << str + std::string(remain, '.') +
std::string("FAILED") << std::endl;
}
else
{
try
{
for (int a = 0; a < i.size(); a++) {
is_close(i[a], j[a], k);
}
std::cout << str + std::string(remain, '.') +
std::string("PASSED") << std::endl;
}
catch (const char* msg)
{
std::cout << str + std::string(remain, '.') +
std::string("FAILED") << std::endl;
}
}
}
template <class type1, class type2> void UnitTest<type1, type2>::
is_close(type1& i, type2& j, double k)
{
double percent_diff = abs((j - i) / ((i + j) / 2.0));
if (percent_diff > k)
{
throw "Number not in Tolerance";
}
}
上面展示的成员函数遍历向量容器,以确保每个感应器中的数据与第二个向量在一定公差范围内匹配。虽然代码按照原样工作得很好,但它要求用户每次想用不同的数据类型进行单元测试时重新实例化类。
在这种情况下,该类使用
UnitTest<int, float>
进行实例化。但在另一个实例中,它可能使用UnitTest<float, double>
进行实例化。这种方法没有问题,但似乎更优雅的方式是只用
UnitTest<>
实例化一次类,然后使vectors_are_close()
函数接受不同的数据类型。是否有某种方法可以促进这种行为?