From a6038b0d723f9a2854cce8defdaa9a10cab5d8c1 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Sun, 16 Apr 2017 00:26:09 +0300 Subject: [PATCH] PY-23549: run files as scripts for py3 unittest (instead of "discovery" engine used for py2) 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 --- python/helpers/pycharm/_jb_unittest_runner.py | 22 ++++++---- .../env/unit/withHyphen/test-foobar.py | 26 ++++++++++++ .../python/testing/PythonUnitTestingTest.java | 41 +++++++++++++++++-- 3 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 python/testData/testRunner/env/unit/withHyphen/test-foobar.py 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 {