我在一个非常小的初创公司开发工厂(3位开发人员)工作,我经常被从我正在努力修复任务关键错误或实施“绝对关键”软件功能 - 我的错误列表重新几乎每天都优先考虑,我很少知道从现在开始几个小时内什么是“重要的”。
正因为如此,我发现我越来越警惕添加可能被我们的QA部门取消检查的代码(读:人)。
当我实现一个新函数时,不知道我是否会随时调用它,我有时会尝试在顶部编写一个return语句,以确保代码永远不会在发布版本上执行
语句的问题如:
public void NewFunction()
{
return; // Put break point so that I can use the debugger to step to meat:
meat:
// ... More code
}
即使在调试模式下,Visual Studio也足够聪明,知道肉:永远不会执行,所以你不能使用“set next statement”命令来实现:在#if!DEBUG等编译器指令中包装代码也是如此。
相反,我写的是:
public void NewFunction()
{
if("a"[0]=='a')
return; // put break point here
meat:
// ... More code
}
因此,如果此代码意外地进入发布版本,则不会造成任何损害,但由于直到运行时才对其进行评估,因此我可以使用调试器来处理问题:没有问题。
我真的不喜欢让事情未完成,但在关键时刻,我们往往没有时间搁置变更集或正确处理事情。目前不需要通过API访问上述功能概述等未完成的功能,因此我不认为将它们留在软件中有任何直接的危害(但是在线下,它们可能导致几个wtf时刻)维护 - 就像“wtf是这个函数在这里没有做任何事情?”因为我不记得我从现在起6个月后做了什么。)
考虑到我(遗憾地)半定期地做这样的事情,这个问题是否有标准做法?作为一个更大的问题,是否有一些实践有助于打击软件版本中的调试代码?
答案 0 :(得分:2)
有些事情对我很突出:
我会查看一些敏捷方法和实践。它旨在考虑发布中的快速移动目标。
您应该执行以下操作:
通过坚持任务/功能分支,您不必像在问题中那样创建将要签入的中间代码。这不应该发生。如果切换将在另一个分支中的任务。这样做可以使您的流程最小化,并且您的分支毫不费力。那么这些事情将成为第二天性。
答案 1 :(得分:1)
分布式版本控制系统使分支和合并成为一种快照。使用像Mercurial这样的工具(我的个人偏好),您甚至不需要远程存储库 - 您只需在本地系统上就地创建存储库,然后在本地驱动器上的其他地方克隆存储库。因此,您可以轻松保留代码的“发布”版本,同时快速将代码更改迁移到“调试”分支和从“调试”分支迁移。
答案 2 :(得分:1)
假设您的代码在C#中,您可以使用[Conditional]
属性在Release配置中排除某些方法调用:
[Conditional("DEBUG")]
public void NewFunction (object something)
{
// do something
}
这相当于包装方法本身及其对#if DEBUG
/ #endif
子句的所有调用。
当未定义NewFunction
符号时,编译器将排除对DEBUG
的任何调用。控制它的最简单方法是通过Visual Studio中的解决方案和项目配置。在Debug配置中,定义了DEBUG
符号,而不是Relase configuraiton。
请注意,只能排除void
次调用,因为代码不依赖于这些方法的返回值。
然而,这被设计用于跟踪,记录等。我不太明白你打算如何保留一些未完成的方法但仍然在调试版本中使用它们。如果他们不工作,或者如果他们这样做,为什么不将他们包括在发布中,这是什么意思呢?
答案 3 :(得分:0)
我处于同样的境地。我有时会把#IF DEBUG放到新函数的调用上。或#IF DEBUG围绕函数的全部内容。
我做的另一件事是将TODO:单元测试评论放在函数上,以便在发布时我可以搜索那些并知道是否存在问题。