有时为了测试/开发目的,我们在必须在生产构建中删除的代码中进行一些更改。我想知道是否有一种简单的方法来标记这样的块,这样只要它们存在,生产构建就会失败,或者至少它会在构建过程中以某种方式警告你。
简单"//TODO:"
并不真正起作用,因为它被遗忘并与大量其他待办事项混合在一起。还有什么更强的吗?
或者即使我可以创建一些外部txt文件并在生产之前提供有关该操作的说明,并且该ant会检查该文件是否存在然后取消构建。
我们正在使用Eclipse / Ant(和java + Spring)。
更新:我并不是说本地和生产中存在大量不同的代码。事实上,所有代码都是相同的,应该是相同的。简单地说,我注释掉了一些代码行,以便在开发过程中节省大量时间,并忘记取消注释或者沿着这些方向进行注释。我只是希望能够以某种方式标记项目需要注意的事情,并且生产构建将失败或显示警告。
答案 0 :(得分:13)
避免必要性。如果您将代码放入一个不应该在生产中的类中,请弄清楚如何以不同方式进行操作。比方说,提供一个钩子,以便测试代码可以执行它所需的操作,但将测试代码留在类之外。或者用于测试的子类,或者使用依赖注入,或者使代码有效且安全可靠的任何其他技术,同时仍然可以测试。许多这样的技术在Michael Feathers的精彩书籍Working Effectively with Legacy Code中有详细记载。
答案 1 :(得分:12)
您还可以定义更强的任务注释标记:FIXME(高优先级)和XXX(普通优先级)是Eclipse中的标准,您可以定义更多任务标记(Eclipse Properties - > Java - > Compiler - >任务标签)
如果您想使构建失败,可以使用Ant(1.7)contains文件选择器来查找包含指定文本的文件:
<target name="fixmeCheck">
<fail message="Fixmes found">
<condition>
<not>
<resourcecount count="0">
<fileset dir="${pom.build.sourceDirectory}"
includes="**/*.java">
<contains text="FIXME" casesensitive="yes"/>
</fileset>
</resourcecount>
</not>
</condition>
</fail>
</target>
<target name="compile" depends="fixmeCheck">
显然,将${pom.build.sourceDirectory}
更改为您的源目录,将FIXME
更改为您要搜索的注释。
有没有人知道在构建文件中打印出此文件集中找到的文件的好方法(除了再次查看Eclipse之外)?
答案 2 :(得分:7)
如果存在块,则添加单元测试失败。也许该块设置单元测试检查的全局变量CODE_BLOCK_IS_NOT_DELETED = true;
。
但是,更大的问题是您使用不需要或在生产中使用的代码进行测试/开发。这听起来不对。
答案 3 :(得分:3)
一个不明显的建议是使用静态方法创建一个类,比如说
class Prod {
public static void uction(){
}
}
然后使用
标记所需的地点Prod.uction();
然后在生产之前删除该类,您将在需要时遇到编译器错误:D
答案 4 :(得分:2)
我们为阻止\\NOCOMMIT:
的subversion添加了一个触发器。在允许构建之前,您可以拥有构建脚本要查找的\\NODEPLOY:
标记。
答案 5 :(得分:2)
[edit:]适用于C ++ ...: - )使用这些预处理器定义,您的所有问题都将得到解决:
#ifdef _DEBUG
#define COMMENT (code) /* code */
#else
#define COMMENT (code) #error "Commented out code in release!"
#endif
不确定语法是否完全正确,但您明白了。
答案 6 :(得分:2)
但是你从技术上解决了这个问题,我建议反过来做:不为生产构建做一些特别的事情,但是以这样的方式构建代码和构建环境在开发构建期间发生。生产构建应该尽可能简单(或墨菲证明)。
如果开发构建中出现问题:那么。
生产版本中出现任何问题都会造成更多伤害。
答案 7 :(得分:1)
在我参与过的项目中,我已经有了各种代码,可以在开发过程中轻松进行测试。我将它们包装在一个检查最终布尔值的if块中。当布尔值为true时,可以访问代码。当boolean为false时,我依赖于编译器从生成的.class文件中删除代码作为优化。例如:
public class Test {
public static void main(String[] args) {
final boolean TESTABLE = true;
if (TESTABLE) {
// do something
}
}
}
通常,我自己管理这些变量,在开发过程中使用它们,并在完成后将TESTABLE设置为false。开发团队可以轻松地同意变量名称的约定,例如TESTABLE,如果任何源文件具有TESTABLE变量= true,则构建文件的生产目标可以检查并失败。
答案 8 :(得分:1)
除了上面提到的所有建议(所有手动废话和添加代码的东西是什么?自动化人们......),我注意到你正在使用Eclipse,Spring和ANT。 Eclipse支持多个源文件夹 - 将您的代码分成“源”和“测试”文件夹,将任何内容放在源文件夹中,并将任何“非生产”放在测试文件夹中。 Spring允许您有多个引用不同实现的配置 - 因此您可以拥有仅在生产中引用类的生产配置,并测试与您的测试代码一起运行的配置。让ANT脚本构建应用程序的生产和测试版本 - 用于测试将“testing”文件夹添加到编译路径,生产将其关闭。如果一个类从生产中引用测试类,则会出现编译错误 - 如果生产Spring配置引用了生产中的测试类,则一旦尝试加载它就会失败。
答案 9 :(得分:1)
TDD和依赖关系倒置概念可能对您有所帮助。通过将变化的代码放入实现接口的类中,您可以控制该代码的测试版本何时运行以及何时运行prod版本。
然后你有一个文件,清楚地命名为测试,你可以放弃你的构建。
答案 10 :(得分:0)
您可以使用java预处理器。对于j2me应用,我使用天线预处理器。代码看起来像这样
public void someMethod() {
//#ifdef DEBUG
doDebugStuff();
//#endif
}
答案 11 :(得分:0)
Eclipse允许其他标记而不仅仅是// TODO,你可以添加,例如// TOBEREMOVED并赋予它高优先级,因此它会显示在所有其他TODO标记之前。
答案 12 :(得分:0)
解决这个问题的一个显而易见的方法是进行单元测试,该测试仅在构建用于生产的构建的构建上运行(或检查当前构建是否针对生产并且如果是,则运行测试)和如果测试失败,则无法构建。
你永远不会忘记。在什么样的测试方面,理想情况下它实际上会检查代码的作用。如果这是不可能的话,那么Terry Lorber建议的全局静态将比你现在的要好得多。
答案 13 :(得分:0)
只需添加一些// TODO: - 然后创建一个c#脚本(cs-script.net),在您的代码中查找// TODO并显示它们。然后,您可以将此脚本添加到自动构建中(如果您正在执行此操作),因此每次执行构建时,您都可以看到要执行的操作。在部署之前查看代码的待办事项列表。
除了编写自己的脚本之外,还有一些关于如何将vstudio与指出你的待办事项行的工具集成的说明:http://predicatet.blogspot.com/2006/12/show-all-tasks-in-visual-studion-2005-c.html
然而,在我看来,设置该工具比使用正则表达式编写简单的C#脚本更令人痛苦。
答案 14 :(得分:0)
我会尽量避免这种情况。 - 另一种方法是使用依赖注入来注入不同的实现进行测试。
或者...
在对象中添加一个inTest布尔字段,并将可选代码包装在if语句中。
if(inTest) {
testMethod();
}
您可以使用依赖注入设置此vboolean,或者从传入的系统属性中读取它(-DinTest = true)
希望这有帮助。
答案 15 :(得分:0)
我在任务视图中使用eclipse显示的// FIXME关键字和// TODO(您可以过滤在其上看到的内容)。 如果有一些// FIXME,你不应该去生产:)
答案 16 :(得分:0)
我的解决方案是处理两个独立的代码分支。一个生产分支只获得没有任何调试代码的干净代码,另一个生产分支(有时我甚至有几个)用于测试,调试,尝试新的填充等。
在eclipse中,这些是单独的项目(或项目组)。
Mercurial对于这类工作来说是一个不错的VCS,但CVS和颠覆也很好。
答案 17 :(得分:0)
对于我们的生产环境,我们有一些简单的C工具,可以使用非常特殊的注释来删除部分。 /*#BEGIN_SKIP*/
和/*#END_SKIP*/
。坚持标准的C运行时,你可以在任何环境下编译。
您可以更改整个构建周期以复制源代码,对其进行转换并进行编译。
答案 18 :(得分:0)
也许如果你将这些类/方法标记为depricated,那么它们会在编译期间被标记出来?