MPS 2020.3 ヘルプ

テスト言語

テスト言語

導入

Testing is an essential part of language designer's work. To be of any good MPS has to provide testing facilities both for BaseLanguage code and for languages. While the jetbrains.mps.baselanguage.unitTest language enables JUnit -like unit tests to test BaseLanguage code, the 言語テスト language jetbrains.mps.lang.test provides a useful interface for creating language tests.

クイックナビゲーションテーブル

言語定義のさまざまな側面がさまざまな方法でテストされています。

言語定義の側面

テストする方法

Intentions
Actions
Side-transforms
Editor ActionMaps
KeyMaps

Use the jetbrains.mps.lang.test language to create EditorTestCases. You set the stage by providing an initial piece of code, define a set of editing actions to perform against the initial code and also provide an expected outcome as another piece of code. Any differences between the expected and real output of the test will be reported as errors.
See the エディターテストセクション for details.

Constraints
Scopes
Type-system
Dataflow

Use the jetbrains.mps.lang.test language to create NodesTestCases. In these test cases write snippets of "correct" code and ensure no error or warning is reported on them. Similarly, write "invalid" pieces of code and assert that an error or a warning is reported in the correct node.
See the ノードテストセクション for details.

Generator
TextGen

Use the language to create GeneratorTests. These let you transform test models and check whether the generated code matches the expected outcome.
See the ジェネレーターテストセクション for details.

現時点でこれらの側面のための組み込みテスト機能はありません。時間の経過とともに私たちのために働いてきたいくつかの習慣があります:

  • おそらく、生成プロセスをチェックするための最も合理的な方法は、正しい生成結果がわかっているモデルを生成し、生成された出力を予想されたものと比較することです。例: 生成コードが VCS に格納されている場合は、テストを実行するたびに違いを確認できます。

  • また、ジェネレーターの重要なケースを表すコードスニペットを用意し、ジェネレーターがそれらから出力を正常に生成するかどうか、または失敗するかどうかを確認することもできます。

  • 生成されたコードをコンパイルして実行すると、ジェネレーターの正しさについての信頼性が高まる可能性があります。

マイグレーション

Use the jetbrains.mps.lang.test language to create MigrationTestCases. In these test cases write pieces of code to run migration on them.
See the 移行テストセクション for details.

作成をテストする

プロジェクトにテストモデルを追加する方法は 2 つあります。

1. 言語でテストアスペクトを作成する

This is easier to setup, but can only contain tests that do not need to run in a newly started MPS instance. So typically can hold plain baselanguage unit tests. To create the Test aspect, right-click on the language node and choose chose New->Test Aspect .

T2

Now you can start creating unit tests in the Test aspect.

T1

Right-clicking on the Test aspect will give you the option to run all tests. The test report will then show up in a Run panel at the bottom of the screen.

2. テストモデルを作成する

This option gives you more flexibility. Create a test model, either in a new or an existing solution. Make sure the model's stereotype is set to tests.

T3

Open the model's properties and add the jetbrains.mps.baselanguage.unitTest language in order to be able to create unit tests. Add the jetbrains.mps.lang.test language in order to create language (node) tests.

T4

Additionally, you need to make sure the solution containing your test model has a kind set - typically choose Other, if you do not need either of the two other options (Core plugin or Editor plugin ).

T8

モデルを右クリックすると、新しい単体テストまたは言語テストを作成できます。利用可能なすべての根本的概念を参照してください。

T5

T6

BTestCase による単体テスト

As for BaseLanguage Test Case, represents a unit test written in baseLanguage. Those are familiar with JUnit will be quickly at home.

T7

A BTestCase has four sections - one to specify test members (fields), which are reused by test methods, one to specify initialization code, one for clean up code and finally a section for the actual test methods. The language also provides a couple of handy assertion statements, which code completion reveals.

TestInfo

In order to be able to run node tests, you need to provide more information through a TestInfo node in the root of your test model.

Test infox1

Especially the Project path attribute is worth your attention. This is where you need to provide a path to the project root, either as an absolute or relative path, or as a reference to a パス変数 defined in MPS (Project Settings -> Path Variables ).

Path variables1

パス変数を Ant スクリプトで使用できるようにするには、mps.macro. 接頭辞を付けてビルドファイルで定義します(以下の例を参照)。

言語定義のテスト面

ノードテスト

A NodesTestCase contains three sections:

T10

The first one contains code that should be verified. The section for test methods may contain baseLanguage code that further investigates nodes specified in the first section. The utility methods section may hold reusable baseLanguage code, typically invoked from the test methods.

正確さをチェックする

To test that the type system correctly calculates types and that proper errors and warnings are reported, you write a piece of code in your desired language first. Then select the nodes, that you'd like to have tested for correctness and choose the Add Node Operations Test Annotation intention.

T11
T12
T13

This will annotate the code with a check attribute, which then can be made more concrete by setting a type of the check:

T14

T15

Note that many of the options have been deprecated and should no longer be used.

The for error messages option ensures that potential error messages inside the checked node get reported as test failures. So, in the given example, we are checking that there are no errors in the whole Script.

型システムとデータフローのエラーと警告をチェックする

If, on the other hand, you want to test that a particular node is correctly reported by MPS as having an error or a warning, use the has error / has warning option.

T16

T17

これは、警告とエラーの両方で機能します。単一のアノテーションで複数の警告とエラーを宣言できます。

T26 1

You can even tie the check with the rule that you expect to report the error / warning. Hit Alt+Enter when with cursor over the node and pick the ルール参照を指定する option:

T18

T19

ルールの識別子が追加されました。 Ctrl+Space でルールの定義に移動できます。

T29

実行すると、テストは指定されたルールが実際にエラーを報告したものであることを確認します。

型システム固有のオプション

The check command offers several options to test the calculated type of a node.

T100

T101

複数の期待を簡単に組み合わせることができます。

T37

テストスコープ

スコープテストアノテーションでは、有効範囲の規則によって正しい項目が適切な範囲に含まれることをテストで検証できます。

T102

The Inspector panel holds the list of expected items that must appear in the completion menu and that are valid targets for the annotated cell:

T103

T104

テスト方法と実用方法

The test methods may refer to nodes in your tests through labels. You assign labels to nodes using intentions:

T32

その後、ラベルはテストメソッドで利用可能になります。

T33

エディターテスト

エディターテストでは、エディターのダイナミズム(アクション、インテンション、置換)をテストできます。

T20

An empty editor test case needs a name, an optional description, setup the code as it should look before an editor transformation, the code after the transformation (result) and finally the actual trigger that transforms the code in the code section.

T21

For example, a test that an IfStatement in BaseLanguage can have an "else" block added if the user types "else{" behind the closing brace would look as follows:
T21a

In the code section the jetbrains.mps.lang.test language gives you several options to invoke user-initiated actions:

  • type- insert some text at the current cursor position

  • press keys- simulate pressing a key combination

  • invoke action- trigger an action

  • invoke intention- trigger an intention

  • invoke quick-fix XXX from YYY to the selected node - invokes a specified quick-fix named XXX to an error YYY from the intentions menu, fails if the quick-fix is not available in the menu

  • invoke quick-fix <the only one available> to the selected node - invokes the only quick-fix that is available in the intentions menu, fails if 0 or more than 1 quick-fixes are available

T22

Obviously you can combine the special test commands with the plain BaseLanguage code.

To mark the position of the caret in the code, use the appropriate intention with the cursor located at the desired position:

T23

The cursor position can be specified in both the before and the after code:

T25

The cell editor annotation has extra properties to fine-tune the position of the caret in the annotated editor cell. These can be set in the Inspector panel.

エディターの状態を調べる

Some editor tests may wish to inspect the state of the editor more thoroughly. The editor component expression gives you access to the editor component under cursor. You can inspect its state as well as modify it, like in these samples:

Ec1

Ec2

Ec3

Ec4

The is intention applicable expression let's you test, whether a particular intention can be invoked in the given editor context:

Iiap

You can also get hold of the model and project using the model and project expressions, respectively.

2 段階削除のテスト

Two-phase deletion of nodes can be tested using the editor component expression as follows

EditorTestUtil.runWithTwoStepDeletion({ => invoke action -> Delete assert true DeletionApproverUtil.isApprovedForDeletion(editor component.getEditorContext(), editor component.getSelectedNode()); assert true editor component.getDeletionApprover().isApprovedForDeletion(editor component.findNodeCell(editor component.getSelectedNode())); invoke action -> Delete }, true);

  • EditorTestUtils.runWithTwoStepDeletion は、2 段階削除を有効にしてローカルコンテキストを作成します。ユーザーは 2 段階の削除を自由にオンおよびオフにできるため、テストの一貫した環境が確保されることに注意してください。メソッドの 2 番目のブールパラメーターは、2 段階削除をオンにするかオフにするかを示します。

  • DeletionApproverUtil.isApprovedForDeletion- 現在のノードに対応するセルを取得し、テストは「approvedForDeletion」フラグです。

  • Alternatively use component.getDeletionApprover() to test the flag without the help of the utility class. You will have to find and provide the editor cell that should have the "approved for deletion" flag tested.

移行テスト

移行テストを使用して、指定された入力を使用して移行スクリプトが期待どおりの結果を生成することを確認できます。

New migration test

移行テストケースを作成するには、その名前とテストする移行スクリプトを指定する必要があります。多くの場合、個々の移行スクリプトを別々にテストするだけで十分ですが、移行が互いにどのように相互作用するかをテストする必要がある場合は、単一のテストケースで複数の移行スクリプトを安全に指定できます。

Empty migration test

さらに、移行テストケースには、移行プロセスに渡されるノードと、移行の成果として出てくることが予想されるノードも含まれます。

Input output

実行すると、移行テストは次のように動作します。

  1. 入力ノードは、単一モデルの空のモジュールにルートとしてコピーされます。

  2. 移行スクリプトはそのモジュール上で実行されます。

  3. 移行後にそのモジュールに含まれているルートは、予想される出力と比較されます。

  4. 問題のマイグレーションの check() メソッドが、問題の空のリストを確実に返すようにするために呼び出されます。

移行テストを作成するプロセスを簡素化するために、現在デプロイされている移行スクリプトを使用して、期待される出力を入力ノードから自動的に生成できます。これを行うには、' 入力から出力を生成 ' というインテンションを使用します。

Generate output

ジェネレーターテスト

ジェネレーターはジェネレーターテストでテストすることができます。彼らのゴールは、ジェネレーターまたはジェネレーターのセットが、期待通りに変換を実行することを保証することです。IDE では、MPS、Ant ビルドスクリプトからの実行と同様に、インプロセス実行モードとアウトプロセス実行モードの両方がサポートされています。MPS のすべてのテストと同様に、ユーザーは以下を指定します。

  1. 入力モデルの形での前提条件

  2. 出力モデルの形でのジェネレーターの期待される出力

  3. 明示的なジェネレータープランの形式で入力モデルに適用するジェネレーターのセット。省略した場合は、暗黙的なジェネレータープランが使用されます。

The jetbrains.mps.lang.test.generator allows you to create GeneratorTests. The jetbrains.mps.lang.modelapi language will let you create convenient model references using the model/ name of the model/ syntax.

Gt1

ジェネレーターテストの構造には、すべてのモデル(入力、予測出力、オプションで生成計画を保持するモデル)を指定する必要がある引数というセクションと、目的の変換とマッチングを行うアサーションというセクションがあります。指定されています。

ジェネレーターの出力と予想される出力との一致に失敗すると、テストレポートでユーザに表示されます。

Gt2

テストを実行する

内側 MPS

To run tests in a model, just right-click the model in the Project View panel and choose テストの実行 :

T39

If the model contains any of the jetbrains.mps.lang.test tests, a new instance of MPS is silently started in the background (that's why it takes quite some time to run these compared to plain baseLanguage unit tests) and the tests are executed in that new MPS instance. A new run configuration is created, which you can then re-use or customize:

Testrunconfig

実行構成ダイアログには、テストのパフォーマンスを調整するためのオプションがあります。

  • デフォルト設定の場所を上書きする - キャッシュを保存するディレクトリを指定します。デフォルトでは、MPS は一時ディレクトリを選択します。ディレクトリは実行ごとにクリアされます。

  • 同じプロセスで実行する - to speed up testing tests can be run in a so-called in-process mode. It was designed specifically for tests, which need to have an MPS instance running. (For example, for the language type-system tests MPS should safely be able to check the types of nodes on the fly.)
    One way to run tests is to have a new MPS instance started in the background and run the tests in this instance. The second way, enabled by this checkbox, runs all tests in the same original MPS process, so no new instance needs to be created.

    When the option 同じプロセスで実行する is set, the test is executed in the current MPS environment. This is the default for:

    • ノードテスト

    • エディターテスト

    To run tests in the original way (in a separate process) you should uncheck this option. This is the default for:

    • 移行テスト

    • Generation tests

    • ユニットテスト (BTestCases and JUnit test cases)

    テストレポートは画面下部の実行パネルに表示されます。

  • JUnit 実行構成はテストを実行する前にデプロイするプラグインを受け入れます。ユーザーはテスト実行中にデプロイされるアイデアプラグインのリストを提供できます。前のタスク 'Assemble Plugins' は JUnit の実行構成でも利用できます。与えられたプラグインを自動的に構築し、アーティファクトを設定ディレクトリにコピーします。

T41

ビルドスクリプトから

In order to have your generated build script offer the test target that you could use to run the tests using Ant, you need to import the jetbrains.mps.build.mps and jetbrains.mps.build.mps.tests languages into your build script, declare using the module-tests plugin and specify a test modules configuration.

Test script1

Ant が JUnit に渡すマクロを定義するには(たとえば、テストの TestInfo ルートで使用するために)、mps.macro. を頭に付けます。

Image2016 10 13 17 29 27

IDEA Plugin でエディターテストを実行する

With the new JUnit test suite (jetbrains.mps.idea.core.tests.PluginsTestSuite) it is possible to execute editor tests for your languages in IntelliJ IDEA, when using the MPS plugin. To make use of this functionality you have to create a simple ANT script that will install all the necessary plugins into the IntelliJ platform and executing the tests by specifying test module name(s).

関連ページ:

世代計画

世代計画:生成計画を使用すると、開発者は自分のモデルに望ましい生成順序を明示的に指定でき、生成プロセスをより適切に制御できます。目的大規模プロジェクトでは、相互ジェネレーターの優先順位を指定するのが面倒になるかもしれません。さらに、優先順位を指定するためには、適切な相互依存関係を宣言することによって関係言語が互いについて知る必要があります。これは、(時に望ましい)独立性を破ります。生成計画は、生成ステップの適切な順序付けの責任を単一の場所、つまり生成計画にまとめます。これにより、言語設計者は、

MPS デバッガーを使う

デバッグ:MPS デバッガーは、カスタム言語用のデバッガーを作成するための API を提供します。MPS ディストリビューションに含まれている Java デバッガープラグインは、ユーザーが最終的に Base Language / Java に生成される言語で書かれているプログラムをデバッグすることを可能にします。下記のプラグインを使って MPS デバッガーの機能を説明します。これらはすべて API を介して他の言語でも利用できます。デバッグ、実行、実行構成のインスタンスの作成、言語定義のデバッ...

依存関係

モデル間の依存関係を管理することは不可欠です。そのトピックに関する情報については、左側のパネルを参照してください。テスト言語依存関係を正しくする