C++支持参数化功能以实现测试目的吗?

C++支持参数化功能以实现测试目的吗?,c++,C++,我有一个很长的单元测试代码片段,我想为两个函数运行它。我想知道是否有一种方法可以做到这一点,而无需复制和粘贴代码,只需更改函数名? 假设测试代码看起来像 int main(){ output1 = function(input1); assert output1 == answer1; output2 = function(input2); assert output2 == answer2; output3 = function(input3);

我有一个很长的单元测试代码片段,我想为两个函数运行它。我想知道是否有一种方法可以做到这一点,而无需复制和粘贴代码,只需更改函数名? 假设测试代码看起来像

int main(){
    output1 = function(input1);
    assert output1 == answer1;
    output2 = function(input2);
    assert output2 == answer2;
    output3 = function(input3);
    assert output3 == answer3;
    ......
    outputN = function(inputN);
    assert outputN == answerN;
}

现在假设我有两个函数func1和func2。我想对func1和func2运行完全相同的测试。我想知道在C++中有没有一种很好的方法,而不涉及一些测试框架?提前感谢您的帮助。

C++支持将参数传递给函数

可以将函数传递给函数。为了简单起见,我假设您要测试的所有函数都具有相同的签名。为了避免函数指针的冗长语法,我将使用一个模板:

template <typename F>
void test_function(F f, std::vector<input_type> input,std::vector<output_type> expected) {
      for (size_t i = 0; i < input.size(); ++i) {
          assert( f(input[i]) == expected[i]);
      }
}

int main() {
    test_function( func1, {1,2,3},{2,3,4} );
    test_function( func2, {1,2,3},{6,7,8} );
}
template <typename F, typename R, typename Args...>
void test_func(F f, R&& r, Args&&... args) {

    auto output = f(std::forward<Args>(args)...);
    assert(output == std::forward<R>(r));

}

PS:根据我自己的经验,我可以告诉你,在手写测试设备上投入太多的工作是不值得的。您会发现自己需要测试框架提供的越来越多的特性,例如记录测试报告。是我可以推荐的。

C++支持将参数传递给函数

可以将函数传递给函数。为了简单起见,我假设您要测试的所有函数都具有相同的签名。为了避免函数指针的冗长语法,我将使用一个模板:

template <typename F>
void test_function(F f, std::vector<input_type> input,std::vector<output_type> expected) {
      for (size_t i = 0; i < input.size(); ++i) {
          assert( f(input[i]) == expected[i]);
      }
}

int main() {
    test_function( func1, {1,2,3},{2,3,4} );
    test_function( func2, {1,2,3},{6,7,8} );
}
template <typename F, typename R, typename Args...>
void test_func(F f, R&& r, Args&&... args) {

    auto output = f(std::forward<Args>(args)...);
    assert(output == std::forward<R>(r));

}

PS:根据我自己的经验,我可以告诉你,在手写测试设备上投入太多的工作是不值得的。您会发现自己需要测试框架提供的越来越多的特性,例如记录测试报告。是我可以推荐的。您可以制作一个函数模板:

template <typename F>
void test_function(F f, std::vector<input_type> input,std::vector<output_type> expected) {
      for (size_t i = 0; i < input.size(); ++i) {
          assert( f(input[i]) == expected[i]);
      }
}

int main() {
    test_function( func1, {1,2,3},{2,3,4} );
    test_function( func2, {1,2,3},{6,7,8} );
}
template <typename F, typename R, typename Args...>
void test_func(F f, R&& r, Args&&... args) {

    auto output = f(std::forward<Args>(args)...);
    assert(output == std::forward<R>(r));

}
其他解释:

传递参数和返回值,然后在使用传递给函数时保留它们

参数被声明为,这样您就可以通过任何类型传递多个参数


您可以制作一个函数模板:

template <typename F>
void test_function(F f, std::vector<input_type> input,std::vector<output_type> expected) {
      for (size_t i = 0; i < input.size(); ++i) {
          assert( f(input[i]) == expected[i]);
      }
}

int main() {
    test_function( func1, {1,2,3},{2,3,4} );
    test_function( func2, {1,2,3},{6,7,8} );
}
template <typename F, typename R, typename Args...>
void test_func(F f, R&& r, Args&&... args) {

    auto output = f(std::forward<Args>(args)...);
    assert(output == std::forward<R>(r));

}
其他解释:

传递参数和返回值,然后在使用传递给函数时保留它们

参数被声明为,这样您就可以通过任何类型传递多个参数


C方法的一个解决方案是使用函数指针。但我建议在c++11中使用lambda函数。您可以按如下方式使用:

template<typename Func>
void test(intput in, output out, Func func) {
    answer = func(in);
    assert(out == answer);

}

void main() {
    intput intput1;
    output output1;
    test(input1, output1, [&](intput in)->output{return func1(in)});
    test(input1, output1, [&](intput in)->output{return func2(in)});
}

毕竟,在使用g++编译器时,您应该添加compile para:-std=c++11。

c方法的解决方案是使用函数指针。但我建议在c++11中使用lambda函数。您可以按如下方式使用:

template<typename Func>
void test(intput in, output out, Func func) {
    answer = func(in);
    assert(out == answer);

}

void main() {
    intput intput1;
    output output1;
    test(input1, output1, [&](intput in)->output{return func1(in)});
    test(input1, output1, [&](intput in)->output{return func2(in)});
}

毕竟,在使用g++编译器时,您应该添加compile para:-std=c++11。

这是我的新观点,应该是编译。它内置于层中,因此您可以查看如何根据需要扩展每个层。它的工作原理与您的示例不同,存在输入数据的副本,并且没有针对输出的赋值操作。您应该考虑这些因素,并根据需要进行相应调整

// Example program
#include <functional>
#include <assert.h>
#include <vector>
#include <utility>

// function to test
int func1(int p_param)
{
  return p_param;
}

// function to test
int func2(int p_param)
{
  return p_param;
}

// Test runner base
template <typename TFunction, typename TInput, typename TOutput>
void test_runner(TFunction f, std::vector < std::pair<TInput, TOutput> > p_testparameters)
{
  for (auto pair : p_testparameters)
  {
    assert(f(pair.first) == pair.second);
  }
}

// Specific test 1
template <typename TFunction>
void test1(TFunction f)
{
  test_runner<TFunction, int, int>(f, { {1,1},{2,2},{3,3} });
}


// Specific test 2
template <typename TFunction>
void test2(TFunction f)
{
  test_runner<TFunction, int, int>(f, { {10,10},{20,20},{30,30} });
}

// Run tests for function
template <typename TFunction>
void runTests(TFunction f)
{
  test1(f);
  test2(f);
}

int main() {
  runTests(func1);
  runTests(func2);

  return 0;
}

这是我的新观点,应该可以编译。它内置于层中,因此您可以查看如何根据需要扩展每个层。它的工作原理与您的示例不同,存在输入数据的副本,并且没有针对输出的赋值操作。您应该考虑这些因素,并根据需要进行相应调整

// Example program
#include <functional>
#include <assert.h>
#include <vector>
#include <utility>

// function to test
int func1(int p_param)
{
  return p_param;
}

// function to test
int func2(int p_param)
{
  return p_param;
}

// Test runner base
template <typename TFunction, typename TInput, typename TOutput>
void test_runner(TFunction f, std::vector < std::pair<TInput, TOutput> > p_testparameters)
{
  for (auto pair : p_testparameters)
  {
    assert(f(pair.first) == pair.second);
  }
}

// Specific test 1
template <typename TFunction>
void test1(TFunction f)
{
  test_runner<TFunction, int, int>(f, { {1,1},{2,2},{3,3} });
}


// Specific test 2
template <typename TFunction>
void test2(TFunction f)
{
  test_runner<TFunction, int, int>(f, { {10,10},{20,20},{30,30} });
}

// Run tests for function
template <typename TFunction>
void runTests(TFunction f)
{
  test1(f);
  test2(f);
}

int main() {
  runTests(func1);
  runTests(func2);

  return 0;
}


您运行的不是同一个测试,而是input2和output2。这是完整的例子还是你有更复杂的问题?你的问题不太清楚。您应该包括func1和func2的测试应该是什么样子的。不管怎样,你有不同解释的答案,你可以选择。我想他是想说,现在main是func1的测试,现在他想以某种方式对func2进行完全相同的测试。@0xbaadf00d也是我的解释,但也可能是其他东西,我们能得到一些反馈吗?这些答案对你有用吗?你运行的不是同一个测试,而是输入2和输出2。这是完整的例子还是你有更复杂的问题?你的问题不太清楚。您应该包括func1和func2的测试应该是什么样子的。不管怎样,你有不同解释的答案,你可以选择。我想他是想说,现在main是func1的测试,现在他想以某种方式对func2进行完全相同的测试。@0xbaadf00d也是我的解释,但也可能是其他东西,我们能得到一些反馈吗?是否有任何答案对您有效?对一个问题的不同答案进行连续投票是否也被视为连续投票?我首先想知道我的答案是否有问题,但当我看到对这个问题的否决票时,我知道这里发生了什么…@idclev463035818我认为没有。连续投票是根据用户计算的,所以…我不在乎我的代表,但一个无辜的用户可能会觉得你的答案有问题+1因为这是唯一一个准确再现OPs的答案code@idclev463035818谢谢,我相信社区会做出正确的判断。最
模糊和激励是关于前5分钟的投票,但从长远来看,这些投票真的毫无意义。对一个问题的不同答案的连续投票也被视为连续投票?我首先想知道我的答案是否有问题,但当我看到对这个问题的否决票时,我知道这里发生了什么…@idclev463035818我认为没有。连续投票是根据用户计算的,所以…我不在乎我的代表,但一个无辜的用户可能会觉得你的答案有问题+1因为这是唯一一个准确再现OPs的答案code@idclev463035818谢谢,我相信社区会做出正确的判断。最模糊和激动的是前5分钟的投票,但从长远来看,这些投票真的毫无意义你可能想检查输入和预期的大小是否相同?@0xbaadf00d我不是故意这么做的,因为我认为这样的检查不应该放在调用堆栈的下面,而是在构建输入和输出时放在最上面,对函数调用中的值进行硬编码只是为了保持简单。您可能希望检查输入和预期值是否具有相同的大小?@0xbaadf00d我不是故意这样做的,因为我认为这样的检查不应该放在调用堆栈的下面,而是在构建输入和输出时放在最上面,硬编码函数调用中的值只是为了保持简单