Is there a style style that will check freemarker templates for template errors?

We were faced with the problem of template errors that sometimes made their way to our production site, so if they had a tool to catch them, I would gladly add it to our deployment process.

+6
source share
3 answers

From my experience, Freemarker really only has two classes of errors when trying to render a template (Ignoring the configuration):

  • Simple syntax errors at the template level
  • Assumptions about a model passed at the Java level are incorrect

Although linting tools usually detect code errors, the lint tool does not replace the need for basic testing, which is much better for what you are experiencing here, as you see exceptions in the production code.

For better or worse, Fremarker's assumptions about who works with data and who works with markup are different people with different skills. Assuming this is the case (and you have the resources to develop Java), you have two ways to approach this problem in terms of the test process (although in order to be really rigorous, you want both).

Frontend Testing

In my previous work, we used this approach on our own. Basically, front-end engineers cracked the templates on a special web interface, where the edited templates were directly on the configuration path containing two lists:

  • Template for rendering
  • Versions of the data model for rendering

"Versions" were essentially a two-tier set of hard-coded Java objects, where level 1 was consistent across all templates, and level 2 was a template-specific option. Since most of our emails were account-level notifications, we only got a lot of mileage and reuse from the global data model, and we rarely had to dig into the little things.

Benefits

  • Frontend engineers never need to touch Java, so you can use your HTML / CSS mavens for their intended purpose, if that's what you have on your team.
  • Backend engineers can recycle many things depending on the patterns and their design.
  • Freely applies uniformity of data model variable names when referring to frequently used values, such as โ€œaccountโ€ (Frontend engineers will be annoyed when there were no expected values, because another backend engineer called something โ€œwrongโ€)

Not very good

  • This is mainly manual testing, and at some point you will not be able to catch the error.

Backend testing

Another alternative is unit form tests for each template as they are created. Since exceptions in the FreeMarker occur during compilation, you will need to do the following (after the initial setup):

Template temp = cfg.getTemplate("myTestedTemplate.ftl"); temp.process(myTestDataModel, myIgnoredOutput); // No exceptions -> OK for us 

Please note that in this case you do not care about the results, you just need to compile it. This is important because you can easily get bogged down in debugging compiled output in Java and not solve the current problem. As before, you will also want to do the same two levels of unit tests here, in all likelihood:

  • Smoke test all templates with some common model (receiving each template can be done programmatically)
  • Check individual patterns with changes to the data model that you expect (missing settings, incomplete fields, etc.).

Benefits

  • Part of the build / deploy process, so you eliminate human error in templates
  • Depending on how you use Freemarker, it can also check if other processes are correctly creating data models if you are not already doing this.

Not so good

  • Frontend engineers will need to read stack traces to find out what failed
  • Development using this method ends with binding to your build process, which is nowhere near as fast as reloading a page.

If you have time to do both, I would recommend working with unit tests to handle extreme cases and other problems that you will find as they occur, and then for the web development interface so that page development does not require recompilation. The appearance of the interface is extremely useful, but the goal is to first prevent production errors for the assembly process. Run, then optimize and that's it.

+2
source

If you mean run-time errors, not pattern syntax errors, you can use a (fragile) set of wait-and-go integration tests. How appropriate this depends on the complexity of your templates and how dynamic they are. If you just need simple smoke tests, this is probably a good solution.

For each template, create at least one test. Using specific / static / predefined input data and specific / static / predetermined output results. This output should be manually generated and verified for the first time after any change, but from that moment it can be saved, and testing can be written in a script. If the template takes its own data (for example, dates, etc.) that cannot be set as fixed input, mask or delete it from the expected result. Each automatic test should:

  • Generate a "received" output from at least one set of input data for each template.
  • Mask or remove unpredictable variable regions from the output.
  • Compare the result with the saved, previously confirmed "expected" result.
  • Refuse reports if they do not match.

Exact output equality is easiest to implement and ensure correctness. If necessary, run several tests for each template. I would not try to be smart, just give the computer a boring and repetitive job. I would ignore parts of the template that need to be masked in the first pass (some tests are better than none). Write explicit tests only for them later, when you decide that it improves reliability enough to be worth the effort (or for those that were erroneous in the past).

These decisions have the following reservations.

  • Too big area. Any change to something in the template or in the data model may require updating the test. Using "diff" can help with manual validation and determine how to modify tests when changing data models and / or patterns.

  • The rejection of code and modularity lead to problems with testing. With good modular code, a single code change can affect data in all templates, but a static test requires changing and redefining all tests independently when this happens. There is not much to do to fix this, so the better your module code is, the more work it causes :(

  • Complex patterns are hard to verify. It would be problematic to have good template coverage using only a few sets of static data. This may mean that the templates do too much โ€œprocessingโ€ and are not actually used in the same way as the template. This is probably not a good idea.

+1
source

I don't know about a tool that does this for you, but to catch syntax errors, all you have to do is provide all your template files new Template("whatever", theTemplateFileReader); . Unfortunately, you cannot detect runtime errors in such a way as references to nonexistent variables / macros / imports. You can call Template.process , but without the data model that you will have in a real application, this does not make sense, of course.

-1
source

Source: https://habr.com/ru/post/907366/


All Articles