From ef0b36a968a9d05b3a7d1cf841d0b91d5509a1ad Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Fri, 6 Sep 2019 21:04:31 +0300 Subject: [PATCH] PY-37841: Do not monkeypatch prepareconfing in pytest: leads to double plugin loading. With testdir fixture, pytest runs test under separate pytest (which may be inline or separate process). Previously we monkeypatched prepareconfig not to call it twice. But this approach fails with testdir, because same config returned twice leading to double plugin registration. See comment in YT GitOrigin-RevId: bd9f11a2a10900fa3c059791d7c0183a20b1ed70 --- python/helpers/pycharm/_jb_pytest_runner.py | 6 +---- python/setup-test-environment/build.gradle | 2 +- .../testRunner/env/pytest/testdir/test_foo.py | 9 +++++++ .../python/testing/PythonPyTestingTest.java | 24 +++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 python/testData/testRunner/env/pytest/testdir/test_foo.py diff --git a/python/helpers/pycharm/_jb_pytest_runner.py b/python/helpers/pycharm/_jb_pytest_runner.py index b11e873676b5..258c2fe5ca1f 100644 --- a/python/helpers/pycharm/_jb_pytest_runner.py +++ b/python/helpers/pycharm/_jb_pytest_runner.py @@ -12,8 +12,6 @@ from _jb_runner_tools import jb_patch_separator, jb_doc_args, JB_DISABLE_BUFFERI from teamcity import pytest_plugin if __name__ == '__main__': - real_prepare_config = config._prepareconfig - path, targets, additional_args = parse_arguments() sys.argv += additional_args joined_targets = jb_patch_separator(targets, fs_glue="/", python_glue="::", fs_to_python_glue=".py::") @@ -34,12 +32,10 @@ if __name__ == '__main__': jb_doc_args("pytest", args) # We need to preparse numprocesses because user may set it using ini file - config_result = real_prepare_config(args, plugins_to_load) + config_result = config._prepareconfig(args, plugins_to_load) if getattr(config_result.option, "numprocesses", None): set_parallel_mode() - config._prepareconfig = lambda _, __: config_result - start_protocol() pytest.main(args, plugins_to_load) diff --git a/python/setup-test-environment/build.gradle b/python/setup-test-environment/build.gradle index aea7b13109d2..05ce98d37fcd 100644 --- a/python/setup-test-environment/build.gradle +++ b/python/setup-test-environment/build.gradle @@ -93,7 +93,7 @@ envs { "2.7.15", ["django==1.11", "tox>=3.8.3", "nose", "pytest", "Twisted", "behave", "lettuce>=0.2.22", "unittest2", "teamcity-messages", "django-nose", "untangle"] + ( Os.isFamily(Os.FAMILY_WINDOWS) ? ['pypiwin32'] : [] ), //win32api is required for pypiwin32 - "python2.7\ndjango\nnose\npytest\nbehave\nlettuce\npackaging\ntox\nunittest2\ntwisted\ndjango-nose\nuntangle", + "python2.7\ndjango\nnose\npytest\nbehave\nlettuce\npackaging\ntox\nunittest2\ntwisted\ndjango-nose\nuntangle\nmessages", true) createPython("py36_django22_full", diff --git a/python/testData/testRunner/env/pytest/testdir/test_foo.py b/python/testData/testRunner/env/pytest/testdir/test_foo.py new file mode 100644 index 000000000000..34be752486d5 --- /dev/null +++ b/python/testData/testRunner/env/pytest/testdir/test_foo.py @@ -0,0 +1,9 @@ +pytest_plugins = "pytester" + + +def test_foo(testdir): + testdir.makefile(".py", test_bar=""" + def test_bar():pass + """) + res = testdir.runpytest() + assert res.ret == 0 diff --git a/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java b/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java index d186ca955cce..c2f7a2cc9af9 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java +++ b/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java @@ -153,6 +153,30 @@ public final class PythonPyTestingTest extends PyEnvTestCase { }); } + @EnvTestTagsRequired(tags = "-messages") //messages registered 2 times when launched with testdir plugin, should be fixed separately + @Test + public void testTestDirFixture() { + runPythonTest( + new PyProcessWithConsoleTestTask("/testRunner/env/pytest/testdir", SdkCreationType.EMPTY_SDK) { + + @NotNull + @Override + protected PyTestTestProcessRunner createProcessRunner() { + return new PyTestTestProcessRunner("test_foo.py", 0); + } + + @Override + protected void checkTestResults(@NotNull final PyTestTestProcessRunner runner, + @NotNull final String stdout, + @NotNull final String stderr, + @NotNull final String all, int exitCode) { + + Assert.assertEquals(stderr, 1, runner.getAllTestsCount()); + Assert.assertEquals(stderr, 1, runner.getPassedTestsCount()); + } + }); + } + /** * Test name must be reported as meta info to be used as argument for "-k" for parametrized tests */