简体   繁体   English

在IntelliJ IDEA中,测试如何访问正在测试的代码的PSI树结构?

[英]How can a test access the PSI tree structure of the code it is testing, In IntelliJ IDEA?

Running tests from the IntelliJ IDEA IDE, I want them to be able to do some custom static analysis on the code being tested. 从IntelliJ IDEA IDE运行测试,我希望它们能够对被测试的代码进行一些自定义的静态分析 To that end, I want the tests to be able to access the PSI tree structure of the tested code. 为此,我希望测试能够访问被测试代码的PSI树结构 Is this possible? 这可能吗? How? 怎么样?

Here it is an example of the usefulness of this: In Hibernate, final methods of entity classes should not directly access any fields. 这是一个有用的例子:在Hibernate中,实体类的final方法不应直接访问任何字段。 So, I would like to write a test that checks that all classes annotated with @Entity have no final methods that reference fields. 因此,我想编写一个测试来检查所有用@Entity注释的类是否没有引用字段的最终方法。 This I can't do with reflection. 我不能用反射做到这一点。 I need access to the PSI tree. 我需要访问PSI树。 This is just an example, and there are many more use cases for such capabilities. 这仅是示例,并且此类功能还有更多用例。

I know this couples tests to IntelliJ IDEA. 我知道这会将测试与IntelliJ IDEA相结合。 And I know I could write an IntelliJ IDEA plugin to implement "inspections" to do this kind of analysis. 而且我知道我可以编写IntelliJ IDEA插件来实现“检查”来进行这种分析。 But I want to write this as tests. 但我想将此写为测试。 Tests that can be red or green. 测试可以是红色或绿色。 Tests that could emit meaningful error messages. 可能发出有意义的错误消息的测试。 Tests that could run the code, access the code through reflection, and also access the PSI tree. 可能运行的代码测试,通过反射访问代码,并且访问PSI树。

What you are trying to do is basically to work on the AST outputted by a parser, so one way to do it is to write unit tests that extend ParsingTestCase . 您要做的基本上是在解析器输出的AST上工作,因此一种实现方法是编写扩展ParsingTestCase单元测试。 The initial behavior of those kind of tests is to print a readable version of the AST and compare it with an expected file, but you can override a method to do completely different tests, while keeping the easy way to retrieve a PSI tree: 这类测试的最初行为是打印一个可读版本的AST并将其与expected文件进行比较,但是您可以覆盖一种方法来进行完全不同的测试,同时保留一种简单的方法来检索PSI树:

import com.intellij.testFramework.ParsingTestCase;

public class MyAwesomeTest extends ParsingTestCase {

    public MyAwesomeTest() {
        super("relative/path/to/files", "java", new JavaParserDefinition());
    }

    @Override
    protected boolean skipSpaces() {
        return true;
    }

    public void testEmpty() {
        doTest(true); // this will test relative/path/to/files/Empty.java
    }

    @Override
    protected void checkResult(@NonNls @TestDataFile String targetDataName, final PsiFile file) throws IOException {
        // do your stuff here
    }

}

Note that file names are extracted from test method names (here, Empty ), which can be annoying if you want to test lots of files, especially when their name is only known at runtime. 请注意,文件名是从测试方法名(此处为Empty )中提取的,如果要测试很多文件,尤其是在运行时才知道它们的名称时,这可能会很烦人。 To overcome this, you can replace doTest() with a custom method that does similar things with an additional name argument. 为了克服这个问题,您可以使用自定义方法替换doTest() ,该方法使用附加的name参数来执行类似的操作。

Then to run those tests, you'll have to download IntelliJ (either Ultimate or Community) and add a bunch of Jar files located in Intellij/lib/ to your classpath. 然后,要运行这些测试,您必须下载IntelliJ(Ultimate或Community),并将一堆位于Intellij/lib/的Jar文件添加到类路径中。 Otherwise, it might be possible to run unit tests in IntelliJ's headless mode, but I don't know how. 否则,可以在IntelliJ的无头模式下运行单元测试,但我不知道如何。

Additional info here: https://confluence.jetbrains.com/display/IDEADEV/Testing+IntelliJ+IDEA+Plugins 此处的其他信息: https : //confluence.jetbrains.com/display/IDEADEV/Testing+IntelliJ+IDEA+Plugins

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM