Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 最佳实践:测试使用随机数生成器的代码_C++_Testing_Random - Fatal编程技术网

C++ 最佳实践:测试使用随机数生成器的代码

C++ 最佳实践:测试使用随机数生成器的代码,c++,testing,random,C++,Testing,Random,在代码中的某个地方(深层,深层)说我正在使用随机数做一些很酷的事情。测试通常应该是确定性的,而这部分代码的发布版本的行为明确地利用了随机数生成器的非确定性/随机性 因此,为了获得确定性(功能性)测试,我想设置一个固定的种子值: size_t seed = 42; std::mt19937 rng; rng.seed(seed); 但我还想确保在使用随机输入和随机种子时不会发生任何奇怪的情况(即异常): std::mt19937 rng; rng.seed(std::random_device(

在代码中的某个地方(深层,深层)说我正在使用随机数做一些很酷的事情。测试通常应该是确定性的,而这部分代码的发布版本的行为明确地利用了随机数生成器的非确定性/随机性

因此,为了获得确定性(功能性)测试,我想设置一个固定的种子值:

size_t seed = 42;
std::mt19937 rng;
rng.seed(seed);
但我还想确保在使用随机输入和随机种子时不会发生任何奇怪的情况(即异常):

std::mt19937 rng;
rng.seed(std::random_device()());
显然,有限数量的测试运行无法确定代码是否正确;然而,大量的测试运行至少可以给您一些信心

我该如何处理这件事?我考虑添加一些类似的内容:

size_t seed = std::random_device()();
#ifdef TESTING
    seed = 42;
#endif
rng.seed(seed);
但是,我不能有一个测试文件(使用gtest)在某些测试中使用随机种子,在某些其他测试中使用常量种子(可以吗?)

在我的例子中:我从n中均匀地、独立地随机选择一个元素来划分输入


编辑:我问的是功能测试,而不是单元测试。

首先,为随机数生成器创建一个接口,这样测试将能够用预定义的接口替换它。如果在单元测试中使用随机数生成器,则它不再是单元

然后想想你真正想测试什么。我想,这个算法应该进行测试:

  • 它是否工作(您预定义的“随机”生成器在每次迭代时可能返回1、2、3,…可能是最大范围的模)
  • 如果random generator始终返回边界值(0和max-1或max,取决于您的需要),则它是否返回有效结果
  • 如果随机生成器返回的值超出范围,则是否通知错误

编辑:(回答问题编辑)


你为什么要在功能测试中担心随机数生成器?功能测试检查应用程序在用户使用时是否正常工作。用户将无法访问随机数生成器的种子,所以请保持原样,并允许它按您设计的方式工作。如果算法的结果不依赖于随机数生成器生成的值,请检查它们在测试之间是否没有变化。如果它们确实依赖于随机数生成器,请检查它们是否在两个测试之间发生了变化(如果它们没有变化,则意味着代码没有按照预期的方式进行)。

这取决于您希望执行的测试类型

在单元测试中,种子应设置为固定值

在某种类型的功能测试中,如果您真的想使用随机数测试行为,并且不管需要多长时间,您可以设置随机种子(可能使用time()),并根据需要多次执行测试


这意味着,您应该以类似的方式创建两组测试(您使用gtest),其中单元测试的执行速度要快得多。使用单元测试时,您不会访问文件和缓慢的资源(如网络和数据库)。

您的生成器可能是完全确定的,因为有一个特定的种子,这就是我在问题中所说的我想做的。真正的问题是:假设我不能轻易通过种子测试,那么使用“定义”是一个好主意吗?@mort不确定你是否真的理解我的答案。使用此设置,您不必使用宏。当然,您可以根据某些宏有条件地编译某些代码。没关系,只要你只有很少这样的宏。对不起,我的问题不够精确:我问的是功能测试,不是单元测试。