diff --git a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocationProvider.java b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocationProvider.java index 4ce0e979ac72..6731375a8e79 100644 --- a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocationProvider.java +++ b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocationProvider.java @@ -17,6 +17,7 @@ package com.intellij.execution.testframework; import com.intellij.execution.Location; import com.intellij.execution.PsiLocation; +import com.intellij.execution.junit2.PsiMemberParameterizedLocation; import com.intellij.execution.junit2.info.MethodLocation; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -46,26 +47,52 @@ public class JavaTestLocationProvider implements TestLocationProvider { public List getLocation(@NotNull String protocolId, @NotNull String locationData, Project project) { List results = Collections.emptyList(); + final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); if (SUITE_PROTOCOL.equals(protocolId)) { - PsiClass[] classes = JavaPsiFacade.getInstance(project).findClasses(locationData, myScope); + PsiClass[] classes = javaPsiFacade.findClasses(locationData, myScope); if (classes.length > 0) { results = ContainerUtil.newSmartList(); for (PsiClass aClass : classes) { results.add(new PsiLocation(project, aClass)); } } + else { + //parameter root for parameterized tests: ClassName.[paramName] + final String className = StringUtil.getPackageName(locationData); + classes = javaPsiFacade.findClasses(className, myScope); + if (classes.length > 0) { + final String paramName = StringUtil.getShortName(locationData); + results = ContainerUtil.newSmartList(); + for (PsiClass aClass : classes) { + results.add(PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName)); + } + } + } } else if (TEST_PROTOCOL.equals(protocolId)) { final String className = StringUtil.getPackageName(locationData); if (!StringUtil.isEmpty(className)) { - final String methodName = StringUtil.getShortName(locationData); - PsiClass[] classes = JavaPsiFacade.getInstance(project).findClasses(className, myScope); + String methodName = StringUtil.getShortName(locationData); + PsiClass[] classes = javaPsiFacade.findClasses(className, myScope); if (classes.length > 0) { results = ContainerUtil.newSmartList(); for (PsiClass aClass : classes) { PsiMethod[] methods = aClass.findMethodsByName(methodName, true); - for (PsiMethod method : methods) { - results.add(MethodLocation.elementInClass(method, aClass)); + if (methods.length > 0) { + for (PsiMethod method : methods) { + results.add(MethodLocation.elementInClass(method, aClass)); + } + } + else { + //parameterized tests: ClassName.testName[paramName] + final int paramIdx = methodName.indexOf("["); + if (paramIdx > -1 && methodName.endsWith("]")) { + final String paramName = methodName.substring(paramIdx); + methods = aClass.findMethodsByName(methodName.substring(0, paramIdx), true); + for (PsiMethod method : methods) { + results.add(new PsiMemberParameterizedLocation(project, method, aClass, paramName)); + } + } } } } diff --git a/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java b/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java index 73a8b2e96d31..d42b741ad653 100644 --- a/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java +++ b/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java @@ -16,6 +16,7 @@ package com.intellij.execution.junit; import com.intellij.execution.Location; +import com.intellij.execution.junit2.PsiMemberParameterizedLocation; import com.intellij.execution.junit2.info.MethodLocation; import com.intellij.execution.testframework.JavaTestLocationProvider; import com.intellij.execution.testframework.sm.runner.SMTestProxy; @@ -62,4 +63,52 @@ public class JUnitRerunFailedTestsTest extends LightCodeInsightFixtureTestCase final String presentation = TestMethods.getTestPresentation(testProxy, project, searchScope); assertEquals("ChildTest,testMe", presentation); } + + public void testParameterizedTestNavigation() throws Exception { + myFixture.addClass("package org.junit.runner;\n" + + "public @interface RunWith {\n" + + " Class value();\n" + + "}"); + myFixture.addClass("package org.junit.runners; public class Parameterized {}"); + + final PsiClass testClass = myFixture.addClass("import org.junit.Test;\n" + + "import org.junit.runner.RunWith;\n" + + "import org.junit.runners.Parameterized;\n" + + "@RunWith(Parameterized.class)\n" + + "public class MyTest {\n" + + " @Test\n" + + " public void testName1() throws Exception {}\n" + + "}"); + + final Project project = getProject(); + final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(project); + final JavaTestLocationProvider locationProvider = new JavaTestLocationProvider(searchScope); + + final SMTestProxy rootProxy = new SMTestProxy("MyTest", true, "java:suite://MyTest"); + rootProxy.setLocator(locationProvider); + + final SMTestProxy proxyParam = new SMTestProxy("[0]", true, "java:suite://MyTest.[0]"); + proxyParam.setLocator(locationProvider); + + final SMTestProxy parameterizedTestProxy = new SMTestProxy("testName1[0]", false, "java:test://MyTest.testName1[0]"); + parameterizedTestProxy.setLocator(locationProvider); + + final Location rootLocation = rootProxy.getLocation(project, searchScope); + assertNotNull(rootLocation); + assertEquals(testClass, rootLocation.getPsiElement()); + + final Location proxyParamLocation = proxyParam.getLocation(project, searchScope); + assertNotNull(proxyParamLocation); + assertInstanceOf(proxyParamLocation, PsiMemberParameterizedLocation.class); + assertEquals("[0]", ((PsiMemberParameterizedLocation)proxyParamLocation).getParamSetName()); + assertEquals(testClass, proxyParamLocation.getPsiElement()); + + final Location parameterizedTestProxyLocation = parameterizedTestProxy.getLocation(project, searchScope); + assertNotNull(parameterizedTestProxyLocation); + assertInstanceOf(parameterizedTestProxyLocation, PsiMemberParameterizedLocation.class); + assertEquals("[0]", ((PsiMemberParameterizedLocation)parameterizedTestProxyLocation).getParamSetName()); + assertEquals(testClass.getMethods()[0], parameterizedTestProxyLocation.getPsiElement()); + assertEquals(testClass, ((PsiMemberParameterizedLocation)parameterizedTestProxyLocation).getContainingClass()); + assertEquals("MyTest,testName1[0]", TestMethods.getTestPresentation(parameterizedTestProxy, project, searchScope)); + } } diff --git a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java b/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java index c3481145f71a..97a1b4f6c143 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java +++ b/plugins/junit_rt/src/com/intellij/junit4/SMTestSender.java @@ -41,6 +41,7 @@ class SMTestSender extends RunListener { private static final String ORG_JUNIT_COMPARISON_NAME = "org.junit.ComparisonFailure"; private String myCurrentClassName; + private String myParamName; private boolean myIgnoreTopSuite; public void testRunStarted(Description description) throws Exception { @@ -48,6 +49,9 @@ class SMTestSender extends RunListener { } public void testRunFinished(Result result) throws Exception { + if (myParamName != null) { + System.out.println("##teamcity[testSuiteFinished name=\'" + myParamName + "\']"); + } if (myCurrentClassName != null) { System.out.println("##teamcity[testSuiteFinished name=\'" + myCurrentClassName + "\']"); } @@ -62,7 +66,19 @@ class SMTestSender extends RunListener { myCurrentClassName = className; System.out.println("##teamcity[testSuiteStarted name =\'" + myCurrentClassName + "\']"); } - System.out.println("##teamcity[testStarted name=\'" + JUnit4ReflectionUtil.getMethodName(description) + "\']"); + final String methodName = JUnit4ReflectionUtil.getMethodName(description); + final int paramStart = methodName.indexOf('['); + if (paramStart > -1) { + final String paramName = methodName.substring(paramStart, methodName.length()); + if (!paramName.equals(myParamName)) { + if (myParamName != null) { + System.out.println("##teamcity[testSuiteFinished name=\'" + myParamName + "\']"); + } + myParamName = paramName; + System.out.println("##teamcity[testSuiteStarted name =\'" + myParamName + "\']"); + } + } + System.out.println("##teamcity[testStarted name=\'" + methodName + "\']"); } public void testFinished(Description description) throws Exception { @@ -181,10 +197,23 @@ class SMTestSender extends RunListener { for (Iterator iterator = tests.iterator(); iterator.hasNext(); ) { final Object next = iterator.next(); final List childTests = runner.getChildTests(next); - if (childTests.isEmpty() && !pass) { + final Description nextDescription = (Description)next; + if ((childTests.isEmpty() || isParameter(nextDescription)) && !pass) { pass = true; - System.out.println("##teamcity[suiteTreeStarted name=\'" + JUnit4ReflectionUtil.getClassName((Description)description) + - "\' locationHint=\'java:suite://" + JUnit4ReflectionUtil.getClassName((Description)description) + "\']"); + final String className = JUnit4ReflectionUtil.getClassName((Description)description); + String locationHint = className; + if (isParameter((Description)description)) { + final String displayName = nextDescription.getDisplayName(); + final int paramIdx = displayName.indexOf(locationHint); + if (paramIdx > -1) { + locationHint = displayName.substring(paramIdx + locationHint.length()); + if (locationHint.startsWith("(") && locationHint.endsWith(")")) { + locationHint = locationHint.substring(1, locationHint.length() - 1) + "." + className; + } + } + } + System.out.println("##teamcity[suiteTreeStarted name=\'" + className + + "\' locationHint=\'java:suite://" + locationHint + "\']"); } sendTree(runner, next, childTests); } @@ -193,6 +222,11 @@ class SMTestSender extends RunListener { } } + private static boolean isParameter(Description description) { + String displayName = description.getDisplayName(); + return displayName.startsWith("[") && displayName.endsWith("]"); + } + public void sendTree(JUnit4IdeaTestRunner runner, Description description) { final List tests = runner.getChildTests(description); if (tests.isEmpty()) {