最近把项目里的代码补丁任务交给Qwen2.5-Coder-14B,发现它特别喜欢给函数生成冗长的mock对象,尤其是涉及数据库操作时,明明可以直接用内存sqlite,它非要mock一个假的repository层。跑测试的时候,覆盖率倒是上去了,但实际逻辑很多没测到。我试过在prompt里强调“少用mock、多写集成测试”,效果还是不稳定。想问下各位,是我系统提示词写得太笼统,还是这个模型本身对测试风格的理解就偏向保守?另外,有没有人对比过它和DeepSeek-Coder在这类任务上的差异?我用的vLLM部署,温度0.2,max_tokens设的2048。
用Qwen2.5-Coder写单元测试总生成一堆无用mock,是我姿势不对吗?
全部回复
共 33 条说实话我也遇到过这问题,14B对“少用mock”的理解经常停留在字面,它可能觉得mock就是省事。你试试在prompt里直接给个负面例子,比如贴一段它之前生成的烂mock代码,然后标注“别这么写”,效果会比抽象描述好很多。
另外温度0.2确实偏低,模型会更倾向安全保守的输出,我调到0.4之后生成的测试风格明显更敢用真实依赖了。至于DeepSeek-Coder,我倒是觉得它在代码补全上更利落,但写测试时反而更爱堆mock,可能跟训练数据里单元测试比例高有关。
你如果主要跑逻辑覆盖,不如直接禁用它访问repository类,强制走sqlite,反正vLLM改system prompt成本低,多试几个版本呗。
同感,Qwen2.5-Coder在mock策略上确实有点“防御性编程”的味道,我试过把“集成测试优先”直接写进系统提示词里,还加了禁止mock repository的负面清单,效果比单纯强调管用。不过温度0.2可能太保守了,我调到0.6之后,生成风格明显更敢直接操作真实依赖。你提到DeepSeek-Coder,我对比过,它在需要多文件联动的测试场景里更敏锐,但单测风格偏激进,有时候会跳过边界检查。建议你试试把sqlite的初始化代码直接贴在prompt的few-shot例子里,比抽象指令稳定很多。
说到点子上了,我也遇到过这问题。Qwen对“mock”的理解感觉特别机械,你强调少用mock它反而可能觉得你在暗示要更精确的mock。试试在prompt里直接给例子,比如“参考这段sqlite内存测试的写法”,比抽象描述管用得多。
另外温度0.2确实偏保守,但mock多跟温度关系不大,更像模型训练时的偏好。我后来改用DeepSeek-Coder实测,它更倾向直接跑真实依赖,但偶尔会过度简化断言,俩模型各有毛病。
对了,你试过给Qwen加个“禁止mock外部IO,改用真实测试容器”这种硬性规则吗?我用这招后覆盖率反而更真实了,虽然偶尔会报环境错误,但至少逻辑是跑通的。
试试把“少用mock”换成“用真实数据库跑集成测试”,温度调到0.1,效果会稳很多。
我之前也踩过这坑,后来发现光在prompt里说“少用mock”没用,得直接给它看具体例子,比如把你想让它写的sqlite测试代码贴一段进去当few-shot,它会学得很快。温度0.2其实偏保守了,生成风格容易模板化,我试过调到0.4反而更容易出来非mock的路径。至于DeepSeek-Coder,感觉它更倾向直接跑真实依赖,但偶尔会忽略边界情况,俩模型得对着调。
题主试试在prompt里直接丢一段你手写的测试样例进去,风格引导比口头强调管用。
说实话我也踩过同样的坑,Qwen2.5-Coder对mock的执念感觉是训练数据里单元测试样本太单一导致的。后来我干脆在prompt里直接写死“禁止mock任何数据访问层,必须用真实sqlite内存库”,并把仓库接口的构造方式也塞进去,效果好很多。DeepSeek-Coder我试过,它更倾向于生成精简的测试骨架,但遇到复杂业务逻辑时容易漏分支,两者其实半斤八两。你温度0.2有点低,我调到0.4之后输出风格活泛了些,但mock问题依旧,所以核心还是得靠提示词强约束。
有没有更详细的教程推荐?
试试在system prompt里直接塞一条“禁止mock数据库层”的硬规则,温度拉到0.1,效果会稳很多。
说实话我也有同感,14B这版对mock的执念特别深,感觉它把“隔离依赖”理解成了“能mock就mock”。后来我试过在系统提示里直接给负面例子,比如贴一段它之前写的烂mock让它别这么干,效果比单纯说“少用mock”强不少。另外温度调到0.1,max_tokens拉高到4096,它反而更愿意把真实逻辑写完整,你可以试试。DeepSeek-Coder我倒没对比过,但听说它在测试生成上更倾向直接跑内存库,不确定是不是真的。
哈哈我也遇到过,14B这个尺寸好像天生就爱堆mock,感觉是训练数据里单元测试占比太高了。你试试在system prompt里直接怼一句“禁止mock数据库层,必须用真实sqlite”,比在任务描述里强调管用得多。
另外温度0.2确实偏低,生成风格会偏保守,我调到0.6之后它至少敢写点带实际断言的代码了。DeepSeek那边我没细测过,但感觉它对测试意图的理解更激进点,不过偶尔会瞎写依赖,各有各的坑吧。
对了,你max_tokens是不是卡了输出?有些时候它mock写一半就截断了,反而更容易出那种又长又没用的东西。可以试着拆成小函数单独让它测,比一次性给整个repository靠谱。
说实话我也踩过这个坑,Qwen2.5-Coder对mock的偏好确实挺顽固的,尤其是你描述的那种“假repository层”场景,我怀疑是训练数据里单元测试的样本占了主导,导致它默认选择最“安全”的隔离策略。我试过在system prompt里直接塞一段“禁止mock数据库,强制用sqlite内存模式”的示例代码,比单纯说“少用mock”管用得多,但偶尔还是会抽风。另外温度0.2偏低可能让输出更倾向保守,我调到0.6之后生成风格反而更灵活,但代价是需要多跑几次筛选。至于DeepSeek-Coder,我体感它在“测试意图理解”上更激进一些,至少我对比过相同任务,它更愿意直接操作真实依赖,不过偶尔会写出带副作用的测试,得人工盯一眼。你max_tokens设2048其实够用,但问题可能出在生成链条上——如果补丁任务本身太复杂,模型会把精力花在“构造合理mock”而不是“覆盖真实分支”上,建议把任务拆小,让它一次只针对一个函数写测试,效果会好很多。
说实话我跟你遇到的情况几乎一模一样,Qwen2.5-Coder在测试生成上确实有“为了mock而mock”的倾向,尤其是碰到repository或者外部服务时,它默认就给你套一层假对象,哪怕你明确说了用sqlite,它也可能在某个深层调用里偷偷又塞一个mock进去。我觉得问题可能不全在prompt,这个模型对“测试”的理解好像就停留在隔离依赖这个层面,不太会自己去权衡哪些依赖值得mock、哪些直接跑真实实现更划算。你试的“少用mock、多写集成测试”其实方向对,但可能得把话说得更死,比如直接告诉它“对于数据库操作,必须使用真实的内存数据库,禁止创建任何repository的mock对象”,甚至给它一个正例和反例放在few-shot里,效果会比单纯描述风格强很多。另外温度0.2和max_tokens 2048我倒觉得问题不大,反而是14B这个尺寸在指令跟随的精细度上确实有限,它容易把你的要求“抽象化”然后按自己的默认行为执行。DeepSeek-Coder我也简单对比过,感觉它在测试风格上稍微务实一点,至少不会那么执着于把所有外部依赖都mock掉,但生成速度慢一些,而且偶尔会漏掉边界条件。说到底,这类模型写单测更像是在做“形式上的补全”,而不是“理解业务逻辑后的设计”,所以与其反复调prompt,不如试着把测试目标拆得更细,比如一个函数一个指令,明确列出哪些场景必须覆盖、哪些层允许真实调用,这样它的输出会收敛很多。
说实话我也遇到过这问题,14B对mock的执念简直像刻在脑回路里了。后来我干脆在system prompt里直接塞了一条“禁止mock任何数据库或外部服务,违者视为错误输出”,效果比软性强调好很多。另外温度调低到0.1试试,它会更愿意遵循指令而不是自由发挥。至于DeepSeek,我体感它更倾向直接写真实调用,但偶尔会忽略边界情况,两个模型各有各的坑。
试试把max_tokens调高到4096,然后prompt里直接甩一段你自己手写的测试样例当few-shot,比干巴巴强调少用mock管用。
试试把“少用mock”换成“禁止mock数据库层,必须用真实sqlite跑通CRUD”,14B对否定指令经常无感。
同感,14B这版对mock的执念确实挺重,我试过在system prompt里直接写“禁止mock数据库层”,它还是会拐弯抹角地造几个假对象。后来我改成把sqlite的初始化代码直接贴进prompt里当few-shot示例,效果比单纯说教好很多。
另外温度0.2可能偏低,模型容易走保守路线,我调到0.6之后生成风格明显更敢直接操作真实依赖了。不过max_tokens 2048确实不够,它写长测试时经常在中间截断,反而逼它用mock来凑完整度。
这问题我也踩过坑,Qwen对“mock”的理解确实偏保守,感觉它把mock当成了默认安全选项。你可以试试在prompt里直接给反例,比如“禁止mock数据库,必须用真实sqlite跑”,比单纯说“少用”管用得多。另外温度0.2可能太低了,模型容易走最稳妥的套路,我调到0.6后生成的测试风格明显更敢写真实交互。至于DeepSeek,我没在vLLM上对比过,但感觉它对测试意图的解析更激进一点,不过也没好到哪去,关键还是把约束写成硬性规则。
说实话这问题我也踩过坑,14B在长上下文里对“少mock”的指令遵循确实不稳定,我后来直接把“禁止mock数据库层,必须用真实sqlite”写进system prompt,效果比在任务描述里强调好很多。另外温度0.2可能偏低了,模型容易走保守路线,我试过调到0.4左右,生成的测试风格会灵活一些。至于DeepSeek-Coder,我体感它更倾向直接写断言而不是绕mock,但偶尔会漏边界条件,俩模型各有各的毛病。
试试把“少用mock”换成“禁止mock,必须用真实数据库跑”,再调低温度到0.1,效果会稳很多。
温度0.2确实偏高,模型容易自由发挥,我降到0.1后mock少了不少。