测试驱动开发(Test Driven Development)
单元测试在行业中#
单元测试框架:
https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks
开源项目几乎都有单元测试:
https://github.com/django/django/actions/workflows/tests.yml
----------------------------------------------------------------------
Ran 17940 tests in 229.063s
https://github.com/psf/requests/actions/workflows/run-tests.yml
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
------ generated xml file: /home/runner/work/requests/requests/report.xml ------
====== 590 passed, 15 skipped, 1 xfailed, 18 warnings in 79.16s (0:01:19) ======
https://github.com/python/cpython/actions/workflows/build.yml
Total duration: 7 min 38 sec
Total tests: run=47,529 failures=1 skipped=2,067
Total test files: run=484/485 skipped=16 resource_denied=2 rerun=1
Result: FAILURE then SUCCESS
编码时遇到下面的问题应该怎样做?#
获取数组长度,下面哪种写法是正确的?
gc.get_objects(0).count()
...
len(gc.get_objects(0))
删除 None 会报错吗?
del None
避免猜测,先去求证#
在 Python Console 中进行测试:
>>> gc.get_objects(0).count()
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevconsole.py", line 364, in runcode
coro = func()
File "<input>", line 1, in <module>
TypeError: list.count() takes exactly one argument (0 given)
>>> len(gc.get_objects(0))
467
>>> del None
Traceback (most recent call last):
File "/Users/zja/.pyenv/versions/3.10.11/lib/python3.10/code.py", line 63, in runsource
code = self.compile(source, filename, symbol)
File "/Users/zja/.pyenv/versions/3.10.11/lib/python3.10/codeop.py", line 153, in __call__
return _maybe_compile(self.compiler, source, filename, symbol)
File "/Users/zja/.pyenv/versions/3.10.11/lib/python3.10/codeop.py", line 73, in _maybe_compile
return compiler(source, filename, symbol)
File "/Users/zja/.pyenv/versions/3.10.11/lib/python3.10/codeop.py", line 118, in __call__
codeob = compile(source, filename, symbol, self.flags, True)
File "<input>", line 1
del None
^^^^
SyntaxError: cannot delete None
函数的逻辑是否正确?#
def check_gen2(*_args, **_kwargs):
global gen2_objs
gc.collect()
new_gen2_objs = WeakSet(gc.get_objects(2))
if gen2_objs is not None:
new_objs = new_gen2_objs - gen2_objs
print(new_objs)
del gen2_objs
gen2_objs = new_gen2_objs
真实代码验证#
# 23aa9299
class TargetAnyDisplay:
@staticmethod
def is_support(define_id):
return define_id == parameter_def.TARGET_ANY.define_id
return define_id in (parameter_def.TARGET_ANY.define_id, parameter_def.SANDBOX_TARGET_ANY.define_id)
@staticmethod
def get_display_info(define_id):
queryset = TargetMachine.objects.filter(type_id=TargetType.REAL, is_deleted=False)
if define_id == parameter_def.SANDBOX_TARGET_ANY.define_id:
queryset = queryset.filter(agent__source=AgentSource.Sandbox)
resource_list = order_agent_list(queryset, TARGET_FIELDS)
return get_agent_display_infos(resource_list, False)
测试代码如下:
@pytest.mark.django_db
def test_sandbox_agent_display_info():
AreaMgt.objects.create(area='sandbox_area')
agent = Agent.objects.create(name='sandbox_agent', source=AgentSource.Sandbox)
target = TargetMachine.objects.create(name='sandbox_target', real_agent=agent, status=AgentStatus.ONLINE, area='sandbox_area', os_type=2)
info = get_define_display_infos([parameter_def.SANDBOX_TARGET_ANY.define_id])
assert info[parameter_def.SANDBOX_TARGET_ANY.define_id][0]['children'][0]['children'][0]['id'] == target.id
assert info[parameter_def.SANDBOX_TARGET_ANY.define_id][0]['children'][0]['children'][0]['source'] == 2