如何测试依赖随机数生成器的while循环内部代码?
强制触发依赖随机数的while循环测试方案
针对你需要测试依赖随机数触发的while循环代码的需求,以下是几种可行的解决方案:
方案1:固定随机数种子
找到一个特定的NumPy随机种子,使得第一次生成的多项式经过p.polydiv和取模后长度恰好为n-1,从而直接触发while循环。这种方式无需修改原函数,只需在测试时固定种子即可。
示例测试代码:
import numpy as np import unittest def gen_poly(n,q): l = 0.0 #Gamma Distribution Location (Mean "center" of dist.) poly = np.floor(np.random.normal(loc=l, size=(n))) while (len(poly) < n): poly = np.floor(np.random.normal(loc=l, size=(n))) poly = np.floor(p.polydiv(poly, xN_1)[1]%q) return poly class TestGenPoly(unittest.TestCase): def test_while_loop_trigger(self): # 提前测试找到能触发循环的种子(示例用123,需根据实际逻辑调整) np.random.seed(123) # 调用函数时,第一次生成的poly长度会小于n,强制进入循环 result = gen_poly(5, 10) # 验证循环执行后的结果符合长度要求 self.assertEqual(len(result), 5)
方案2:Mock依赖函数(更可靠)
利用unittest.mock直接替换随机数生成或多项式除法的返回值,手动构造触发循环的条件,完全摆脱随机数依赖。这种方式适合所有同类型的随机依赖函数测试。
示例测试代码:
from unittest.mock import patch import numpy as np import unittest def gen_poly(n,q): l = 0.0 #Gamma Distribution Location (Mean "center" of dist.) poly = np.floor(np.random.normal(loc=l, size=(n))) while (len(poly) < n): poly = np.floor(np.random.normal(loc=l, size=(n))) poly = np.floor(p.polydiv(poly, xN_1)[1]%q) return poly class TestGenPoly(unittest.TestCase): @patch('numpy.random.normal') @patch('p.polydiv') # 替换你的多项式除法函数 def test_while_loop_execution(self, mock_polydiv, mock_normal): n = 5 q = 10 # 让第一次随机生成的数组处理后长度为n-1 mock_normal.return_value = np.array([0,0,0,0,0]) # 让polydiv返回的余数部分长度仅为n-1 mock_polydiv.return_value = (None, np.array([1,2,3,4])) result = gen_poly(n, q) # 验证循环内代码被执行:随机数生成函数被调用至少两次 self.assertGreaterEqual(mock_normal.call_count, 2) # 验证最终结果长度符合要求 self.assertEqual(len(result), n)
方案3:抽离循环内逻辑(可选)
如果允许微调原函数结构,可以把循环内的生成逻辑抽成独立的辅助函数,直接测试该辅助函数的逻辑,无需依赖主函数的随机触发流程。
修改后的函数:
def gen_poly(n,q): l = 0.0 poly = np.floor(np.random.normal(loc=l, size=(n))) while len(poly) < n: poly = _generate_valid_poly(n, q, l) return poly def _generate_valid_poly(n, q, l): poly = np.floor(np.random.normal(loc=l, size=(n))) return np.floor(p.polydiv(poly, xN_1)[1]%q)
测试时可直接针对_generate_valid_poly构造输入,验证其处理后的结果是否符合预期,无需关心循环触发问题。
内容的提问来源于stack exchange,提问作者Niall
相关产品推荐
相关产品推荐

