使用Selenium测试Django Channels 2失败:无法Pickle本地对象报错
解决Django Channels测试中的
AttributeError: Can't pickle local object 'DaphneProcess.__init__.<locals>.<lambda>' 这个问题我之前在跟进Django Channels聊天功能测试时也踩过坑,核心原因是Daphne启动进程时用了局部定义的lambda函数——而Django测试的多进程环境需要序列化进程相关对象,但lambda根本没法被pickle序列化,所以才触发了这个报错。下面给你几个可行的解决办法:
方案1:升级Daphne到最新版本
最省心的就是直接升级Daphne,这个pickle问题是旧版本的已知bug,官方在后续版本里已经替换了lambda的使用逻辑。执行下面的命令升级即可:
pip install --upgrade daphne
升级后重新运行测试,大概率能直接解决问题。
方案2:重写测试类的进程启动方法
如果升级后还是有问题,你可以在测试类里重写get_worker_process方法,手动创建Daphne进程,避开原逻辑里的lambda:
from django.test import ChannelsLiveServerTestCase from daphne.server import Server from django.conf import settings from django.utils.module_loading import import_string from multiprocessing import Process class ChatTestCase(ChannelsLiveServerTestCase): def get_worker_process(self, port): # 手动初始化ASGI应用与Daphne服务器 application = import_string(settings.ASGI_APPLICATION) server = Server(application) # 直接传递server.run方法作为进程目标,替代原逻辑中的lambda return Process( target=server.run, args=(port,), )
方案3:调整多进程启动方式
在测试文件的最顶部添加以下代码,强制使用spawn启动方式(Windows默认是spawn,Linux/macOS可能需要显式设置),确保子进程能正确序列化所需对象:
import multiprocessing # 仅在主进程执行时设置启动方式 if __name__ == '__main__': multiprocessing.set_start_method('spawn')
额外排查点
- 确认你的测试类继承的是
ChannelsLiveServerTestCase,而非普通的TestCase——只有前者会自动启动ASGI服务器进程。 - 检查
settings.ASGI_APPLICATION配置是否正确,确保指向你的项目ASGI应用模块。
内容的提问来源于stack exchange,提问作者neverwalkaloner
相关产品推荐
相关产品推荐

