Complex test project setup with multiple modules

Hi all,

I'd like to be able to create a complex project structure with multiple modules during my tests; I can't seem to find any examples of this on the testing documentation page
Is there a way to create multiple modules and make use of myFixture to populate these modules perhaps?

I am hoping to be able to test a complex maven project which has multiple modules, to ensure that my Converters/Contribitors are scoped correctly, and my annotators work as expected across maven modules.

Cheers

4 comments

    final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder =
      IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName());
    final JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);


You can call addModule() multiple times as needed.
0

Thanks for the reply Dmitry; Using your example code I get the following exception

java.lang.AssertionError: interface com.intellij.testFramework.builders.JavaModuleFixtureBuilder
     at com.intellij.testFramework.fixtures.impl.HeavyTestFixtureBuilderImpl.a(HeavyTestFixtureBuilderImpl.java:48)
     at com.intellij.testFramework.fixtures.impl.HeavyTestFixtureBuilderImpl.addModule(HeavyTestFixtureBuilderImpl.java:61)
     at me.alanfoster.camelus.blueprint.dom.inspection.ModuleSupportTest.setUp(ModuleSupportTest.java:20)
     at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
     at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
     at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)


However if I change the code call JavaTestFixtureFactory, which actually seems to call IdeaTestFixtureFactory behind the scenes, it doesn't give this exception...
This might be related to the static initialisation block within JavaTestFixtureFactory perhaps?


final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = JavaTestFixtureFactory.createFixtureBuilder(getName());

Hopefully this will still allow me to get going in the right direction with tests though :)

0
Hi again Dmitry,

I've now wired up a quick test to ensure i'm using the builder API correctly - which is now passing.
It'd be great if you could check the small code snippet out to see if i'm using the API incorrectly :)





 
public class ModuleSupportTest extends TestCase {
    // Project test fixture which points to the root src content folder
    protected JavaCodeInsightTestFixture myFixture;

    // Direct access to the created modules
    protected Module myFirstModule;
    protected Module mySecondModule;

    // Setup creates a new project test fixture + two modules
    @Override
    public void setUp() throws Exception {
        super.setUp();

        final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = JavaTestFixtureFactory.createFixtureBuilder(getName());
        myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
        myFixture.setTestDataPath(getTestDataPath());

        final ModuleFixture firstModuleFixture = newModule(projectBuilder, "0");
        final ModuleFixture secondModuleFixture = newModule(projectBuilder, "1");

        // Call setup on our project fixture, which now allows us to access the ModuleFixture's modules without exception
        myFixture.setUp();

        myFirstModule = firstModuleFixture.getModule();
        mySecondModule = secondModuleFixture.getModule();
    }

    // Creates a new java 1.7 module and adds it to the project
    private ModuleFixture newModule(TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder, String contentRoot) throws Exception {
        final JavaModuleFixtureBuilder firstProjectBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
        firstProjectBuilder.setLanguageLevel(LanguageLevel.JDK_1_7);
        String tempDirPath = myFixture.getTempDirPath();

        // Create a new content root for each module, and create a directory for it manually
        String contentRootPath = tempDirPath + "/" + contentRoot;
        new File(contentRootPath).mkdir();

        // Call the builder
        ModuleFixture moduleFixture = firstProjectBuilder
                .addContentRoot(contentRootPath)
                .addSourceRoot("src")
                .getFixture();

        return moduleFixture;
    }

    @Override
    public void tearDown() throws Exception {
        super.tearDown();
        myFixture.tearDown();
    }

    public String getTestDataPath() {
        return TestHelper.getTestDataPath();
    }

    public void testFileCopiesSuccessfullyIntoTwoDifferentModules() {
        // Copy two different files into both modules separately
        myFixture.copyFileToProject("blueprint/dom/inspection/OneTwoThreeFourBeans.xml", myFirstModule.getName() + "/src/OneTwoThreeFourBeans.xml");
        myFixture.copyFileToProject("blueprint/dom/inspection/TwoThreeFourFiveBeans.xml", mySecondModule.getName() + "/src/TwoThreeFourFiveBeans.xml");

        Collection<VirtualFile> virtualFilesTwo = FileBasedIndex.getInstance().getContainingFiles(
                FileTypeIndex.NAME, XmlFileType.INSTANCE, mySecondModule.getModuleContentScope());
        Assert.assertEquals("The second module should only have one xml file available within its content scope", 1, virtualFilesTwo.size());
    }
}


Some of the things i'm unsure about are
1) Why the generated modules don't contain *.iml files within each created module
2) Should I be creating the module contentRootPath directories myself?

Many thanks,
Alan

0

The code looks correct to me. The .iml files will be created on disk if you call Project.save() (which actually doesn't have any benefit if you aren't testing specifically the code that saves or loads some project settings). The content root does need to be created manually.

0

Please sign in to leave a comment.