如何使用Pytest测试内部包含Wrapper的Python类私有方法?
如何使用Pytest测试内部包含Wrapper的Python类私有方法?
嘿,我来帮你捋清楚这个问题~
首先看你遇到的错误:断言失败是因为_conv_bn_activation这个方法返回的是内部定义的wrapper函数,而不是你期望的tfk.Model实例,所以直接用isinstance判断肯定会出错。
问题根源
你的_conv_bn_activation是一个工厂方法,它的作用是生成并返回一个闭包函数(也就是那个wrapper),这个函数需要接收输入张量后,才会调用_conv2d_bn创建层并执行前向传播。所以你现在的测试逻辑走偏了——你在断言“工厂方法的返回值是Model”,但实际上工厂方法只负责生产“能创建/调用层的函数”。
修正后的测试方案
你需要先拿到这个wrapper函数,再给它传入一个符合要求的测试输入张量,最后根据实际的输出结果来做断言。这里给你一个修改后的测试示例:
import tensorflow as tf import pytest @pytest.mark.parametrize('filters', [256, 128]) def test_conv2d_layer(self, filters): model = Unet() # 1. 获取工厂方法返回的wrapper函数 conv_wrapper = model._conv_bn_activation(filters=filters, name="conv2d_layer9") # 2. 创建测试用的输入张量(形状要匹配你的模型输入要求,这里假设是(1, 64, 64, 3)) test_input = tf.random.normal(shape=(1, 64, 64, 3)) # 3. 调用wrapper函数,得到层的输出结果 output_tensor = conv_wrapper(test_input) # 4. 做针对性的断言:比如检查输出通道数是否等于传入的filters参数 assert output_tensor.shape[-1] == filters, f"输出通道数不匹配,预期{filters},实际{output_tensor.shape[-1]}" # 如果你需要验证内部创建的层类型,也可以直接测试_conv2d_bn方法(如果有必要的话) # conv_layer = model._conv2d_bn( # filters=filters, # kernel_size=model.kernel_size_, # activation=model.activation_, # # 其他参数... # ) # assert isinstance(conv_layer, tfk.Model)
额外小提示
虽然Python允许直接访问私有方法(通过_前缀),但从软件工程的角度来说,不建议直接测试私有方法——因为私有方法是类的内部实现细节,后续可能会被修改、重构,直接测试会让你的测试用例变得脆弱。如果可以的话,优先测试类的公共API,通过公共方法的输入输出来间接验证私有方法的正确性。
备注:内容来源于stack exchange,提问作者MediaJ
相关产品推荐
相关产品推荐

