Could someone help me with some guidance to create Functional test for Non Java projects ?
Hi,
I'm new in IntelliJ plugin dev, that's 4 months only I'm struggling with the platform, I anyway succdeed to do some stuffs but now with the help of some of you too, now, I would like to add some functional tests, after having read http://confluence.jetbrains.com/display/IntelliJIDEA/Tests+Prerequisites I've been able to create some basic tests https://github.com/RandoriAS/randori-plugin-intellij/tree/develop/src/test/java/randori/plugin
Now, I need to test some more real life use cases.
My plugin allows the user to code in AS3 and cross compile to JS, it uses its own SDK and compiler.
So, what are the steps, given the described specificities of this plugin to:
- Create programaticaly an empty project/modules using my SDK ?
- Load an existing project/modules ?
I guess that's the basic things to know, don't hesitate to tell me if I need to know some more important things related to the fact it is not a Java project.
Thanks,
-Fred
请先登录再写评论。
Hi Frederic,
When using the test framework, it doesn't matter much whether you're using a Java project or not. Most of the APIs work the same for any kind of project.
The best way to create a project using your SDK is to extend LightPlatformCodeInsightFixtureTestCase, to override the getProjectDescriptor() method and to return your SDK from its getSdk() method.
Loading existing projects in tests is not something that we norrmally do, unless we want to test specifically the project loading code. Instead, we do all the project configuration programmatically in the test code.
Thanks Dmitry,
> The best way to create a project using your SDK is to extend LightPlatformCodeInsightFixtureTestCase, to override the getProjectDescriptor() method and to return your SDK from its getSdk() method
Ok :)
> Loading existing projects in tests is not something that we norrmally do, unless we want to test specifically the project loading code. Instead, we do all the project configuration programmatically in the test code.
Some of the tests I want to implement start from the ground (ie Importing a Randori Project from the sources programaticaly) and verify the imported project corresponds to an existing one, some others will start from an already imported one and test refactoring,... to check there's no regression in my FileChangeListener.
So, will the strategy be starting from the ground and execute all the tests in order ? not loading an already define project/modules later for the refactoring tests but do what is called end-to-end tests, is it what I need to understand ?
More techinicaly, how do I ask IJ to import a project from the sources programaticaly ?
My questions are basic I know but I need to get this basic first :)
Of course you shouldn't have any dependencies between tests. Every test should perform its own setup and not rely on anything done by previous tests.
For testing project import, see ProjectWizardTestCase and its usages.
Thanks Dmitry, I had a look at the ProjectWizardTestCase.importProjectFrom but during the RootsDetectionStep I can't figure out how I can set programaticaly the detectors (I would like to select my custom ModuleType proposed in the comboBox), here is my code but I'm a bit lost, I'm not even sure I can use the ProjectFromSourcesBuilderImpl.getBuilder().setProjectRoots() because the RootsDetectionStep.updateDataModel() is called after and I it will override my changes, I guess I could use getContext().requestNextStep() but I don't know how to deal with setProjectRoots, can you help ?
public void testImportProject() throws Exception {
final ImportFromSourcesProvider provider = new ImportFromSourcesProvider();
importProjectFrom(new File(RandoriTestUtil.getTestDataPath(this) + "simpleProject").getAbsolutePath(), new Consumer<ModuleWizardStep>() {
@Override
public void consume(ModuleWizardStep moduleWizardStep) {
if (moduleWizardStep instanceof ProjectNameStep) {
ProjectNameStep projectNameStep = (ProjectNameStep) moduleWizardStep;
assertEquals(projectNameStep.getProjectName(), "simpleProject");
}
else if (moduleWizardStep instanceof RootsDetectionStep) {
RootsDetectionStep rootsDetectionStep = (RootsDetectionStep) moduleWizardStep;
ProjectFromSourcesBuilderImpl builder = (ProjectFromSourcesBuilderImpl) provider.getBuilder();
}
else if (moduleWizardStep instanceof LibrariesDetectionStep) {
LibrariesDetectionStep librariesDetectionStep = (LibrariesDetectionStep) moduleWizardStep;
}
else if (moduleWizardStep instanceof RandoriSdkStep) {
RandoriSdkStep randoriSdkStep = (RandoriSdkStep) moduleWizardStep;
}
}
}, provider);
}
That's crazy, there's no way to do force the source root detectors, I even tried [1] but didn't change anything :
//RootsDetectionStep rootsDetectionStep = (RootsDetectionStep) moduleWizardStep;
ProjectFromSourcesBuilderImpl builder = (ProjectFromSourcesBuilderImpl) provider.getBuilder();
ProjectStructureDetector detector = ProjectStructureDetector.EP_NAME.findExtension(RandoriProjectStructureDetector.class);
//Collection<ProjectDescriptor> selectedDescriptors = builder.getSelectedDescriptors();
//Collection<DetectedProjectRoot> projectRoots = builder.getProjectRoots(detector);
RandoriWebModuleSourceRoot sourcesRootDetector = new RandoriWebModuleSourceRoot(sourceRootFile);
ConcurrentMultiMap<ProjectStructureDetector, DetectedProjectRoot> roots = new ConcurrentMultiMap<ProjectStructureDetector, DetectedProjectRoot>();
Collection<DetectedProjectRoot> detectedProjectRoots = new HashSet<DetectedProjectRoot>();
detectedProjectRoots.add(sourcesRootDetector);
roots.put(detector, detectedProjectRoots);
builder.setProjectRoots(roots);
I love IntelliJ but it sucks at time or it's me ?
Hi guys,
Is there a reason why nobody answered yet ?
You've been very quick at the beginning to answer and it was very much apreciated, now it turned into more specific stuffs, there is nobody, did I do something wrong or is something in my demand not clear enought ?
Really guys, you're the only ones being able to help me, this forum is made for, so, I hope someone will answer because I'm locked testing my import wizard features.
-Fred
Hi Frederic,
your RandoriProjectStructureDetector should find roots from test data for you, doesn't it?
Sorry if I missed something from previous discussion.
Yes, RandoriProjectStructureDetector detects roots, the point is my plugin depends on com.intellij.flex and the source files of Randori projects have the same type than the ones used by Flex, so, I've got more than one DetectedSourceRoot, my goal in the test of import project wizard is to be able to select one those 3 DetectedSourceRoot (the Flex one labeled "ActionScript", RandoriWebModuleSourceRoot, RandoriLibraryModuleSourceRoot) to then being able to go to the RandoriSdkStep and check my project has been well created with the right SDK, etc...
At the moment, I don't know how programaticaly set the right DetectedSourceRoot (RandoriWebModuleSourceRoot) from the importProjectFrom function.
Am I a bit clearer ?
-Fred
Yes, I see your problem now.
Try to put your detector in front of flex one, like
<projectStructureDetector implementation="MyDetector" order="first"/>
Thanks very much Dmitry, it works.
I just wonder if the Flex project detector does the same, who wins ?
Is there really no way to do that programaticaly ?
My next test will be to setup libraries and modules when I import a project, I hope that's won't be the same problem trying to set them :-)
oups !
So, at the end this solution works well when I have only one module.
As soon, I have a another type of module it is not valid anymore, ex:
-ModuleA: RANDORI_WEB_MODULE
-ModuleB: RANDORI_LIBRARY_MODULE
Now, I set the ProjectStructureDetector order to FIRST, the ActionScript DetectedSourceRoot is not set anymore by default, that's my RandoriWebModuleSourceRoot but for my ModuleB too and that's still a problem.
Any other thoughts ?
Do you need your modules to be imported by different detectors?
Yes, I need both to associate them with my 2 ModuleType RandoriWebModuleType and RandoriLibraryModuleType via my RandoriModuleInsight.createModuleDescriptor :
@Override
protected ModuleDescriptor createModuleDescriptor(File moduleContentRoot,
Collection<DetectedProjectRoot> sourceRoots)
{
ModuleDescriptor moduleDescriptor = null;
String rootTypeName = sourceRoots.iterator().next().getRootTypeName();
if (rootTypeName.equals(RandoriWebModuleType.getInstance().getName()))
moduleDescriptor = new ModuleDescriptor(moduleContentRoot, RandoriWebModuleType.getInstance(), sourceRoots);
else if (rootTypeName.equals(RandoriLibraryModuleType.getInstance().getName()))
moduleDescriptor = new ModuleDescriptor(moduleContentRoot, RandoriLibraryModuleType.getInstance(), sourceRoots);
return moduleDescriptor;
}
I didn't find any other ways to do it.