如何让Django autocomplete light的Select2QuerySetView单元测试覆盖查询分支
如何测试Django AutoComplete Light的查询分支以实现全代码覆盖
你当前的测试仅覆盖了不带查询参数的请求场景,所以if self.q:内部的过滤逻辑完全没被执行到。要实现完整的代码覆盖,你需要在测试中模拟用户输入搜索关键词的行为——也就是发送带q查询参数的GET请求。
下面是完善后的测试类,能覆盖所有代码分支:
from django.test import TestCase from django.urls import reverse from django.db.models import Q from .models import Item class TestItemAutoComplete(TestCase): def setUp(self): # 预先创建测试数据,保证每次测试都有稳定的数据源 self.item1 = Item.objects.create(id=101, name="办公笔记本") self.item2 = Item.objects.create(id=202, name="无线静音鼠标") self.item3 = Item.objects.create(id=303, name="机械游戏键盘") def test_visit_without_query(self): # 保留原测试:覆盖无查询参数的分支 response = self.client.get(reverse('buy_invoice_items_autocomplete')) self.assertEqual(response.status_code, 200) # 额外验证返回全部数据 self.assertEqual(len(response.json()['results']), 3) def test_visit_with_exact_id_query(self): # 测试按ID精确匹配的分支(对应Q(id__iexact=self.q)) response = self.client.get( reverse('buy_invoice_items_autocomplete'), {'q': '202'} ) self.assertEqual(response.status_code, 200) results = response.json()['results'] # 验证仅返回匹配ID的条目 self.assertEqual(len(results), 1) self.assertEqual(results[0]['id'], str(self.item2.id)) self.assertEqual(results[0]['text'], self.item2.name) def test_visit_with_name_contain_query(self): # 测试按名称模糊匹配的分支(对应Q(name__icontains=self.q)) response = self.client.get( reverse('buy_invoice_items_autocomplete'), {'q': '鼠标'} ) self.assertEqual(response.status_code, 200) results = response.json()['results'] # 验证返回包含关键词的条目 self.assertEqual(len(results), 1) self.assertEqual(results[0]['id'], str(self.item2.id)) def test_visit_with_no_match_query(self): # 测试无匹配结果的场景,覆盖过滤后空QuerySet的情况 response = self.client.get( reverse('buy_invoice_items_autocomplete'), {'q': '不存在的关键词'} ) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()['results']), 0)
关键优化点:
- 用
reverse('buy_invoice_items_autocomplete')替代硬编码URL,符合Django最佳实践,避免URL变更导致测试失效。 - 通过
setUp预先初始化测试数据,确保测试环境的一致性。 - 拆分多个测试用例,分别覆盖无查询、ID精确匹配、名称模糊匹配、无匹配结果这四类场景,确保每一行代码都被执行到。
- 验证返回的JSON结构(Select2的响应格式固定为包含
results的字典),不仅保证代码覆盖,还能验证业务逻辑的正确性。
这样修改后,Coverage工具就会检测到if self.q:及后续的过滤代码都被执行过,实现完整的代码覆盖了。
内容的提问来源于stack exchange,提问作者Ahmed Wagdi
相关产品推荐
相关产品推荐

