diff --git a/python/testData/testRunner/env/unit/reference_tests.py b/python/testData/testRunner/env/unit/reference_tests.py new file mode 100644 index 000000000000..d60fe9f2cb74 --- /dev/null +++ b/python/testData/testRunner/env/unit/reference_tests.py @@ -0,0 +1,13 @@ +__author__ = 'Ilya.Kazakevich' +import unittest + +class SpamTest(unittest.TestCase): + + def test_1(self): + self.fail() + + +class SpamTest2(unittest.TestCase): + + def test_2(self): + assert False \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java b/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java index a0de60ccc906..f91da241a7a9 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java +++ b/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java @@ -1,13 +1,17 @@ package com.jetbrains.env.python.testing; import com.jetbrains.env.PyEnvTestCase; +import com.jetbrains.env.ut.PyTestTestTask; import com.jetbrains.env.ut.PyUnitTestTask; -import junit.framework.Assert; +import org.hamcrest.Matchers; +import org.junit.Assert; + +import java.util.List; /** * @author traff */ -public class PythonUnitTestingTest extends PyEnvTestCase{ +public class PythonUnitTestingTest extends PyEnvTestCase { public void testUTRunner() { runPythonTest(new PyUnitTestTask("/testRunner/env/unit", "test1.py") { @@ -80,6 +84,42 @@ public class PythonUnitTestingTest extends PyEnvTestCase{ }); } + /** + * Ensures file references are highlighted for python traceback + */ + public void testUnitTestFileReferences() { + final String fileName = "reference_tests.py"; + runPythonTest(new PyUnitTestTask("/testRunner/env/unit", fileName) { + + @Override + public void after() { + final List fileNames = getHighlightedStrings().second; + Assert.assertThat("Wrong number of highlighted entries", fileNames, Matchers.hasSize(2)); + // UnitTest highlights file name + Assert.assertThat("Bad line highlighted", fileNames, Matchers.everyItem(Matchers.endsWith(fileName))); + } + }); + } + + /** + * Ensures file references are highlighted for pytest traceback + */ + public void testPyTestFileReferences() { + final String fileName = "reference_tests.py"; + runPythonTest(new PyTestTestTask("/testRunner/env/unit", fileName) { + + @Override + public void after() { + final List fileNames = getHighlightedStrings().second; + Assert.assertThat("No lines highlighted", fileNames, Matchers.not(Matchers.empty())); + // PyTest highlights file:line_number + Assert.assertThat("Bad line highlighted", fileNames, Matchers.everyItem(Matchers.anyOf(Matchers.endsWith("reference_tests.py:13"), + Matchers.endsWith("reference_tests.py:7")))); + } + }); + } + + public void testDependent() { runPythonTest(new PyUnitTestTask("/testRunner/env/unit", "dependentTests/test_my_class.py") { diff --git a/python/testSrc/com/jetbrains/env/ut/PyUnitTestTask.java b/python/testSrc/com/jetbrains/env/ut/PyUnitTestTask.java index 633885453ff9..6520450c24ee 100644 --- a/python/testSrc/com/jetbrains/env/ut/PyUnitTestTask.java +++ b/python/testSrc/com/jetbrains/env/ut/PyUnitTestTask.java @@ -7,6 +7,7 @@ import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.impl.ConsoleViewImpl; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; @@ -15,17 +16,20 @@ import com.intellij.execution.runners.ExecutionEnvironmentBuilder; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.testframework.AbstractTestProxy; import com.intellij.execution.testframework.Filter; -import com.intellij.execution.testframework.Printable; import com.intellij.execution.testframework.sm.runner.SMTestProxy; -import com.intellij.execution.testframework.sm.runner.ui.MockPrinter; import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView; import com.intellij.execution.testframework.sm.runner.ui.TestResultsViewer; +import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.RangeHighlighterEx; +import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.util.Processor; @@ -43,6 +47,8 @@ import org.jetbrains.annotations.Nullable; import org.junit.Assert; import java.io.File; +import java.util.ArrayList; +import java.util.List; /** * Tasks to run unit test configurations. @@ -317,6 +323,36 @@ public abstract class PyUnitTestTask extends PyExecutionFixtureTestTask { return myTestProxy.collectChildren(NOT_SUIT.and(Filter.PASSED)).size(); } + /** + * Gets highlighted information from test console. Some parts of output (like file links) may be highlighted, and you need to check them. + * + * @return pair of [[ranges], [texts]] where range is [from,to] in doc. for each region, and "text" is text extracted from this region. + * For example assume that in document "spam eggs ham" words "ham" and "spam" are highlighted. + * You should have 2 ranges (0, 4) and (10, 13) and 2 strings (spam and ham) + */ + @NotNull + public final Pair>, List> getHighlightedStrings() { + final ConsoleView console = myConsoleView.getConsole(); + assert console instanceof ConsoleViewImpl : "Console has no editor!"; + final Editor editor = ((ConsoleViewImpl)console).getEditor(); + final List resultStrings = new ArrayList(); + final List> resultRanges = new ArrayList>(); + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + for (final RangeHighlighter highlighter : editor.getMarkupModel().getAllHighlighters()) { + if (highlighter instanceof RangeHighlighterEx) { + final int start = ((RangeHighlighterEx)highlighter).getAffectedAreaStartOffset(); + final int end = ((RangeHighlighterEx)highlighter).getAffectedAreaEndOffset(); + resultRanges.add(Pair.create(start, end)); + resultStrings.add(editor.getDocument().getText().substring(start, end)); + } + } + } + }); + return Pair.create(resultRanges, resultStrings); + } + public void assertFinished() { Assert.assertTrue("State is " + myTestProxy.getMagnitudeInfo().getTitle() + "\n" + output(), myTestProxy.wasLaunched() && !myTestProxy.wasTerminated());