You may have wondered how exactly does a node test such as this one work:

There is some copying magic that lets you mutate the nodes under test, even when the test is executed in-process, but the original test model remains unaffected. It may be useful to understand a little bit deeper how the magic works to know its limitations.

After initializing a headless environment MPS creates a temporary copy of the original model. Then, before the test is executed, MPS creates a second copy of each “node under test” and adds it to the same model as a root (copying not just the node itself but also the wrapping TestNode).

The test runtime maintains a map from the original nodes to the copies and uses this map to make the green underlined labels work.

For each green annotation check such as check ... for error messages MPS will create an additional test method. This test method does not perform any second copies ad

MPS will generate additional test methods to perform the green annotation checks, one per each check. These methods work directly on the nodes inside NodesTestCase in the temporary model (the “first copy”) and do not create any additional “second copies” of test nodes.

If you are curious where this all happens, look at the BaseTransformationTest and BaseTestBody classes in MPS.

What consequences does this have?

  • It is possible to mutate the test nodes like in the example above, without affecting the original model.
  • Any code that uses model.rootsIncludingImported or similar (e.g. scopes) will work differently under test since the test nodes are never roots.