test discovery for testng tests

This commit is contained in:
Anna Kozlova
2015-07-16 12:53:17 +03:00
parent f19dd5dd8c
commit 5cdf67d588
9 changed files with 280 additions and 50 deletions
@@ -16,8 +16,6 @@
package com.intellij.execution.testDiscovery;
import com.intellij.codeInsight.actions.FormatChangedTextUtil;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.testframework.SearchForTestsTask;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
@@ -34,29 +32,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.*;
public abstract class TestDiscoverySearchTask extends SearchForTestsTask {
private final Pair<String, String> myPosition;
private final String myChangeList;
public TestDiscoverySearchTask(Project project, ServerSocket socket, Pair<String, String> position, String changeList) {
super(project, socket);
myPosition = position;
myChangeList = changeList;
}
protected abstract void writeFoundPatterns(Set<String> patterns) throws ExecutionException;
@Override
protected void search() throws ExecutionException {
final Project project = getProject();
public class TestDiscoverySearchHelper {
public static Set<String> search(final Project project, final Pair<String, String> position, final String changeList) {
final Set<String> patterns = new LinkedHashSet<String>();
if (myPosition != null) {
if (position != null) {
try {
final Collection<String> testsByMethodName = TestDiscoveryIndex
.getInstance(project).getTestsByMethodName(myPosition.first, myPosition.second);
.getInstance(project).getTestsByMethodName(position.first, position.second);
if (testsByMethodName != null) {
for (String pattern : testsByMethodName) {
patterns.add(pattern.replace('-', ','));
@@ -67,7 +51,7 @@ public abstract class TestDiscoverySearchTask extends SearchForTestsTask {
}
}
else {
final List<VirtualFile> files = getAffectedFiles();
final List<VirtualFile> files = getAffectedFiles(changeList, project);
final PsiManager psiManager = PsiManager.getInstance(project);
for (final VirtualFile file : files) {
@@ -103,16 +87,16 @@ public abstract class TestDiscoverySearchTask extends SearchForTestsTask {
});
}
}
writeFoundPatterns(patterns);
return patterns;
}
@NotNull
private List<VirtualFile> getAffectedFiles() {
final ChangeListManager changeListManager = ChangeListManager.getInstance(getProject());
if (myChangeList == null) {
private static List<VirtualFile> getAffectedFiles(String changeListName, Project project) {
final ChangeListManager changeListManager = ChangeListManager.getInstance(project);
if (changeListName == null) {
return changeListManager.getAffectedFiles();
}
final LocalChangeList changeList = changeListManager.findChangeList(myChangeList);
final LocalChangeList changeList = changeListManager.findChangeList(changeListName);
if (changeList != null) {
List<VirtualFile> files = new ArrayList<VirtualFile>();
for (Change change : changeList.getChanges()) {
@@ -130,12 +114,8 @@ public abstract class TestDiscoverySearchTask extends SearchForTestsTask {
return Collections.emptyList();
}
@Override
protected void onFound() {
}
@Nullable
protected static LinkedHashSet<String> collectPatterns(PsiMethod psiMethod) {
private static LinkedHashSet<String> collectPatterns(PsiMethod psiMethod) {
LinkedHashSet<String> patterns = new LinkedHashSet<String>();
final PsiClass containingClass = psiMethod.getContainingClass();
if (containingClass != null) {
@@ -23,9 +23,8 @@ import com.intellij.execution.junit.JUnitConfigurationType;
import com.intellij.execution.junit.TestObject;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testDiscovery.TestDiscoveryConfiguration;
import com.intellij.execution.testDiscovery.TestDiscoverySearchTask;
import com.intellij.execution.testDiscovery.TestDiscoverySearchHelper;
import com.intellij.execution.testframework.SearchForTestsTask;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.refactoring.listeners.RefactoringElementListener;
@@ -69,11 +68,15 @@ public class JUnitTestDiscoveryConfiguration extends TestDiscoveryConfiguration
@Override
public SearchForTestsTask createSearchingForTestsTask() {
return new TestDiscoverySearchTask(getProject(), myServerSocket, getPosition(), getChangeList()) {
return new SearchForTestsTask(getProject(), myServerSocket) {
@Override
protected void writeFoundPatterns(Set<String> patterns) throws ExecutionException {
protected void search() throws ExecutionException {
final Set<String> patterns = TestDiscoverySearchHelper.search(getProject(), getPosition(), getChangeList());
addClassesListToJavaParameters(patterns, FunctionUtil.<String>id(), "", false, getJavaParameters());
}
@Override
protected void onFound() {}
};
}
+6
View File
@@ -74,7 +74,13 @@
implementationClass="com.theoryinpractice.testng.inspection.TestNGDataProviderInspection" displayName="Data provider problems"
groupName="TestNG" enabledByDefault="true" level="WARNING"/>
<programRunner implementation="com.theoryinpractice.testng.configuration.TestNGDebuggerRunner"/>
<runConfigurationProducer
implementation="com.theoryinpractice.testng.configuration.testDiscovery.TestNGTestDiscoveryConfigurationProducer"/>
<configurationType implementation="com.theoryinpractice.testng.configuration.testDiscovery.TestNGTestDiscoveryConfigurationType"/>
</extensions>
<extensions defaultExtensionNs="com.theoryinpractice.testng">
<listener implementation="org.testng.TestNGTestDiscoveryListener"/>
</extensions>
<extensionPoints >
<extensionPoint qualifiedName="com.theoryinpractice.testng.listener" interface="org.testng.IDEATestNGListener"/>
</extensionPoints>
@@ -23,10 +23,7 @@ import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.process.*;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.testframework.Printable;
import com.intellij.execution.testframework.Printer;
import com.intellij.execution.testframework.TestFrameworkRunningModel;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.execution.testframework.*;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -0,0 +1,89 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.theoryinpractice.testng.configuration.testDiscovery;
import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.*;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testDiscovery.TestDiscoveryConfiguration;
import com.intellij.execution.testDiscovery.TestDiscoverySearchHelper;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.theoryinpractice.testng.configuration.SearchingForTestsTask;
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
import com.theoryinpractice.testng.configuration.TestNGConfigurationType;
import com.theoryinpractice.testng.configuration.TestNGRunnableState;
import com.theoryinpractice.testng.model.TestNGTestPattern;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public class TestNGTestDiscoveryConfiguration extends TestDiscoveryConfiguration {
public TestNGTestDiscoveryConfiguration(String name, Project project, ConfigurationFactory factory) {
super(name, new JavaRunConfigurationModule(project, false), factory,
new TestNGConfiguration("", project, TestNGConfigurationType.getInstance().getConfigurationFactories()[0]));
}
@Override
protected ModuleBasedConfiguration createInstance() {
final TestNGTestDiscoveryConfigurationType configurationType =
ConfigurationTypeUtil.findConfigurationType(TestNGTestDiscoveryConfigurationType.class);
final ConfigurationFactory[] factories = configurationType.getConfigurationFactories();
return new TestNGTestDiscoveryConfiguration(getName(), getProject(), factories[0]);
}
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException {
return new TestNGTestDiscoveryRunnableState(environment);
}
@Nullable
@Override
public RefactoringElementListener getRefactoringElementListener(PsiElement element) {
return null;
}
private class TestNGTestDiscoveryRunnableState extends TestNGRunnableState {
public TestNGTestDiscoveryRunnableState(ExecutionEnvironment environment) {
super(environment, ((TestNGConfiguration)myDelegate));
}
@Override
public SearchingForTestsTask createSearchingForTestsTask() {
return new SearchingForTestsTask(myServerSocket, getConfiguration(), myTempFile, client) {
@Override
protected void search() throws CantRunException {
myClasses.clear();
final Set<String> patterns = TestDiscoverySearchHelper.search(getProject(), getPosition(), getChangeList());
final Module module = getConfigurationModule().getModule();
final GlobalSearchScope searchScope =
module != null ? GlobalSearchScope.moduleWithDependenciesScope(module) : GlobalSearchScope.projectScope(getProject());
TestNGTestPattern.fillTestObjects(myClasses, patterns, TestSearchScope.MODULE_WITH_DEPENDENCIES,
TestNGTestDiscoveryConfiguration.this, searchScope);
}
};
}
}
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.theoryinpractice.testng.configuration.testDiscovery;
import com.intellij.execution.configurations.ConfigurationTypeUtil;
import com.intellij.execution.testDiscovery.TestDiscoveryConfigurationProducer;
public class TestNGTestDiscoveryConfigurationProducer extends TestDiscoveryConfigurationProducer {
protected TestNGTestDiscoveryConfigurationProducer() {
super(ConfigurationTypeUtil.findConfigurationType(TestNGTestDiscoveryConfigurationType.class));
}
}
@@ -0,0 +1,71 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.theoryinpractice.testng.configuration.testDiscovery;
import com.intellij.execution.configuration.ConfigurationFactoryEx;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.configurations.ModuleBasedConfiguration;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import icons.TestngIcons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class TestNGTestDiscoveryConfigurationType implements ConfigurationType {
private final ConfigurationFactory myFactory;
public TestNGTestDiscoveryConfigurationType() {
myFactory = new ConfigurationFactoryEx(this) {
public RunConfiguration createTemplateConfiguration(Project project) {
return new TestNGTestDiscoveryConfiguration("", project, this);
}
@Override
public void onNewConfigurationCreated(@NotNull RunConfiguration configuration) {
((ModuleBasedConfiguration)configuration).onNewConfigurationCreated();
}
};
}
@Override
public String getDisplayName() {
return "TestNG Test Discovery";
}
@Override
public String getConfigurationTypeDescription() {
return "Runs TestNG tests which passed changed code";
}
@Override
public Icon getIcon() {
return TestngIcons.TestNG;
}
@NotNull
@Override
public String getId() {
return "TestNGTestDiscovery";
}
@Override
public ConfigurationFactory[] getConfigurationFactories() {
return new ConfigurationFactory[] {myFactory};
}
}
@@ -16,6 +16,7 @@
package com.theoryinpractice.testng.model;
import com.intellij.execution.CantRunException;
import com.intellij.execution.configurations.ModuleBasedConfiguration;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
import com.intellij.execution.testframework.SourceScope;
@@ -51,7 +52,16 @@ public class TestNGTestPattern extends TestNGTestObject {
public void fillTestObjects(Map<PsiClass, Map<PsiMethod, List<String>>> classes)
throws CantRunException {
final TestData data = myConfig.getPersistantData();
for (final String pattern : data.getPatterns()) {
final Set<String> patterns = data.getPatterns();
fillTestObjects(classes, patterns, myConfig.getPersistantData().getScope(), myConfig, getSearchScope());
}
public static void fillTestObjects(final Map<PsiClass, Map<PsiMethod, List<String>>> classes,
final Set<String> patterns,
final TestSearchScope testSearchScope,
final ModuleBasedConfiguration config,
final GlobalSearchScope searchScope) throws CantRunException {
for (final String pattern : patterns) {
final String className;
final String methodName;
if (pattern.contains(",")) {
@@ -66,7 +76,8 @@ public class TestNGTestPattern extends TestNGTestObject {
@Nullable
@Override
public PsiClass compute() {
return ClassUtil.findPsiClass(PsiManager.getInstance(myConfig.getProject()), className.replace('/', '.'), null, true, getSearchScope());
return ClassUtil
.findPsiClass(PsiManager.getInstance(config.getProject()), className.replace('/', '.'), null, true, searchScope);
}
});
if (psiClass != null) {
@@ -78,20 +89,19 @@ public class TestNGTestPattern extends TestNGTestObject {
});
if (hasTest) {
if (StringUtil.isEmpty(methodName)) {
calculateDependencies(null, classes, getSearchScope(), psiClass);
calculateDependencies(null, classes, searchScope, psiClass);
}
else {
collectTestMethods(classes, psiClass, methodName, getSearchScope());
collectTestMethods(classes, psiClass, methodName, searchScope);
}
} else {
throw new CantRunException("No tests found in class " + className);
}
}
}
if (classes.size() != data.getPatterns().size()) {
TestSearchScope scope = myConfig.getPersistantData().getScope();
if (classes.size() != patterns.size()) {
final List<Pattern> compilePatterns = new ArrayList<Pattern>();
for (String p : data.getPatterns()) {
for (String p : patterns) {
final Pattern compilePattern;
try {
compilePattern = Pattern.compile(p);
@@ -101,9 +111,10 @@ public class TestNGTestPattern extends TestNGTestObject {
}
compilePatterns.add(compilePattern);
}
final SourceScope sourceScope = scope.getSourceScope(myConfig);
final SourceScope sourceScope = testSearchScope.getSourceScope(config);
TestClassFilter projectFilter =
new TestClassFilter(sourceScope != null ? sourceScope.getGlobalSearchScope() : GlobalSearchScope.allScope(myConfig.getProject()), myConfig.getProject(), true, true){
new TestClassFilter(sourceScope != null ? sourceScope.getGlobalSearchScope() : GlobalSearchScope.allScope(config.getProject()),
config.getProject(), true, true){
@Override
public boolean isAccepted(PsiClass psiClass) {
if (super.isAccepted(psiClass)) {
@@ -116,9 +127,9 @@ public class TestNGTestPattern extends TestNGTestObject {
return false;
}
};
calculateDependencies(null, classes, getSearchScope(), TestNGUtil.getAllTestClasses(projectFilter, false));
calculateDependencies(null, classes, searchScope, TestNGUtil.getAllTestClasses(projectFilter, false));
if (classes.size() == 0) {
throw new CantRunException("No tests found in for patterns \"" + StringUtil.join(data.getPatterns(), " || ") + '\"');
throw new CantRunException("No tests found in for patterns \"" + StringUtil.join(patterns, " || ") + '\"');
}
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.testng;
import com.intellij.execution.TestDiscoveryListener;
public class TestNGTestDiscoveryListener extends TestDiscoveryListener implements IDEATestNGListener {
public void onTestStart(ITestResult result) {
testStarted(result.getTestClass().getName(), result.getTestName());
}
public void onTestSuccess(ITestResult result) {
onTestEnded(result);
}
public void onTestFailure(ITestResult result) {
onTestEnded(result);
}
public void onTestSkipped(ITestResult result) {
onTestEnded(result);
}
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
onTestEnded(result);
}
public void onStart(ITestContext context) {}
public void onFinish(ITestContext context) {}
private void onTestEnded(ITestResult result) {
testFinished(result.getTestClass().getName(), result.getName());
}
}