Use when writing or modifying tests inside MPS `@tests` models — `NodesTestCase` (typesystem, constraints, scopes, dataflow, generator output), `EditorTestCase` (intentions, actions, keystrokes, side-transforms, completion), `MigrationTestCase` (migration scripts), `BTestCase` (plain JUnit on hand-written Java/Kotlin runtime), inline annotations such as `has error` / `has type` / `ScopesTest`, label-based `node<label>` cross-references, caret markers, and running tests via MCP / in MPS. Reach for this skill whenever the task involves authoring or fixing tests in a `tests`-stereotype model, or interpreting failures from one.
78
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
MPS ships a dedicated test language — jetbrains.mps.lang.test — for testing language artefacts (typesystem, scopes, constraints, dataflow, editor, generator, migrations). Plain JUnit-style tests against runtime classes use jetbrains.mps.baseLanguage.unitTest (the BTestCase concept).
A test is a root node living in a model whose stereotype is tests (pass modelName: "<name>@tests" to mps_mcp_create_model; the on-disk file ends in @tests.mps). See aspect-model-stereotypes.md for all model identifiers. The test model lives in a Solution module carrying the tests facet, not in the language module itself, so it can depend on the language under test plus arbitrary runtime libraries.
This skill is the reference for what to put in a test model and what each test type means. For the mechanics of creating/modifying nodes via MCP, see mps-model-manipulation and the mps_mcp_* tool docs. Documentation: https://www.jetbrains.com/help/mps/testing-languages.html. Source: plugins/mps-testing/languages/lang.test/.
tests (file name …@tests.mps). Without it, roots compile but are not discovered as JUnit tests.jetbrains.mps.lang.test, jetbrains.mps.baseLanguage.unitTest, the language(s) under test, plus jetbrains.mps.baseLanguage, jetbrains.mps.baseLanguage.collections, jetbrains.mps.lang.smodel, jetbrains.mps.lang.text as needed by assertion code.tests facet. Languages and Generators don't compile the test classes, so the test root must live in this dedicated Solution. Create it via mps_mcp_create_module(type="solution", …, facets="[\"tests\"]"); the response is self-describing — {"data":{"kind":"Solution","facets":["java","tests"],"loadExtensions":"NotAvailable",…}} confirms the kind without a follow-up call. For an existing Solution, attach the facet via mps_mcp_update_module_facet(facetType="tests", enabled=true) and verify with mps_mcp_get_project_structure(startingPoint="…") (its facets array will include "tests").testMethods role declares NodesTestMethod, which is abstract — instantiate SimpleNodeTest (c:8585453e-6bfb-4d80-98de-b16074f1d86c/1225978065297). Inserting raw NodesTestMethod fails with "Abstract concept instance detected".TestNodeAnnotation labels are only resolvable via TestNodeReference from test-method bodies. For in-snippet references (e.g. setting RoutineCall.routine) use the target node's own name property (resolved through the language's scope) or a persistent r: node ref, never the label name.invoke action <ActionId> over raw press <chord> for Enter/Tab/etc. in EditorTestCase — PressKeyStatement may bypass the named-action dispatcher used by the production editor. Editor actions live in r:9832fb5f-2578-4b58-8014-a5de79da988e(jetbrains.mps.ide.editor.actions).empty_<role> for the caret — not refNodeList_<role> (the latter is the populated wrapper cell).test_gen/ or classes_gen/ — those are regenerated.When asked to "write tests" for an MPS language feature:
NodesTestCase. Intention / action / keystroke → EditorTestCase. Migration → MigrationTestCase. Runtime helper → BTestCase. Generator output equivalence → NodesTestCase + assertNodesMatch. See references/test-types.md.@tests model in the language's adjacent test Solution; only create a new one if no suitable Solution exists.mps_mcp_create_root_node using the concept ref from references/concept-identifiers.md, then populate nodes / code / etc. with mps_mcp_update_node. Use mps_mcp_parse_java_and_insert to drop a Java/BaseLanguage snippet into a TestNode.references/nodes-test-case.md and references/editor-test-case.md). For prototypes, open the model in MPS and use the Alt+Enter intentions ("Add Node Operations Test Annotation", "Add Test Node Label", "Mark Caret Position") — they create the right annotations without hand-building blueprints.mps_mcp_check_root_node_problems on the new root.JUnit Tests config via mps_mcp_create_run_configuration (pass the test root's reference) and launch it with execute_run_configuration, or ask the user to run it in MPS.| Where | When |
|---|---|
Test aspect of the language (testAspect model under <lang>/) | Quick, language-local checks; cannot run in a fresh MPS instance from outside the language. |
Dedicated test Solution with @tests model | Recommended for anything serious. Runs out-of-process; can be wired into the build/CI. |
If the only goal is plain JUnit on hand-written Java/Kotlin (no MPS-specific assertions), prefer a regular module test source root rather than a @tests model — see mps-distribution-build for how BTestCase-based MPS test modules are packaged.
mps-model-manipulation — the smodel / closures / collections reference for assertion bodies.mps-node-editing — MCP recipes for inserting children and harvesting persistent refs (used heavily by the ScopesTest staged-construction recipe).mps-aspect-typesystem — when the system-under-test is the typesystem; has error/type annotations here verify those rules.mps-aspect-constraints — when validating can-be / scope / validator rules from the constraints aspect.mps-aspect-migrations — for migration scripts being exercised by MigrationTestCase.mps-aspect-intentions and mps-aspect-editor-menus-and-keymaps — when an EditorTestCase exercises intentions, side transforms, or keymapped actions.mps-build-language and mps-distribution-build — when wiring a @tests Solution into the build pipeline (test-only BuildProject).mps-quotations — for tests that use quotation snippets.references/test-model-setup.md when bootstrapping a new @tests model — required stereotype, used languages, Solution kind, optional TestInfo root, and the choice between the language's testAspect and a dedicated test Solution. Includes the canonical example test Solutions in this repo.references/test-types.md for the test-type cheat sheet (concept refs and what each tests). Use to decide which root concept to instantiate.references/nodes-test-case.md when authoring or modifying a NodesTestCase — section layout (nodes, test methods, utility methods, accessMode), inline assertion annotations (has error, has type, has typesystem error, has expected type, has type in), labelled-node assertions inside test methods, and the namespace separation between labels and scope-resolved references.references/scopes-test.md when writing declarative scope assertions (ScopesTest + ScopesExpectedNode) — where to attach the annotation, the exact-set semantics, the JSON blueprint, the stage-construction recipe for resolving expected refs, and why declarative scope tests beat imperative ones.references/editor-test-case.md when writing an EditorTestCase — root layout (before / result / code), the AnonymousCellAnnotation caret marker, the cell-ID convention for auto-generated editors (property_<name>, refNodeList_<role>, empty_<role>, refNode_<role>, constant/collection cells), the editor-driving statements (type "...", press, invoke action, invoke intention, invoke quick-fix), the editor expressions usable inside code (EditorComponentExpression → getEditorComponent(), IsIntentionApplicableExpression → isIntentionApplicable(), ProjectExpression → getProject(), ModelExpression → model of the edited node), and the side-transform / completion testing pattern.references/generator-and-migration-tests.md when validating generator output (NodesTestCase + assertNodesMatch) or testing a migration script (MigrationTestCase — inputNodes, outputNodes, migration refs, options including StableIdOption). Lists the four-child structure of MigrationTestCase and the "Generate Output from Input" intention.references/btestcase.md when writing plain JUnit-style tests against hand-written Java/Kotlin — the BTestCase annotation, TestMethod / BeforeTest / AfterTest, and the available assertion concepts.references/running-tests.md when launching tests — inside MPS (right-click → Run tests), from the command line via the Ant pipeline, or from an agent via mps_mcp_create_run_configuration + execute_run_configuration. Covers in-process vs separate-MPS-instance, and mps_mcp_check_root_node_problems as a fast pre-run gate.references/common-failures.md when a test won't run, runs but doesn't fail when expected, fails for the wrong reason, or generates a misleading outputNodes. Includes the abstract-concept gotcha, label-vs-name confusion, press VK_ENTER vs invoke action Insert, replace_node_child ref invalidation, and ScopesExpectedNode.ref not being scope-resolved.references/concept-identifiers.md for the validated FQN+concept-ref table covering jetbrains.mps.lang.test (every concept used by the skill — NodesTestCase, SimpleNodeTest, TestNode, TestNodeAnnotation, AnonymousCellAnnotation, the annotation/check operations, the editor-driving statements, ScopesTest/ScopesExpectedNode, etc.) and jetbrains.mps.baseLanguage.unitTest.52c9d63
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.