diff --git a/python/helpers/pycharm/_jb_unittest_runner.py b/python/helpers/pycharm/_jb_unittest_runner.py index 11c019ffe7f6..f23dce6a38ba 100644 --- a/python/helpers/pycharm/_jb_unittest_runner.py +++ b/python/helpers/pycharm/_jb_unittest_runner.py @@ -1,5 +1,6 @@ # coding=utf-8 import os +import sys from unittest import main from _jb_runner_tools import jb_start_tests, jb_doc_args @@ -10,16 +11,21 @@ if __name__ == '__main__': args = ["python -m unittest"] if path: - discovery_args = ["discover", "-s"] - # Unittest does not support script directly, but it can use "discover" to find all tests in some folder - # filtering by script assert os.path.exists(path), "{0}: No such file or directory".format(path) - if os.path.isfile(path): - discovery_args += [os.path.dirname(path), "-p", os.path.basename(path)] + if sys.version_info > (3, 0) and os.path.isfile(path): + # In Py3 it is possible to run script directly which is much more stable than discovery machinery + # For example it supports hyphens in file names PY-23549 + additional_args = [path] + additional_args else: - discovery_args.append(path) - discovery_args += ["-t", os.getcwd()] # To force unit calculate path relative to this folder - additional_args = discovery_args + additional_args + discovery_args = ["discover", "-s"] + # Unittest in py2 does not support running script directly (and folders in py2 and py3), + # but it can use "discover" to find all tests in some folder (optionally filtering by script) + if os.path.isfile(path): + discovery_args += [os.path.dirname(path), "-p", os.path.basename(path)] + else: + discovery_args.append(path) + discovery_args += ["-t", os.getcwd()] # To force unit calculate path relative to this folder + additional_args = discovery_args + additional_args elif targets: additional_args += targets args += additional_args diff --git a/python/testData/testRunner/env/unit/withHyphen/test-foobar.py b/python/testData/testRunner/env/unit/withHyphen/test-foobar.py new file mode 100644 index 000000000000..d21686d7f154 --- /dev/null +++ b/python/testData/testRunner/env/unit/withHyphen/test-foobar.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +# from falcon import testing +import unittest + + +# class TestAPI(testing.TestCase): + +class TestAPI(unittest.TestCase): + def setUp(self): + + super().setUp() + + +class TestCoverage(TestAPI): + def test_first(self): + + self.assertTrue(1 == 1) + + def test_second(self): + + self.assertFalse(1 == 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java b/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java index 6390ebfb7c28..b92c01733ed0 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java +++ b/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java @@ -23,7 +23,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.EdtTestUtil; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.jetbrains.env.EnvTestTagsRequired; -import com.jetbrains.env.ProcessWithConsoleRunner; import com.jetbrains.env.PyEnvTestCase; import com.jetbrains.env.ut.PyUnitTestProcessRunner; import com.jetbrains.python.PyBundle; @@ -60,6 +59,41 @@ public final class PythonUnitTestingTest extends PyEnvTestCase { }); } + + /** + * Make sure test rerun works when pattern is enabled (PY-23416) + */ + @Test + @EnvTestTagsRequired(tags = "python3") + public void testScriptWithHyphen() throws Exception { + runPythonTest(new PyUnitTestProcessWithConsoleTestTask("testRunner/env/unit/withHyphen", "test-foobar.py") { + + @NotNull + @Override + protected PyUnitTestProcessRunner createProcessRunner() throws Exception { + return new PyUnitTestProcessRunner(toFullPath(myScriptName), 1); + } + + @Override + protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner, + @NotNull final String stdout, + @NotNull final String stderr, + @NotNull final String all) { + if (runner.getCurrentRerunStep() == 0) { + Assert.assertEquals(runner.getFormattedTestTree(), 2, runner.getAllTestsCount()); + Assert.assertEquals(runner.getFormattedTestTree(), 1, runner.getPassedTestsCount()); + Assert.assertEquals(runner.getFormattedTestTree(), 1, runner.getFailedTestsCount()); + } + else { + Assert.assertEquals(runner.getFormattedTestTree(), 1, runner.getAllTestsCount()); + Assert.assertEquals(runner.getFormattedTestTree(), 0, runner.getPassedTestsCount()); + Assert.assertEquals(runner.getFormattedTestTree(), 1, runner.getFailedTestsCount()); + } + } + }); + } + + /** * Make sure test rerun works when pattern is enabled (PY-23416) */ @@ -73,7 +107,8 @@ public final class PythonUnitTestingTest extends PyEnvTestCase { // Full pass is required because it is folder return new PyUnitTestProcessRunner(toFullPath(myScriptName), 2) { @Override - protected void configurationCreatedAndWillLaunch(@NotNull final PyUniversalUnitTestConfiguration configuration) throws IOException { + protected void configurationCreatedAndWillLaunch(@NotNull final PyUniversalUnitTestConfiguration configuration) + throws IOException { super.configurationCreatedAndWillLaunch(configuration); configuration.setPattern("test*"); } @@ -100,7 +135,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase { */ @Test public void testRunModuleAsFile() throws Exception { - runPythonTest(new RunModuleAsFileTask(){ + runPythonTest(new RunModuleAsFileTask() { @NotNull @Override protected PyUnitTestProcessRunner createProcessRunner() throws Exception {