我们一直遇到模板错误偶尔潜入我们的生产网站的问题,所以如果有一个工具来捕获这些,我很乐意将它添加到我们的部署过程中。
答案 0 :(得分:3)
根据我的经验,Freemarker在尝试渲染模板时实际上只有两类错误(忽略配置):
尽管linting工具通常会在代码中发现错误,但lint工具并不能代替基本测试,这对于您在此处遇到的问题来说是一个更好的解决方案,因为您在生产代码中看到异常。
无论好坏,Freemarker关于谁在使用数据以及谁在使用标记的假设都是具有不同技能组的不同人。假设情况确实如此(并且您可以使用Java工程资源),从测试过程的角度来看,您有两种方法可以解决此问题(尽管要真正严格,但您需要两者)。
在我之前的工作中,我们自己使用了这种方法。基本上,前端工程师会在特殊的Web前端攻击模板,其中编辑的模板直接位于包含两个列表的配置路径上:
'版本'本质上是一组两层硬编码的Java对象,其中第1层在所有模板中都是一致的,而第2层是模板特定的变体。因为我们的大多数电子邮件都是帐户级别的通知,所以我们获得了很多里程并且只使用全局数据模型就可以重复使用,而且我们很少需要深入研究这些小东西。
<强>优势强>
不太好
另一种选择是在创建每个模板时对其进行单元测试。因为Freemarker中的异常都发生在编译时,所以您只需要执行以下操作(完成初始设置后):
Template temp = cfg.getTemplate("myTestedTemplate.ftl");
temp.process(myTestDataModel, myIgnoredOutput); // No exceptions -> OK for us
请注意,在这种情况下你不关心结果,你只需要编译它。这很重要,因为在Java中调试编译输出时很容易陷入困境而不能解决当前问题。和以前一样,您也希望在这里进行相同的两层单元测试:
<强>优势强>
<强>不那么好强>
如果您有时间同时执行这两项操作,我建议您使用单元测试来处理边缘情况以及弹出时发现的其他问题,然后开发Web前端以便开发页面不会需要重新编译。版本前端的功能非常有用,但目标是首先防止生成错误到构建过程。启动,然后优化和全部。
答案 1 :(得分:1)
如果您的意思是运行时输出错误而不是模板语法错误,您可以使用一组(脆弱的)“期望获得”集成测试。这有多合适取决于模板的复杂程度以及模板的动态性。如果您只想进行一些简单的“冒烟”测试,这可能是一个很好的解决方案。
对于每个模板,至少创建一个测试。使用具体/静态/预先指定的输入数据和具体/静态/预先指定的输出结果。此输出必须在任何更改后第一次手动生成和验证,但从那时起,它可以保存并且可以编写测试脚本。如果模板拉入自己的数据(如日期等),这些数据无法设置为固定输入,则屏蔽或从预期输出中删除它。每个自动化测试应该:
确切的输出相等是最容易实现的并且确保正确。如果需要,每个模板都有多个测试。我不会试图聪明,只是让计算机做无聊和重复的工作。我会忽略在第一次传递时需要屏蔽的模板部分(一些测试比没有测试更好)。稍后当你决定提高可靠性以获得足够的价值时(或者过去曾经做错的任何事情),只为他们编写明确的测试。
此解决方案有以下注意事项。
范围太大。对模板或数据模型中的任何内容进行的任何更改都可能需要更新测试。使用“diff”可能有助于手动验证并确定在数据模型和/或模板更改时如何修改测试。
代码拒绝和模块化导致测试问题。使用良好的模块化代码,一次代码更改可能会影响所有模板中的数据,但静态测试需要在发生这种情况时单独更改和重新验证所有测试。解决这个问题并不多,所以代码越好越模块化,导致的工作就越多:(
复杂的模板很难测试。仅使用几组静态数据来获得良好的模板覆盖可能会有问题。这可能意味着模板做了太多的“处理”,并没有真正用作模板。无论如何,这可能不是一个好主意。
答案 2 :(得分:-1)
我不知道有哪个工具可以帮到您,但是为了捕获语法错误,您所要做的就是将所有模板文件提供给new Template("whatever", theTemplateFileReader);
。遗憾的是,您无法以这种方式检测运行时错误,例如对非存在变量/宏/导入的引用。为此,您可以调用Template.process
,但如果没有实际应用程序中的数据模型,那么它当然没有意义。