我认为发布开发人员实际测试的软件版本会更好;因此,我倾向于从project / makefile中删除'debug'目标,因此只有一个版本可以构建(并经过测试,调试和发布) .
出于类似的原因,我不会断言(另见Are assertions always bad? ......) .
一个人认为“调试”版本的原因是它更容易调试:但是,我反驳说你可能最终想要支持和调试你发布的任何东西,所以你需要构建一个版本,您可以在必要时调试...这可能意味着启用调试符号,并禁用某些优化,即使在“发布”版本中也是如此 .
有人说“这是个坏主意”;这是我几年前发展起来的政策,被以下因素烧毁:
-
一些开发人员测试他们的调试但不测试发布版本
-
一些开发人员编写的bug只出现在发布版本中
-
该公司在测试不充分后发布了发布版本( ever 完全足够吗?)
-
被调用以调试发行版本
从那时起,我看到不止一个开发商遵循这种做法(即没有单独的调试和发布版本) .
你的政策是什么?
19 回答
由于您在问题中列出的所有原因,我一直订阅“发送您调试的内容,以便调试您发布的内容”方法 .
我们的策略是让开发人员使用Debug构建,但其他人(QA,BA,销售等)运行发布版本 . 昨天我不得不修复一个只出现在发布版本中的bug,很明显发生了什么,因为它只是在发布时出现
这是这家商店的第一家店,我已经在这里待了18个月左右 .
事情变得多毛的时候,Release版本对调试版本做了不同的事情 - 是的,我去过地狱,并在一些非常古老,非常复杂的 生产环境 代码中看到了这一点 .
如果配置之间的唯一区别是调试符号和优化,我认为没有理由不同时使用两者 .
在我看来,这个讨论错过了一个非常重要的观点:
这真的取决于它是什么样的项目!
如果您创建本机(C / C)项目,实际上您将被迫创建调试版本,这仅仅是因为在某些情况下编译器优化可能使调试几乎不可能 .
如果您创建Web应用程序,您可能更愿意只使用一个构建(尽管“构建”对于某些Web应用程序而言具有误导性),这些构建可以在运行时启用日志记录功能 .
虽然本机C项目和PHP Web应用程序显然不是所有类型的项目,但我希望我的观点得到了解决 .
P.S . :在为C#开发时,你会遇到一个边框情况,因为虽然使用调试版本会禁用编译器优化,但根据我的经验,你不会遇到与C一样多的差异
开发人员使用调试版本,QA,其他人都使用发布版本,我们称之为“ 生产环境 ” . 这样做的主要优点是在调试版本中,我们可以添加许多额外的代码和断言 . 除了在调试器中查看代码之外,某些对象包含额外的信息 . 有些对象会定期验证自己,以确保所有状态信息都是一致的 . 这些事情使得调试版本变得更慢,但是它们帮助我们找到了在 生产环境 版本中本来就无法找到的错误 .
正如我所说,我们所有的质量保证和性能测试都使用 生产环境 版本,我们偶尔遇到的问题出现在 生产环境 中但不会出现在调试中 . 但它们相对较少,作为开发人员,调试调试版本而不是 生产环境 版本的优势远远超过了这个问题 .
我们总是 Build 两者,甚至从未考虑过这样做 . 启用调试选项会增加代码大小并降低性能,在测试时可能不是您的软件类型的问题,但如果客户正在运行您的代码以及其他5个应用程序,该怎么办...
测试问题可以通过使用自动化测试进行整理,因此当您认为已准备好发布时,可以毫不费力地测试发布版本 . 您的开发人员或公司未能正确测试发布版本并不是发布和调试版本的失败,而是在您的开发人员和/或公司中 .
在你的最后一点,我从来没有被要求调试发布版本,只是为了解决它...
单独的调试和发布版本是一个好主意,因为它确实使开发更容易 .
但是调试版本应该仅用于开发,而不是用于测试 . 您只测试发布版本 . 并且您不使用开发人员来测试这些构建,而是使用测试人员 .
IMO是一个简单的政策,可以提供两全其美的优势 .
Edit: 在回复评论时,我认为很明显调试和发布版本(可以)生成不同的代码 . 想想"-DDEBUG"与"-DNDEBUG"和"#if defined(DEBUG)"等 .
因此,测试最终发布的代码至关重要 . 如果您在调试和发布版本中生成不同的代码,则意味着测试两次 - 无论是否由同一个人测试 .
但是,调试符号不是一个大问题 . 始终使用调试符号构建,保留未提取的二进制文件的副本,但释放已剥离的二进制文件 . 只要您以某种方式使用内部版本号标记每个二进制文件,您应始终能够识别哪个未剥离的二进制文件对应于您必须调试的剥离二进制文件...
如何从外部源中删除调试器中的二进制文件和加载符号与平台有关 .
我认为这取决于项目大小以及您正在使用的构建系统和测试类型 .
如果您有自动构建系统,并且在给定构建上运行单元和功能测试很简单,那么您应该永远不会遇到多种构建类型的任何问题 .
看到这个What's your most controversial programming opinion?
引用:
这可能是次要的,但它增加了其他人在这里所说的内容 . 拥有QA测试版本构建的一个优点是,随着时间的推移,软件的内置调试和日志记录功能将由于开发人员的需求而有所提升,他们需要弄清楚QA中出现问题的原因 .
开发人员需要调试发布版本的次数越多,客户开始遇到问题时就会有更好的工具 . 当然,开发人员没有理由将发布版本作为开发周期的一部分 .
此外,我不知道有任何软件公司有足够长的周期来支付从版本的测试期间中途将QA从调试转换到发布版本的开销 . 必须进行完整的QA循环,这种情况经常很少发生 .
嗯......听起来你正在为我做一个调试版本......对吧?
你出错的部分就是这句话:
Developers don't test code. Tests test code.
您的单元测试应该测试 ALL 构建配置 . 不要让你的开发人员单手绑在背后工作 - 让他们使用他们拥有的所有调试工具 . Debug构建就是其中之一 .
关于断言:断言的使用在很大程度上取决于你是否按 Contract 编程 . 如果这样做,那么断言只是在调试版本中检查 Contract .
这是一个权衡 . 鉴于CPU周期便宜并且越来越便宜而人工周期仍然很昂贵,因此仅维护大型复杂程序的单个版本(调试(山墙)版本)是很有意义的 .
始终使用断言总是比从不使用断言更安全的策略 . 如果生成单独的调试版和发行版,请重新启用所需的
#define
d符号,以保证在发行版中也启用了断言 .我认为权衡很简单:是的,只有一个发布版本,你真的测试实际发送的是什么 . 另一方面,您确实为开发人员的调试和/或用户的性能付出了代价,因此您需要检查这两种情况 .
在大多数中型到大型项目中,易于调试 will 最终确保为您的用户提供更好的产品 .
在我的公司,我们有Debug和Release . - 开发人员使用调试版本来正确查找和修复错误 . - 我们正在使用TDD,因此我们有一个大型测试套件,我们在服务器上运行,测试调试和发布版本配置以及我们也有64/32版本 .
因此,如果使用“debug”配置可以帮助开发人员更快地找到错误,那么就没有理由不使用它 - 当代码进入服务器(进一步测试)或审查时,我们使用“Release” .
使用Java进行开发时,我讨厌非调试版本 . 抛出异常时,您不会获得任何行信息,这使得很难甚至无法追踪错误 . 此外,使用Java 5或更高版本,调试和非调试之间的运行时差异约为5%,因此这实际上没有问题,而且对于今天的硬盘,大小不再重要 .
在使用调试版本的正面:
堆栈跟踪包含您需要的所有信息
可以检查变量
如果您在 生产环境 中遇到问题,只需连接到正在运行的进程,而无需先停止服务器以安装调试版本 .
你不会被聪明的人 grab 优化错误
构建更简单(只有一个工件)
这里我们在调试模式下开发并在发布模式下进行所有单元测试 . 我们是一个小商店,只有少数(12岁以下)应用程序支持从经典ASP,ASP.Net,VB.Net和C# . 我们还有一个专门的人来处理所有测试,调试问题被抛回给开发人员 .
根据我在链接线程中的答案,我们也使用相同的构建进行调试和发布,原因非常相似 . 与算法级别的手动优化相比,优化器的10%-20%性能增益往往非常小 . 单个构建消除了许多潜在的错误 . 特别;
未初始化的变量和小的缓冲区溢出在调试和优化的发布版本中可能会产生非常不同的结果 .
即使有可用的符号信息,调试优化版本也很困难,因为对象与源不匹配,例如变量可能已经过优化,代码可能已经重新排列 . 因此,在测试版本构建中报告的错误可能更难以追踪,因此也很耗时 .
在自动化回归测试中比较未经优化和优化的构建后,优化提供的性能提升不足以为我的案例中的两个构建提供额外的 Value . 值得注意的是,我开发的软件非常耗费CPU(例如创建和操作大型表面模型) .
如果你有一个真正的QA小组可以指望完全测试这个东西,我会说make debug build直到你接近发布,然后确保在相同的构建上完成一个完整的QA循环出门 .
虽然至少在一个案例中我们发布了一些仍然有一些调试代码的东西 . 唯一的后果是它运行得慢一点,日志文件非常大 .
通过删除“调试目标”,您迫使开发人员调试软件的发行版本 . probaly在实践中意味着两件事:
1)“发布版本”将禁用优化(其他的开发人员不能使用调试器)
2)没有构建将有特殊的PREPROCESSOR宏改变它们的执行 .
所以你真正要做的是合并发布和调试配置,而不是仅仅消除“调试”模式 .
我个人已经在iOS开发中完成了这项工作而没有任何不良影响 . 在我们编写的代码中花费的时间不到实际发生的时间的1%,因此优化不是重要的贡献者 . 在这种情况下,它们确实似乎确实导致了错误的增加,但即使它们没有,但是单向测试的想法,然后用不同的代码给QA引入了另外一个要考虑问题的因素 .
另一方面,有些情况下优化是必要的,它们是有用的,甚至在有足够时间进行测试时也是如此 . 通常,调试和发布之间的变化非常小,以至于根本不会引起任何问题 .
我学会了很久以前用.PDB文件构建发布版本,以便我可以调试发布版本 . 许多程序员往往会忘记的是,当您运行调试版本时,关闭所有优化后,您将完全调试另一个程序 . 它可能表现得像发布版本(大多数情况下),但它仍然是一个与发布版本不同的程序 .
此外,调试发布版本并不困难 . 如果你得到一个崩溃转储,你必须能够做到这一点 .