Writing unit tests in my compiler (which generates IL)

Deadly 提交于 2019-12-05 02:51:36

That's exactly what we do on the C# compiler team to test our IL generator.

We also run the generated executable through ILDASM and verify that the IL is produced as expected, and run it through PEVERIFY to ensure that we're generating verifiable code. (Except of course in those cases where we are deliberately generating unverifiable code.)

Jordão

I've created a post-compiler in C# and I used this approach to test the mutated CIL:

  1. Save the assembly in a temp file, that will be deleted after I'm done with it.
  2. Use PEVerify to check the assembly; if there's a problem I copy it to a known place for further error analysis.
  3. Test the assembly contents. In my case I'm mostly loading the assembly dynamically in a separate AppDomain (so I can tear it down later) and exercising a class in there (so it's like a self-checking assembly: here's a sample implementation).

I've also given some ideas on how to scale integration tests in this answer.

You can think of testing as doing two things:

  1. letting you know if the output has changed
  2. letting you know if the output is incorrect

Determining if something has changed is often considerably faster than determining if something is incorrect, so it can be a good strategy to run change-detecting tests more frequently than incorrectness-detecting tests.

In your case you don't need to run the executables produced by your compiler every time if you can quickly determine that the executable has not changed since a known good (or assumed good) copy of the same executable was produced.

You typically need to do a small amount of manipulation on the output that you're testing to eliminate differences that are expected (for example setting embedded dates to a fixed value), but once you have that done, change-detecting tests are easy to write because the validation is basically a file comparison: Is the output the same as the last known good output? Yes: Pass, No: Fail.

So the point is that if you see performance problems with running the executables produced by your compiler and detecting changes in the output of those programs, you can choose to run tests that detect changes a stage earlier by comparing the executables themselves.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!