mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
PY-2410: Support twisted.trial
Trial is test framework for Twisted much like unittests. It is fully supported on Leonid side, we only need to create wrappers. There were too many places with framework naming code making it pretty hard to support new frameworks. It is now unified. Any service (except framework-specific) should work via PyTestFrameworkService to obtain list of frameworks and its
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
Plugin to support twisted trial.
|
||||
|
||||
From: http://twistedmatrix.com/documents/13.1.0/core/howto/plugin.html
|
||||
if a directory which has been added to sys.path (typically by adding it to the PYTHONPATH environment variable) contains a directory
|
||||
named twisted/plugins/, each .py file in that directory will be loaded as a source of plugins.
|
||||
@@ -0,0 +1,37 @@
|
||||
import sys
|
||||
from teamcity.unittestpy import TeamcityTestResult
|
||||
from twisted.trial.reporter import Reporter
|
||||
from twisted.python.failure import Failure
|
||||
from twisted.plugins.twisted_trial import _Reporter
|
||||
|
||||
|
||||
class FailureWrapper(Failure):
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.value[key]
|
||||
|
||||
|
||||
class TeamcityReporter(TeamcityTestResult, Reporter):
|
||||
|
||||
def __init__(self,
|
||||
stream=sys.stdout,
|
||||
tbformat='default',
|
||||
realtime=False,
|
||||
publisher=None):
|
||||
TeamcityTestResult.__init__(self)
|
||||
Reporter.__init__(self,
|
||||
stream=stream,
|
||||
tbformat=tbformat,
|
||||
realtime=realtime,
|
||||
publisher=publisher)
|
||||
|
||||
def addError(self, test, failure, *k):
|
||||
super(TeamcityReporter, self).addError(test, FailureWrapper(failure), *k)
|
||||
|
||||
|
||||
Teamcity = _Reporter("Teamcity Reporter",
|
||||
"twisted.plugins.teamcity_plugin",
|
||||
description="teamcity messages",
|
||||
longOpt="teamcity",
|
||||
shortOpt="teamcity",
|
||||
klass="TeamcityReporter")
|
||||
28
python/helpers/pycharm/_jb_trialtest_runner.py
Normal file
28
python/helpers/pycharm/_jb_trialtest_runner.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# coding=utf-8
|
||||
import os
|
||||
from pprint import pprint
|
||||
|
||||
from _jb_runner_tools import jb_start_tests, jb_doc_args
|
||||
from twisted.scripts import trial
|
||||
import sys
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# This folder should be in sys.path because teamcity twisted plugin is there
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "__jb.for_twisted"))
|
||||
|
||||
path, targets, additional_args = jb_start_tests()
|
||||
|
||||
sys.path.append(os.getcwd()) # Current dir must be in sys.path according to trial docs
|
||||
|
||||
sys.argv.append("--reporter=teamcity")
|
||||
if path:
|
||||
assert os.path.exists(path), path + " does not exist"
|
||||
# assert os.path.isfile(path), path + " is folder. Provide its name as python target (dot separated)"
|
||||
sys.argv.append(os.path.normpath(path))
|
||||
elif targets:
|
||||
sys.argv += targets
|
||||
|
||||
sys.argv += additional_args
|
||||
jb_doc_args("trial", sys.argv[1:])
|
||||
trial.run()
|
||||
@@ -1,4 +1,7 @@
|
||||
Test runners wraps python framework and provides teamcity protocol.
|
||||
They are are distributed separately.
|
||||
Copy latest version from https://github.com/JetBrains/teamcity-messages.git/teamcity
|
||||
See https://confluence.jetbrains.com/display/~link/PyCharm+test+runners+protocol
|
||||
See https://confluence.jetbrains.com/display/~link/PyCharm+test+runners+protocol
|
||||
|
||||
When updating, place "twisted.plugins" one level up because "twisted" should be in sys.path.
|
||||
See twisted/plugins/README.txt
|
||||
@@ -210,6 +210,7 @@ public class PyNames {
|
||||
|
||||
public static final String NOSE_TEST = "nose";
|
||||
public static final String PY_TEST = "pytest";
|
||||
public static final String TRIAL_TEST = "trial";
|
||||
|
||||
public static final String TEST_CASE = "TestCase";
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ envs {
|
||||
packages = ["pip", "setuptools"]
|
||||
_64Bits = true
|
||||
|
||||
conda "django19", "2.7", ["django==1.9", "tox", "nose", "pytest", "behave", "lettuce>=0.2.22", "unittest2", "teamcity-messages"], true
|
||||
textfile "django19/tags.txt", "python2.7\ndjango\nnose\npytest\nbehave\nlettuce\npackaging\ntox\nunittest2"
|
||||
conda "django19", "2.7", ["django==1.9", "tox", "nose", "pytest", "Twisted", "behave", "lettuce>=0.2.22", "unittest2", "teamcity-messages"], true
|
||||
textfile "django19/tags.txt", "python2.7\ndjango\nnose\npytest\nbehave\nlettuce\npackaging\ntox\nunittest2\ntwisted"
|
||||
|
||||
conda "django110", "3.4", ["django==1.10", "django-nose"], false
|
||||
textfile "django110/tags.txt", "python3.4\ndjango\nskeletons\ndjango-nose"
|
||||
|
||||
@@ -817,6 +817,8 @@ runcfg.pytest.target=&Target:
|
||||
runcfg.pytest.parameters=&Options:
|
||||
runcfg.pytest.keywords=&Keywords:
|
||||
|
||||
### trial run conf
|
||||
runcfg.trial.display_name=Twsited Trial
|
||||
|
||||
### test run configuration
|
||||
runcfg.test.display_name=Python tests
|
||||
|
||||
@@ -60,6 +60,7 @@ public enum PythonHelper implements HelperPackage {
|
||||
|
||||
UNITTEST("pycharm", "_jb_unittest_runner"),
|
||||
PYTEST("pycharm", "_jb_pytest_runner"),
|
||||
TRIAL("pycharm", "_jb_trialtest_runner"),
|
||||
NOSE("pycharm", "_jb_nosetest_runner"),
|
||||
|
||||
BEHAVE("pycharm", "behave_runner"),
|
||||
|
||||
@@ -38,8 +38,9 @@ public class PyTestFrameworkService implements PersistentStateComponent<PyTestFr
|
||||
|
||||
public Map<String, Boolean> SDK_TO_PYTEST = new HashMap<>();
|
||||
public Map<String, Boolean> SDK_TO_NOSETEST = new HashMap<>();
|
||||
public Map<String, Boolean> SDK_TO_TRIALTEST = new HashMap<>();
|
||||
|
||||
private static final String[] FRAMEWORK_NAMES = {PyNames.PY_TEST, PyNames.NOSE_TEST};
|
||||
private static final String[] FRAMEWORK_NAMES = {PyNames.PY_TEST, PyNames.NOSE_TEST, PyNames.TRIAL_TEST};
|
||||
|
||||
@Override
|
||||
public PyTestFrameworkService getState() {
|
||||
@@ -62,6 +63,17 @@ public class PyTestFrameworkService implements PersistentStateComponent<PyTestFr
|
||||
return FRAMEWORK_NAMES.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pypi package that contains this framework
|
||||
*/
|
||||
@NotNull
|
||||
public static String getPackageByFramework(@NotNull final String frameworkName) {
|
||||
if (frameworkName.equals(PyNames.TRIAL_TEST)) {
|
||||
return "Twisted";
|
||||
}
|
||||
return frameworkName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getSdkReadableNameByFramework(@NotNull final String frameworkName) {
|
||||
switch (frameworkName) {
|
||||
@@ -71,6 +83,9 @@ public class PyTestFrameworkService implements PersistentStateComponent<PyTestFr
|
||||
case PyNames.NOSE_TEST: {
|
||||
return PyBundle.message("runcfg.nosetests.display_name");
|
||||
}
|
||||
case PyNames.TRIAL_TEST: {
|
||||
return PyBundle.message("runcfg.trial.display_name");
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown framework " + frameworkName);
|
||||
}
|
||||
@@ -84,6 +99,9 @@ public class PyTestFrameworkService implements PersistentStateComponent<PyTestFr
|
||||
case PyNames.NOSE_TEST: {
|
||||
return SDK_TO_NOSETEST;
|
||||
}
|
||||
case PyNames.TRIAL_TEST: {
|
||||
return SDK_TO_TRIALTEST;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown framework " + frameworkName);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ private fun VirtualFile.asPyFile(project: Project): PyFile? {
|
||||
class PyTestLegacyConfigurationAdapter<in T : PyAbstractTestConfiguration>(newConfig: T)
|
||||
: JDOMExternalizable {
|
||||
|
||||
private val configManager: LegacyConfigurationManager<*, *>
|
||||
private val configManager: LegacyConfigurationManager<*, *>?
|
||||
private val project = newConfig.project
|
||||
|
||||
/**
|
||||
@@ -168,12 +168,17 @@ class PyTestLegacyConfigurationAdapter<in T : PyAbstractTestConfiguration>(newCo
|
||||
configManager = LegacyConfigurationManagerUnit(newConfig)
|
||||
}
|
||||
else -> {
|
||||
throw IllegalAccessException("Unknown config: $newConfig")
|
||||
configManager = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun readExternal(element: Element) {
|
||||
val configManager = configManager
|
||||
if (configManager == null) {
|
||||
containsLegacyInformation = false
|
||||
return
|
||||
}
|
||||
val legacyConfig = configManager.legacyConfig
|
||||
if (legacyConfig is RunConfiguration) {
|
||||
(legacyConfig as RunConfiguration).readExternal(element)
|
||||
@@ -190,7 +195,7 @@ class PyTestLegacyConfigurationAdapter<in T : PyAbstractTestConfiguration>(newCo
|
||||
|
||||
override fun writeExternal(element: Element) {
|
||||
if (containsLegacyInformation ?: return) {
|
||||
val legacyConfig = configManager.legacyConfig
|
||||
val legacyConfig = configManager?.legacyConfig
|
||||
if (legacyConfig is RunConfiguration) {
|
||||
(legacyConfig as RunConfiguration).writeExternal(element)
|
||||
}
|
||||
@@ -203,7 +208,7 @@ class PyTestLegacyConfigurationAdapter<in T : PyAbstractTestConfiguration>(newCo
|
||||
fun copyFromLegacyIfNeeded() {
|
||||
assert(project.isInitialized, { "Initialized project required" })
|
||||
if (containsLegacyInformation ?: return && !(legacyInformationCopiedToNew ?: false) && SwingUtilities.isEventDispatchThread()) {
|
||||
configManager.copyFromLegacy()
|
||||
configManager?.copyFromLegacy()
|
||||
legacyInformationCopiedToNew = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,8 @@ import com.jetbrains.reflection.getProperties
|
||||
val factories: Array<PythonConfigurationFactoryBase> = arrayOf(
|
||||
PyUnitTestFactory,
|
||||
PyTestFactory,
|
||||
PyNoseTestFactory)
|
||||
PyNoseTestFactory,
|
||||
PyTrialTestFactory)
|
||||
|
||||
internal fun getAdditionalArgumentsPropertyName() = com.jetbrains.python.testing.PyAbstractTestConfiguration::additionalArguments.name
|
||||
|
||||
|
||||
60
python/src/com/jetbrains/python/testing/PyTrialTest.kt
Normal file
60
python/src/com/jetbrains/python/testing/PyTrialTest.kt
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.testing
|
||||
|
||||
import com.intellij.execution.Executor
|
||||
import com.intellij.execution.configurations.RunProfileState
|
||||
import com.intellij.execution.runners.ExecutionEnvironment
|
||||
import com.intellij.openapi.options.SettingsEditor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.jetbrains.python.PyNames
|
||||
import com.jetbrains.python.PythonHelper
|
||||
|
||||
/**
|
||||
* Py.test runner
|
||||
*/
|
||||
|
||||
class PyTrialTestSettingsEditor(configuration: PyAbstractTestConfiguration) :
|
||||
PyAbstractTestSettingsEditor(PyTestSharedForm.create(configuration))
|
||||
|
||||
class PyTrialTestExecutionEnvironment(configuration: PyTrialTestConfiguration, environment: ExecutionEnvironment) :
|
||||
PyTestExecutionEnvironment<PyTrialTestConfiguration>(configuration, environment) {
|
||||
override fun getRunner() = PythonHelper.TRIAL
|
||||
}
|
||||
|
||||
|
||||
class PyTrialTestConfiguration(project: Project, factory: PyTrialTestFactory)
|
||||
: PyAbstractTestConfiguration(project, factory, PyTestFrameworkService.getSdkReadableNameByFramework(PyNames.TRIAL_TEST)) {
|
||||
|
||||
|
||||
override fun getState(executor: Executor, environment: ExecutionEnvironment): RunProfileState? =
|
||||
PyTrialTestExecutionEnvironment(this, environment)
|
||||
|
||||
override fun createConfigurationEditor(): SettingsEditor<PyAbstractTestConfiguration> =
|
||||
PyTrialTestSettingsEditor(this)
|
||||
|
||||
override fun shouldSeparateTargetPath() = false
|
||||
|
||||
override fun isFrameworkInstalled() = VFSTestFrameworkListener.getInstance().isTestFrameworkInstalled(sdk, PyNames.TRIAL_TEST)
|
||||
|
||||
}
|
||||
|
||||
|
||||
object PyTrialTestFactory : PyAbstractTestFactory<PyTrialTestConfiguration>() {
|
||||
override fun createTemplateConfiguration(project: Project) = PyTrialTestConfiguration(project, this)
|
||||
|
||||
override fun getName(): String = PyTestFrameworkService.getSdkReadableNameByFramework(PyNames.TRIAL_TEST)
|
||||
}
|
||||
@@ -135,12 +135,12 @@ public class VFSTestFrameworkListener {
|
||||
* @return null if we can't be sure
|
||||
*/
|
||||
@Contract("null, _ -> null")
|
||||
private Boolean checkTestFrameworkInstalled(@Nullable Sdk sdk, @NotNull String testPackageName) {
|
||||
return checkTestFrameworksInstalled(sdk, testPackageName).get(testPackageName);
|
||||
private Boolean checkTestFrameworkInstalled(@Nullable Sdk sdk, @NotNull String testFrameworkName) {
|
||||
return checkTestFrameworksInstalled(sdk, testFrameworkName).get(testFrameworkName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<String, Boolean> checkTestFrameworksInstalled(@Nullable Sdk sdk, @NotNull String... testPackageNames) {
|
||||
private Map<String, Boolean> checkTestFrameworksInstalled(@Nullable Sdk sdk, @NotNull String... testFrameworkNames) {
|
||||
final Map<String, Boolean> result = new HashMap<>();
|
||||
if (sdk == null || StringUtil.isEmptyOrSpaces(sdk.getHomePath())) {
|
||||
LOG.info("Searching test runner in empty sdk");
|
||||
@@ -151,8 +151,9 @@ public class VFSTestFrameworkListener {
|
||||
if (refreshed) {
|
||||
final List<PyPackage> packages = manager.getPackages();
|
||||
if (packages != null) {
|
||||
for (String name : testPackageNames) {
|
||||
result.put(name, PyPackageUtil.findPackage(packages, name) != null);
|
||||
for (final String frameworkName : testFrameworkNames) {
|
||||
final String packageName = PyTestFrameworkService.getPackageByFramework(frameworkName);
|
||||
result.put(frameworkName, PyPackageUtil.findPackage(packages, packageName) != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
__author__ = 'ktisha'
|
||||
56
python/testSrc/com/jetbrains/env/python/testing/PyTestsFunctionBasedRunner.java
vendored
Normal file
56
python/testSrc/com/jetbrains/env/python/testing/PyTestsFunctionBasedRunner.java
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.env.python.testing;
|
||||
|
||||
import com.intellij.execution.testframework.AbstractTestProxy;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.jetbrains.env.PyProcessWithConsoleTestTask;
|
||||
import com.jetbrains.env.ut.PyScriptTestProcessRunner;
|
||||
import com.jetbrains.python.sdkTools.SdkCreationType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Checks each method by name
|
||||
*/
|
||||
abstract class PyTestsFunctionBasedRunner<T extends PyScriptTestProcessRunner<?>> extends PyProcessWithConsoleTestTask<T> {
|
||||
@NotNull
|
||||
protected final String[] myFunctionsToCheck;
|
||||
|
||||
protected PyTestsFunctionBasedRunner(@NotNull final String... functionsToCheck) {
|
||||
super("/testRunner/env/testsInFolder", SdkCreationType.EMPTY_SDK);
|
||||
assert functionsToCheck.length > 0 : "Provide functions";
|
||||
myFunctionsToCheck = functionsToCheck.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
for (final String functionName : myFunctionsToCheck) {
|
||||
ReadAction.run((ThrowableRunnable<AssertionError>)() -> {
|
||||
final AbstractTestProxy method = runner.findTestByName(functionName);
|
||||
checkMethod(method, functionName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for each method
|
||||
*/
|
||||
protected abstract void checkMethod(@NotNull final AbstractTestProxy method, @NotNull final String functionName);
|
||||
}
|
||||
53
python/testSrc/com/jetbrains/env/python/testing/PyTestsInSubFolderRunner.java
vendored
Normal file
53
python/testSrc/com/jetbrains/env/python/testing/PyTestsInSubFolderRunner.java
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.env.python.testing;
|
||||
|
||||
import com.intellij.execution.Location;
|
||||
import com.intellij.execution.testframework.AbstractTestProxy;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.jetbrains.env.ut.PyScriptTestProcessRunner;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Checks tests are resolved when launched from subfolder
|
||||
*/
|
||||
abstract class PyTestsInSubFolderRunner<T extends PyScriptTestProcessRunner<?>> extends PyTestsFunctionBasedRunner<T> {
|
||||
|
||||
/**
|
||||
* @param functionsToCheck name of functions that should be found in test tree and resolved
|
||||
*/
|
||||
PyTestsInSubFolderRunner(@NotNull final String... functionsToCheck) {
|
||||
super(functionsToCheck);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkMethod(@NotNull final AbstractTestProxy method, @NotNull final String functionName) {
|
||||
|
||||
final Location<?> methodLocation = method.getLocation(getProject(), GlobalSearchScope.moduleScope(myFixture.getModule()));
|
||||
|
||||
Assert.assertNotNull("Failed to resolve method location " + method, methodLocation);
|
||||
final PsiElement methodPsiElement = methodLocation.getPsiElement();
|
||||
Assert.assertNotNull("Failed to get PSI for method location", methodPsiElement);
|
||||
Assert.assertThat("Wrong test returned", methodPsiElement, Matchers.instanceOf(PyFunction.class));
|
||||
Assert.assertEquals("Wrong method name", functionName, ((PsiNamedElement)methodPsiElement).getName());
|
||||
}
|
||||
}
|
||||
51
python/testSrc/com/jetbrains/env/python/testing/PyTestsOutputRunner.java
vendored
Normal file
51
python/testSrc/com/jetbrains/env/python/testing/PyTestsOutputRunner.java
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.env.python.testing;
|
||||
|
||||
import com.intellij.execution.testframework.AbstractTestProxy;
|
||||
import com.intellij.execution.testframework.sm.runner.ui.MockPrinter;
|
||||
import com.jetbrains.env.ut.PyScriptTestProcessRunner;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Checks test output is correct
|
||||
*/
|
||||
abstract class PyTestsOutputRunner<T extends PyScriptTestProcessRunner<?>> extends PyTestsFunctionBasedRunner<T> {
|
||||
|
||||
PyTestsOutputRunner(@NotNull final String... functionsToCheck) {
|
||||
super(functionsToCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkMethod(@NotNull final AbstractTestProxy method, @NotNull final String functionName) {
|
||||
if (functionName.endsWith("test_metheggs")) {
|
||||
Assert.assertThat("Method output is broken",
|
||||
MockPrinter.fillPrinter(method).getStdOut().trim(), Matchers.containsString("I am method"));
|
||||
}
|
||||
else if (functionName.endsWith("test_funeggs")) {
|
||||
Assert.assertThat("Function output is broken",
|
||||
MockPrinter.fillPrinter(method).getStdOut().trim(), Matchers.containsString("I am function"));
|
||||
}
|
||||
else if (functionName.endsWith("test_first") || functionName.endsWith("test_second")) {
|
||||
// No output expected
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unknown function " + functionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
python/testSrc/com/jetbrains/env/python/testing/PyUnitTestLikeProcessWithConsoleTestTask.kt
vendored
Normal file
47
python/testSrc/com/jetbrains/env/python/testing/PyUnitTestLikeProcessWithConsoleTestTask.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.env.python.testing
|
||||
|
||||
import com.google.common.collect.Sets
|
||||
import com.jetbrains.env.PyProcessWithConsoleTestTask
|
||||
import com.jetbrains.env.ut.PyScriptTestProcessRunner
|
||||
import com.jetbrains.env.ut.PyUnitTestProcessRunner
|
||||
import com.jetbrains.python.sdkTools.SdkCreationType
|
||||
import java.util.function.Function
|
||||
|
||||
/**
|
||||
* [PyProcessWithConsoleTestTask] to be used with python unittest and trial. It saves you from boilerplate
|
||||
* by setting working folder and creating [PyUnitTestProcessRunner]
|
||||
|
||||
* @author Ilya.Kazakevich
|
||||
*/
|
||||
internal abstract class PyUnitTestLikeProcessWithConsoleTestTask<T :
|
||||
PyScriptTestProcessRunner<*>> @JvmOverloads constructor(relativePathToTestData: String,
|
||||
val myScriptName: String,
|
||||
val myRerunFailedTests: Int = 0,
|
||||
protected val processRunnerCreator: Function<TestRunnerConfig, T>) :
|
||||
PyProcessWithConsoleTestTask<T>(relativePathToTestData, SdkCreationType.SDK_PACKAGES_ONLY) {
|
||||
|
||||
override fun getTagsToCover(): Set<String> = Sets.newHashSet("python2.6", "python2.7", "python3.5", "python3.6", "jython", "pypy",
|
||||
"IronPython")
|
||||
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun createProcessRunner(): T =
|
||||
processRunnerCreator.apply(TestRunnerConfig(myScriptName, myRerunFailedTests))
|
||||
}
|
||||
|
||||
data class TestRunnerConfig(val scriptName: String, val rerunFailedTests: Int)
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.env.python.testing;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.execution.Location;
|
||||
import com.intellij.execution.testframework.AbstractTestProxy;
|
||||
import com.intellij.execution.testframework.sm.runner.ui.MockPrinter;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.jetbrains.env.PyProcessWithConsoleTestTask;
|
||||
import com.jetbrains.env.ut.PyScriptTestProcessRunner;
|
||||
import com.jetbrains.env.ut.PyUnitTestProcessRunner;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.sdkTools.SdkCreationType;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* {@link PyProcessWithConsoleTestTask} to be used with python unittest. It saves you from boilerplate
|
||||
* by setting working folder and creating {@link PyUnitTestProcessRunner}
|
||||
*
|
||||
* @author Ilya.Kazakevich
|
||||
*/
|
||||
abstract class PyUnitTestProcessWithConsoleTestTask extends PyProcessWithConsoleTestTask<PyUnitTestProcessRunner> {
|
||||
@NotNull
|
||||
protected final String myScriptName;
|
||||
private final int myRerunFailedTests;
|
||||
|
||||
PyUnitTestProcessWithConsoleTestTask(@NotNull final String relativePathToTestData, @NotNull final String scriptName) {
|
||||
this(relativePathToTestData, scriptName, 0);
|
||||
}
|
||||
PyUnitTestProcessWithConsoleTestTask(@NotNull final String relativePathToTestData,
|
||||
@NotNull final String scriptName,
|
||||
final int rerunFailedTests) {
|
||||
super(relativePathToTestData, SdkCreationType.SDK_PACKAGES_ONLY);
|
||||
myScriptName = scriptName;
|
||||
myRerunFailedTests= rerunFailedTests;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<String> getTagsToCover() {
|
||||
return Sets.newHashSet("python2.6", "python2.7", "python3.5", "python3.6", "jython", "pypy", "IronPython");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(myScriptName, myRerunFailedTests);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks each method by name
|
||||
*/
|
||||
abstract static class PyTestsFunctionBasedRunner<T extends PyScriptTestProcessRunner<?>> extends PyProcessWithConsoleTestTask<T> {
|
||||
@NotNull
|
||||
protected final String[] myFunctionsToCheck;
|
||||
|
||||
protected PyTestsFunctionBasedRunner(@NotNull final String... functionsToCheck) {
|
||||
super("/testRunner/env/testsInFolder", SdkCreationType.EMPTY_SDK);
|
||||
assert functionsToCheck.length > 0 : "Provide functions";
|
||||
myFunctionsToCheck = functionsToCheck.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
for (final String functionName : myFunctionsToCheck) {
|
||||
ReadAction.run((ThrowableRunnable<AssertionError>)() -> {
|
||||
final AbstractTestProxy method = runner.findTestByName(functionName);
|
||||
checkMethod(method, functionName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for each method
|
||||
*/
|
||||
protected abstract void checkMethod(@NotNull final AbstractTestProxy method, @NotNull final String functionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks tests are resolved when launched from subfolder
|
||||
*/
|
||||
abstract static class PyTestsInSubFolderRunner<T extends PyScriptTestProcessRunner<?>> extends PyTestsFunctionBasedRunner<T> {
|
||||
|
||||
/**
|
||||
* @param functionsToCheck name of functions that should be found in test tree and resolved
|
||||
*/
|
||||
PyTestsInSubFolderRunner(@NotNull final String... functionsToCheck) {
|
||||
super(functionsToCheck);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkMethod(@NotNull final AbstractTestProxy method, @NotNull final String functionName) {
|
||||
|
||||
final Location<?> methodLocation = method.getLocation(getProject(), GlobalSearchScope.moduleScope(myFixture.getModule()));
|
||||
|
||||
Assert.assertNotNull("Failed to resolve method location " + method, methodLocation);
|
||||
final PsiElement methodPsiElement = methodLocation.getPsiElement();
|
||||
Assert.assertNotNull("Failed to get PSI for method location", methodPsiElement);
|
||||
Assert.assertThat("Wrong test returned", methodPsiElement, Matchers.instanceOf(PyFunction.class));
|
||||
Assert.assertEquals("Wrong method name", functionName, ((PsiNamedElement)methodPsiElement).getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks test output is correct
|
||||
*/
|
||||
abstract static class PyTestsOutputRunner<T extends PyScriptTestProcessRunner<?>> extends PyTestsFunctionBasedRunner<T> {
|
||||
|
||||
PyTestsOutputRunner(@NotNull final String... functionsToCheck) {
|
||||
super(functionsToCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkMethod(@NotNull final AbstractTestProxy method, @NotNull final String functionName) {
|
||||
if (functionName.endsWith("test_metheggs")) {
|
||||
Assert.assertThat("Method output is broken",
|
||||
MockPrinter.fillPrinter(method).getStdOut().trim(), Matchers.containsString("I am method"));
|
||||
}
|
||||
else if (functionName.endsWith("test_funeggs")) {
|
||||
Assert.assertThat("Function output is broken",
|
||||
MockPrinter.fillPrinter(method).getStdOut().trim(), Matchers.containsString("I am function"));
|
||||
}
|
||||
else if (functionName.endsWith("test_first") || functionName.endsWith("test_second")) {
|
||||
// No output expected
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unknown function " + functionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,8 +119,8 @@ public final class PythonNoseTestingTest extends PyEnvTestCase {
|
||||
@Test
|
||||
public void testTestsInSubFolderResolvable() throws Exception {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask.PyTestsInSubFolderRunner<PyNoseTestProcessRunner>("test_metheggs", "test_funeggs",
|
||||
"test_first") {
|
||||
new PyTestsInSubFolderRunner<PyNoseTestProcessRunner>("test_metheggs", "test_funeggs",
|
||||
"test_first") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyNoseTestProcessRunner createProcessRunner() throws Exception {
|
||||
@@ -141,7 +141,7 @@ public final class PythonNoseTestingTest extends PyEnvTestCase {
|
||||
@Test
|
||||
public void testOutput() throws Exception {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask.PyTestsOutputRunner<PyNoseTestProcessRunner>("test_metheggs", "test_funeggs", "test_first") {
|
||||
new PyTestsOutputRunner<PyNoseTestProcessRunner>("test_metheggs", "test_funeggs", "test_first") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyNoseTestProcessRunner createProcessRunner() throws Exception {
|
||||
|
||||
@@ -292,8 +292,8 @@ public final class PythonPyTestingTest extends PyEnvTestCase {
|
||||
@Test
|
||||
public void testTestsInSubFolderResolvable() throws Exception {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask.PyTestsInSubFolderRunner<PyTestTestProcessRunner>("test_metheggs", "test_funeggs",
|
||||
"test_first") {
|
||||
new PyTestsInSubFolderRunner<PyTestTestProcessRunner>("test_metheggs", "test_funeggs",
|
||||
"test_first") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyTestTestProcessRunner createProcessRunner() throws Exception {
|
||||
@@ -314,7 +314,7 @@ public final class PythonPyTestingTest extends PyEnvTestCase {
|
||||
@Test
|
||||
public void testOutput() throws Exception {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask.PyTestsOutputRunner<PyTestTestProcessRunner>("test_metheggs", "test_funeggs", "test_first") {
|
||||
new PyTestsOutputRunner<PyTestTestProcessRunner>("test_metheggs", "test_funeggs", "test_first") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyTestTestProcessRunner createProcessRunner() throws Exception {
|
||||
|
||||
32
python/testSrc/com/jetbrains/env/python/testing/PythonTrialTest.kt
vendored
Normal file
32
python/testSrc/com/jetbrains/env/python/testing/PythonTrialTest.kt
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.env.python.testing
|
||||
|
||||
import com.jetbrains.env.EnvTestTagsRequired
|
||||
import com.jetbrains.env.ut.PyScriptTestProcessRunner
|
||||
import com.jetbrains.python.testing.PyTrialTestConfiguration
|
||||
import com.jetbrains.python.testing.PyTrialTestFactory
|
||||
|
||||
// Twisted trial test case
|
||||
@EnvTestTagsRequired(tags = arrayOf("twisted"))
|
||||
internal class PythonTrialTest : PythonUnitTestingLikeTest<PyTrialTestProcessRunner>() {
|
||||
override fun createTestRunner(config: TestRunnerConfig) = PyTrialTestProcessRunner(config.scriptName, config.rerunFailedTests)
|
||||
}
|
||||
|
||||
|
||||
class PyTrialTestProcessRunner(scriptName: String,
|
||||
timesToRerunFailedTests: Int) : PyScriptTestProcessRunner<PyTrialTestConfiguration>(
|
||||
PyTrialTestFactory, PyTrialTestConfiguration::class.java, scriptName, timesToRerunFailedTests)
|
||||
388
python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingLikeTest.java
vendored
Normal file
388
python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingLikeTest.java
vendored
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.env.python.testing;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.EdtTestUtil;
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestFixture;
|
||||
import com.jetbrains.env.PyEnvTestCase;
|
||||
import com.jetbrains.env.ut.PyScriptTestProcessRunner;
|
||||
import com.jetbrains.env.ut.PyUnitTestProcessRunner;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jetbrains.env.ut.PyScriptTestProcessRunner.TEST_TARGET_PREFIX;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Parent of unittest and trial test.
|
||||
* All tests here should run with trial and unit
|
||||
*/
|
||||
public abstract class PythonUnitTestingLikeTest<T extends PyScriptTestProcessRunner<?>> extends PyEnvTestCase {
|
||||
/**
|
||||
* Ensure "[" in test does not break output
|
||||
*/
|
||||
@Test
|
||||
public void testEscaping() throws Exception {
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "test_escaping.py", this::createTestRunner) {
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(0, runner.getPassedTestsCount());
|
||||
assertEquals(1, runner.getFailedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
abstract T createTestRunner(@NotNull final TestRunnerConfig config);
|
||||
|
||||
/**
|
||||
* Ensure that sys.path[0] is script folder, not helpers folder
|
||||
*/
|
||||
@Test
|
||||
public void testSysPath() throws Exception {
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("testRunner/env/unit/sysPath", "test_sample.py", this::createTestRunner) {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected T createProcessRunner() throws Exception {
|
||||
return getProcessRunnerCreator().apply(new TestRunnerConfig(toFullPath(getMyScriptName()), 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
Assert.assertEquals(runner.getFormattedTestTree(), 1, runner.getAllTestsCount());
|
||||
myFixture.getTempDirFixture().getFile("sysPath");
|
||||
|
||||
final VirtualFile folderWithScript = myFixture.getTempDirFixture().getFile(".");
|
||||
assert folderWithScript != null : "No folder for script " + getMyScriptName();
|
||||
Assert.assertThat("sys.path[0] should point to folder with test, while it does not", stdout,
|
||||
Matchers.containsString(String.format("path[0]=%s", new File(folderWithScript.getPath()).getAbsolutePath())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTRunner() {
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "test1.py", this::createTestRunner) {
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getPassedTestsCount());
|
||||
runner.assertAllTestsPassed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* tests with docstrings are reported as "test.name (text)" by unittest.
|
||||
*/
|
||||
@Test
|
||||
public void testWithDocString() throws Exception {
|
||||
|
||||
runPythonTest(
|
||||
new PyUnitTestLikeProcessWithConsoleTestTask<T>("testRunner/env/unit/withDocString", "test_test.py", this::createTestRunner) {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected T createProcessRunner() throws Exception {
|
||||
return getProcessRunnerCreator().apply(new TestRunnerConfig(toFullPath(getMyScriptName()), 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
if (runner.getCurrentRerunStep() == 0) {
|
||||
assertEquals("test with docstring produced bad tree", "Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..SomeTestCase\n" +
|
||||
"...testSomething (Only with docstring test is parsed with extra space)(+)\n" +
|
||||
"...testSomethingBad (Fail)(-)\n", runner.getFormattedTestTree());
|
||||
}
|
||||
else {
|
||||
assertEquals("test with docstring failed to rerun",
|
||||
"Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..SomeTestCase\n" +
|
||||
"...testSomethingBad (Fail)(-)\n", runner.getFormattedTestTree());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClass() {
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit",
|
||||
TEST_TARGET_PREFIX + "test_file.GoodTest", this::createTestRunner) {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTRunner2() {
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "test2.py", this::createTestRunner) {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 3, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 1, runner.getPassedTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getFailedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensures file references are highlighted for python traceback
|
||||
*/
|
||||
@Test
|
||||
public void testUnitTestFileReferences() {
|
||||
final String fileName = "reference_tests.py";
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", fileName, this::createTestRunner) {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
final List<String> fileNames = runner.getHighlightedStringsInConsole().getSecond();
|
||||
Assert.assertTrue(String.format("Not enough highlighted entries(%s) in the following output: %s",
|
||||
StringUtil.join(fileNames, ","),
|
||||
runner.getAllConsoleText()),
|
||||
fileNames.size() >= 3);
|
||||
// UnitTest highlights file name
|
||||
Assert.assertThat("Bad line highlighted", fileNames, hasItem(endsWith(fileName)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that skipped and erroneous tests do not lead to suite ignorance
|
||||
*/
|
||||
@Test
|
||||
public void testUTSkippedAndIgnored() {
|
||||
runPythonTest(
|
||||
new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "test_with_skips_and_errors.py", this::createTestRunner) {
|
||||
|
||||
@Override
|
||||
public boolean isLanguageLevelSupported(@NotNull final LanguageLevel level) {
|
||||
// This test requires unittest to have decorator "test" that does not exists in 2.6
|
||||
return level.compareTo(LanguageLevel.PYTHON26) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(4, runner.getAllTestsCount());
|
||||
assertEquals(2, runner.getPassedTestsCount());
|
||||
assertEquals(2, runner.getFailedTestsCount());
|
||||
Assert.assertFalse("Suite is not finished", runner.getTestProxy().isInterrupted());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDependent() {
|
||||
runPythonTest(
|
||||
new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "dependentTests/test_my_class.py", this::createTestRunner) {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that python target pointing to module works correctly
|
||||
*/
|
||||
@Test
|
||||
public void testRunModuleAsFile() throws Exception {
|
||||
runPythonTest(new RunModuleAsFileTask<PyUnitTestProcessRunner>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(TARGET, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure rerun test works even if test is declared in parent
|
||||
* See https://github.com/JetBrains/teamcity-messages/issues/117
|
||||
*/
|
||||
@Test
|
||||
public void testRerunDerivedClass() throws Exception {
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "rerun_derived.py", this::createTestRunner) {
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
Assert.assertThat("Wrong number of failed tests", runner.getFailedTestsCount(), equalTo(1));
|
||||
final int expectedNumberOfTests = (runner.getCurrentRerunStep() == 0 ? 2 : 1);
|
||||
Assert.assertThat("Wrong number tests", runner.getAllTestsCount(), equalTo(expectedNumberOfTests));
|
||||
if (runner.getCurrentRerunStep() == 1) {
|
||||
// Make sure derived tests are launched, not abstract
|
||||
Assert.assertEquals("Wrong tests after rerun",
|
||||
"Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".rerun_derived\n" +
|
||||
"..TestDerived\n" +
|
||||
"...test_a(-)\n", runner.getFormattedTestTree());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected T createProcessRunner() throws Exception {
|
||||
return getProcessRunnerCreator().apply(new TestRunnerConfig(getMyScriptName(), 2));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Ensures setup/teardown does not break anything
|
||||
@Test
|
||||
public void testSetupTearDown() throws Exception {
|
||||
runPythonTest(new SetupTearDownTestTask<PyUnitTestProcessRunner>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner("test_test.py", 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFolder() {
|
||||
runPythonTest(new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "test_folder/", this::createTestRunner) {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(5, runner.getAllTestsCount());
|
||||
assertEquals(3, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Run tests, delete file and click "rerun" should throw exception and display error since test ids do not point to correct PSI
|
||||
* from that moment
|
||||
*/
|
||||
@Test
|
||||
public void testCantRerun() throws Exception {
|
||||
startMessagesCapture();
|
||||
|
||||
runPythonTest(
|
||||
new PyUnitTestLikeProcessWithConsoleTestTask<T>("/testRunner/env/unit", "test_with_skips_and_errors.py", this::createTestRunner) {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final T runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assert runner.getFailedTestsCount() > 0 : "We need failed tests to test broken rerun";
|
||||
|
||||
startMessagesCapture();
|
||||
|
||||
EdtTestUtil.runInEdtAndWait(() -> {
|
||||
deleteAllTestFiles(myFixture);
|
||||
runner.rerunFailedTests();
|
||||
});
|
||||
|
||||
final List<Throwable> throwables = getCapturesMessages().first;
|
||||
Assert.assertThat("Exception shall be thrown", throwables, not(emptyCollectionOf(Throwable.class)));
|
||||
final Throwable exception = throwables.get(0);
|
||||
Assert.assertThat("ExecutionException should be thrown", exception, instanceOf(ExecutionException.class));
|
||||
Assert.assertThat("Wrong text", exception.getMessage(), equalTo(PyBundle.message("runcfg.tests.cant_rerun")));
|
||||
Assert.assertThat("No messages displayed for exception", getCapturesMessages().second, not(emptyCollectionOf(String.class)));
|
||||
|
||||
|
||||
stopMessageCapture();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all files in temp. folder
|
||||
*/
|
||||
private static void deleteAllTestFiles(@NotNull final CodeInsightTestFixture fixture) {
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
final VirtualFile testRoot = fixture.getTempDirFixture().getFile(".");
|
||||
assert testRoot != null : "No temp path?";
|
||||
try {
|
||||
for (final VirtualFile child : testRoot.getChildren()) {
|
||||
child.delete(null);
|
||||
}
|
||||
}
|
||||
catch (final IOException e) {
|
||||
throw new AssertionError(String.format("Failed to delete files in %s : %s", testRoot, e));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -15,19 +15,11 @@
|
||||
*/
|
||||
package com.jetbrains.env.python.testing;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.EdtTestUtil;
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestFixture;
|
||||
import com.jetbrains.env.EnvTestTagsRequired;
|
||||
import com.jetbrains.env.PyEnvTestCase;
|
||||
import com.jetbrains.env.ut.PyUnitTestProcessRunner;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.sdk.InvalidSdkException;
|
||||
@@ -35,26 +27,57 @@ import com.jetbrains.python.testing.PyUnitTestConfiguration;
|
||||
import com.jetbrains.python.testing.PyUnitTestFactory;
|
||||
import com.jetbrains.python.testing.PythonTestConfigurationsModel;
|
||||
import com.jetbrains.python.testing.TestTargetType;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jetbrains.env.ut.PyScriptTestProcessRunner.TEST_TARGET_PREFIX;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
public final class PythonUnitTestingTest extends PythonUnitTestingLikeTest<PyUnitTestProcessRunner> {
|
||||
|
||||
|
||||
@Override
|
||||
PyUnitTestProcessRunner createTestRunner(@NotNull final TestRunnerConfig config) {
|
||||
return new PyUnitTestProcessRunner(config.getScriptName(), config.getRerunFailedTests());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameClass() throws Exception {
|
||||
runPythonTest(
|
||||
new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameClassTask<>(
|
||||
PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME,
|
||||
PyUnitTestConfiguration.class));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeConfigurationWarning.class)
|
||||
public void testValidation() throws Exception {
|
||||
|
||||
final CreateConfigurationTestTask.PyConfigurationCreationTask<PyUnitTestConfiguration> task =
|
||||
new CreateConfigurationTestTask.PyConfigurationCreationTask<PyUnitTestConfiguration>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestFactory createFactory() {
|
||||
return PyUnitTestFactory.INSTANCE;
|
||||
}
|
||||
};
|
||||
runPythonTest(task);
|
||||
final PyUnitTestConfiguration configuration = task.getConfiguration();
|
||||
configuration.setPattern("foo");
|
||||
configuration.getTarget().setTargetType(TestTargetType.PATH);
|
||||
configuration.getTarget().setTarget("foo.py");
|
||||
configuration.checkConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* tests failfast as example of argument
|
||||
*/
|
||||
@@ -66,7 +89,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 1) {
|
||||
return new PyUnitTestProcessRunner(toFullPath(getMyScriptName()), 1) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull final PyUnitTestConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
@@ -92,7 +115,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
|
||||
|
||||
/**
|
||||
* check non-ascii (127+) chars are supported in skip messaged
|
||||
* check non-ascii (127+) chars are supported in skip messaged
|
||||
*/
|
||||
@Test
|
||||
public void testNonAsciiMessage() throws Exception {
|
||||
@@ -109,56 +132,16 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
runner.getFormattedTestTree();
|
||||
assertEquals("Skipped test with non-ascii message broke tree",
|
||||
"Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..TestCase\n" +
|
||||
"...test(~)\n", runner.getFormattedTestTree());
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..TestCase\n" +
|
||||
"...test(~)\n", runner.getFormattedTestTree());
|
||||
Assert.assertThat("non-ascii char broken in output", stdout, containsString("ошибка"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* tests with docstrings are reported as "test.name (text)" by unittest.
|
||||
*/
|
||||
@Test
|
||||
public void testWithDocString() throws Exception {
|
||||
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("testRunner/env/unit/withDocString", "test_test.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) {
|
||||
assertEquals("test with docstring produced bad tree", "Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..SomeTestCase\n" +
|
||||
"...testSomething (Only with docstring test is parsed with extra space)(+)\n" +
|
||||
"...testSomethingBad (Fail)(-)\n", runner.getFormattedTestTree());
|
||||
}
|
||||
else {
|
||||
assertEquals("test with docstring failed to rerun",
|
||||
"Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..SomeTestCase\n" +
|
||||
"...testSomethingBad (Fail)(-)\n", runner.getFormattedTestTree());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Ensure failed and error subtests work
|
||||
@Test
|
||||
@EnvTestTagsRequired(tags = "python3")
|
||||
@@ -168,7 +151,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 1);
|
||||
return new PyUnitTestProcessRunner(toFullPath(getMyScriptName()), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,7 +181,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 1);
|
||||
return new PyUnitTestProcessRunner(toFullPath(getMyScriptName()), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,7 +216,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 1);
|
||||
return new PyUnitTestProcessRunner(toFullPath(getMyScriptName()), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -261,18 +244,6 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
// Ensures setup/teardown does not break anything
|
||||
@Test
|
||||
public void testSetupTearDown() throws Exception {
|
||||
runPythonTest(new SetupTearDownTestTask<PyUnitTestProcessRunner>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner("test_test.py", 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Raising SkipTest on class setup should not lead to KeyError
|
||||
@@ -287,43 +258,14 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
Assert.assertEquals("Output tree broken for skipped exception thrown in setup method" ,"Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..TestSimple\n" +
|
||||
"...setUpClass(~)\n" +
|
||||
"..TestSubSimple\n" +
|
||||
"...setUpClass(~)\n", runner.getFormattedTestTree());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensure that sys.path[0] is script folder, not helpers folder
|
||||
*/
|
||||
@Test
|
||||
public void testSysPath() throws Exception {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("testRunner/env/unit/sysPath", "test_sample.py") {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
Assert.assertEquals(runner.getFormattedTestTree(), 1, runner.getAllTestsCount());
|
||||
myFixture.getTempDirFixture().getFile("sysPath");
|
||||
|
||||
final VirtualFile folderWithScript = myFixture.getTempDirFixture().getFile(".");
|
||||
assert folderWithScript != null : "No folder for script " + myScriptName;
|
||||
Assert.assertThat("sys.path[0] should point to folder with test, while it does not", stdout,
|
||||
Matchers.containsString(String.format("path[0]=%s", new File(folderWithScript.getPath()).getAbsolutePath())));
|
||||
Assert.assertEquals("Output tree broken for skipped exception thrown in setup method", "Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".test_test\n" +
|
||||
"..TestSimple\n" +
|
||||
"...setUpClass(~)\n" +
|
||||
"..TestSubSimple\n" +
|
||||
"...setUpClass(~)\n",
|
||||
runner.getFormattedTestTree());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -340,7 +282,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 1);
|
||||
return new PyUnitTestProcessRunner(toFullPath(getMyScriptName()), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -374,7 +316,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
// Full pass is required because it is folder
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 2) {
|
||||
return new PyUnitTestProcessRunner(toFullPath(getMyScriptName()), 2) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull final PyUnitTestConfiguration configuration)
|
||||
throws IOException {
|
||||
@@ -399,20 +341,6 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that python target pointing to module works correctly
|
||||
*/
|
||||
@Test
|
||||
public void testRunModuleAsFile() throws Exception {
|
||||
runPythonTest(new RunModuleAsFileTask<PyUnitTestProcessRunner>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(TARGET, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRerunSubfolder() throws Exception {
|
||||
runPythonTest(new RerunSubfolderTask<PyUnitTestProcessRunner>(1) {
|
||||
@@ -442,7 +370,7 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
// Full pass is required because it is folder
|
||||
return new PyUnitTestProcessRunner(toFullPath(myScriptName), 2) {
|
||||
return new PyUnitTestProcessRunner(toFullPath(getMyScriptName()), 2) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull PyUnitTestConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
@@ -510,20 +438,181 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
// PY-24407
|
||||
@Test
|
||||
public void testMultipleCases() throws Exception {
|
||||
public void testWorkingDirectoryDependsOnRelativeImport() throws Exception {
|
||||
runPythonTest(new CreateConfigurationTestTask<PyUnitTestConfiguration>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME,
|
||||
PyUnitTestConfiguration.class) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<PsiElement> getPsiElementsToRightClickOn() {
|
||||
myFixture.configureByFile("testRelativeImport/src/tests/test_no_relative.py");
|
||||
final PyFunction noRelativeImportFun = myFixture.findElementByText("test_no_relative", PyFunction.class);
|
||||
assert noRelativeImportFun != null;
|
||||
|
||||
myFixture.configureByFile("testRelativeImport/src/tests/test_relative.py");
|
||||
final PyFunction relativeImportFun = myFixture.findElementByText("test_relative", PyFunction.class);
|
||||
assert relativeImportFun != null;
|
||||
|
||||
|
||||
return Arrays.asList(relativeImportFun, noRelativeImportFun);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkConfiguration(@NotNull PyUnitTestConfiguration configuration, @NotNull PsiElement elementToRightClickOn) {
|
||||
super.checkConfiguration(configuration, elementToRightClickOn);
|
||||
configuration.getWorkingDirectorySafe();
|
||||
|
||||
final PyFunction function = (PyFunction)elementToRightClickOn;
|
||||
if (function.getName().equals("test_relative")) {
|
||||
Assert.assertThat("Wrong dir for relative import", configuration.getWorkingDirectory(), endsWith("testRelativeImport"));
|
||||
assertEquals("Bad target", "src.tests.test_relative.ModuleTest.test_relative", configuration.getTarget().getTarget());
|
||||
}
|
||||
else if (function.getName().equals("test_no_relative")) {
|
||||
Assert
|
||||
.assertThat("Wrong dir for non relative import", configuration.getWorkingDirectory(), endsWith("testRelativeImport/src/tests"));
|
||||
assertEquals("Bad target", "test_no_relative.ModuleTest.test_no_relative", configuration.getTarget().getTarget());
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unexpected function " + function.getName());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks tests are resolved when launched from subfolder
|
||||
*/
|
||||
@Test
|
||||
public void testTestsInSubFolderResolvable() throws Exception {
|
||||
runPythonTest(
|
||||
new CreateConfigurationMultipleCasesTask<PyUnitTestConfiguration>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME,
|
||||
PyUnitTestConfiguration.class){
|
||||
new PyTestsInSubFolderRunner<PyUnitTestProcessRunner>("test_metheggs", "test_first") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected boolean configurationShouldBeProducedForElement(@NotNull final PsiElement element) {
|
||||
// test_functions.py does not conttain any TestCase and can't be launched with unittest
|
||||
final PsiFile file = element.getContainingFile();
|
||||
return file == null || ! file.getName().endsWith("test_functions.py");
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath("tests"), 0) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull PyUnitTestConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
configuration.setWorkingDirectory(getWorkingFolderForScript());
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures test output works
|
||||
*/
|
||||
@Test
|
||||
public void testOutput() throws Exception {
|
||||
runPythonTest(
|
||||
new PyTestsOutputRunner<PyUnitTestProcessRunner>("test_metheggs", "test_first") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath("tests"), 0) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull PyUnitTestConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
configuration.setWorkingDirectory(getWorkingFolderForScript());
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks <a href="https://docs.python.org/2/library/unittest.html#load-tests-protocol">Load test protocol</a>
|
||||
*/
|
||||
@Test
|
||||
public void testLoadProtocol() throws Exception {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test_load_protocol.py") {
|
||||
@Override
|
||||
public boolean isLanguageLevelSupported(@NotNull final LanguageLevel level) {
|
||||
// "load_protocol" does not exist before 2.7
|
||||
return level.compareTo(LanguageLevel.PYTHON26) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals("bad num of passed tests: unittest load protocol failed to find tests?", 3, runner.getPassedTestsCount());
|
||||
runner.assertAllTestsPassed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures pattern is supported
|
||||
*/
|
||||
@Test
|
||||
public void testUTRunnerByPattern() {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", PyUnitTestProcessRunner.TEST_PATTERN_PREFIX + "*pattern.py") {
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 4, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getPassedTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getFailedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethod() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit",
|
||||
TEST_TARGET_PREFIX +
|
||||
"test_file.GoodTest.test_passes") {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelativeImports() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit/relativeImports",
|
||||
PyUnitTestProcessRunner.TEST_PATTERN_PREFIX + "test_imps.py") {
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 1, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConfigurationProducerOnDirectory() throws Exception {
|
||||
runPythonTest(
|
||||
new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameFolderTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME,
|
||||
PyUnitTestConfiguration.class));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConfigurationProducer() throws Exception {
|
||||
runPythonTest(new CreateConfigurationByFileTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUnitTestConfiguration.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures newly created configuration inherits working dir from default if set
|
||||
*/
|
||||
@@ -554,438 +643,31 @@ public final class PythonUnitTestingTest extends PyEnvTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
// PY-24407
|
||||
@Test
|
||||
public void testWorkingDirectoryDependsOnRelativeImport() throws Exception {
|
||||
runPythonTest(new CreateConfigurationTestTask<PyUnitTestConfiguration>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUnitTestConfiguration.class){
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<PsiElement> getPsiElementsToRightClickOn() {
|
||||
myFixture.configureByFile("testRelativeImport/src/tests/test_no_relative.py");
|
||||
final PyFunction noRelativeImportFun = myFixture.findElementByText("test_no_relative", PyFunction.class);
|
||||
assert noRelativeImportFun != null;
|
||||
|
||||
myFixture.configureByFile("testRelativeImport/src/tests/test_relative.py");
|
||||
final PyFunction relativeImportFun = myFixture.findElementByText("test_relative", PyFunction.class);
|
||||
assert relativeImportFun != null;
|
||||
|
||||
|
||||
return Arrays.asList(relativeImportFun, noRelativeImportFun);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkConfiguration(@NotNull PyUnitTestConfiguration configuration, @NotNull PsiElement elementToRightClickOn) {
|
||||
super.checkConfiguration(configuration, elementToRightClickOn);
|
||||
configuration.getWorkingDirectorySafe();
|
||||
|
||||
final PyFunction function = (PyFunction)elementToRightClickOn;
|
||||
if (function.getName().equals("test_relative")) {
|
||||
Assert.assertThat("Wrong dir for relative import", configuration.getWorkingDirectory(), endsWith("testRelativeImport"));
|
||||
assertEquals("Bad target", "src.tests.test_relative.ModuleTest.test_relative", configuration.getTarget().getTarget());
|
||||
} else if (function.getName().equals("test_no_relative")) {
|
||||
Assert.assertThat("Wrong dir for non relative import", configuration.getWorkingDirectory(), endsWith("testRelativeImport/src/tests"));
|
||||
assertEquals("Bad target", "test_no_relative.ModuleTest.test_no_relative", configuration.getTarget().getTarget());
|
||||
} else {
|
||||
throw new AssertionError("Unexpected function " + function.getName());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigurationProducer() throws Exception {
|
||||
runPythonTest(new CreateConfigurationByFileTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUnitTestConfiguration.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks tests are resolved when launched from subfolder
|
||||
*/
|
||||
@Test
|
||||
public void testTestsInSubFolderResolvable() throws Exception {
|
||||
public void testMultipleCases() throws Exception {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask.PyTestsInSubFolderRunner<PyUnitTestProcessRunner>("test_metheggs", "test_first") {
|
||||
@NotNull
|
||||
new CreateConfigurationMultipleCasesTask<PyUnitTestConfiguration>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME,
|
||||
PyUnitTestConfiguration.class) {
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath("tests"), 0) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull PyUnitTestConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
configuration.setWorkingDirectory(getWorkingFolderForScript());
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures test output works
|
||||
*/
|
||||
@Test
|
||||
public void testOutput() throws Exception {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask.PyTestsOutputRunner<PyUnitTestProcessRunner>("test_metheggs", "test_first") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(toFullPath("tests"), 0) {
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull PyUnitTestConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
configuration.setWorkingDirectory(getWorkingFolderForScript());
|
||||
}
|
||||
};
|
||||
protected boolean configurationShouldBeProducedForElement(@NotNull final PsiElement element) {
|
||||
// test_functions.py does not conttain any TestCase and can't be launched with unittest
|
||||
final PsiFile file = element.getContainingFile();
|
||||
return file == null || !file.getName().endsWith("test_functions.py");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = RuntimeConfigurationWarning.class)
|
||||
public void testValidation() throws Exception {
|
||||
private abstract class PyUnitTestProcessWithConsoleTestTask extends PyUnitTestLikeProcessWithConsoleTestTask<PyUnitTestProcessRunner> {
|
||||
public PyUnitTestProcessWithConsoleTestTask(@NotNull String relativePathToTestData,
|
||||
@NotNull String scriptName) {
|
||||
super(relativePathToTestData, scriptName, PythonUnitTestingTest.this::createTestRunner);
|
||||
}
|
||||
|
||||
final CreateConfigurationTestTask.PyConfigurationCreationTask<PyUnitTestConfiguration> task =
|
||||
new CreateConfigurationTestTask.PyConfigurationCreationTask<PyUnitTestConfiguration>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestFactory createFactory() {
|
||||
return PyUnitTestFactory.INSTANCE;
|
||||
}
|
||||
};
|
||||
runPythonTest(task);
|
||||
final PyUnitTestConfiguration configuration = task.getConfiguration();
|
||||
configuration.setPattern("foo");
|
||||
configuration.getTarget().setTargetType(TestTargetType.PATH);
|
||||
configuration.getTarget().setTarget("foo.py");
|
||||
configuration.checkConfiguration();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testConfigurationProducerOnDirectory() throws Exception {
|
||||
runPythonTest(
|
||||
new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameFolderTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME,
|
||||
PyUnitTestConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameClass() throws Exception {
|
||||
runPythonTest(
|
||||
new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameClassTask<>(
|
||||
PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME,
|
||||
PyUnitTestConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTRunner() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test1.py") {
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getPassedTestsCount());
|
||||
runner.assertAllTestsPassed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks <a href="https://docs.python.org/2/library/unittest.html#load-tests-protocol">Load test protocol</a>
|
||||
*/
|
||||
@Test
|
||||
public void testLoadProtocol() throws Exception {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test_load_protocol.py") {
|
||||
@Override
|
||||
public boolean isLanguageLevelSupported(@NotNull final LanguageLevel level) {
|
||||
// "load_protocol" does not exist before 2.7
|
||||
return level.compareTo(LanguageLevel.PYTHON26) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals("bad num of passed tests: unittest load protocol failed to find tests?", 3, runner.getPassedTestsCount());
|
||||
runner.assertAllTestsPassed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure rerun test works even if test is declared in parent
|
||||
* See https://github.com/JetBrains/teamcity-messages/issues/117
|
||||
*/
|
||||
@Test
|
||||
public void testRerunDerivedClass() throws Exception {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "rerun_derived.py") {
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
Assert.assertThat("Wrong number of failed tests", runner.getFailedTestsCount(), equalTo(1));
|
||||
final int expectedNumberOfTests = (runner.getCurrentRerunStep() == 0 ? 2 : 1);
|
||||
Assert.assertThat("Wrong number tests", runner.getAllTestsCount(), equalTo(expectedNumberOfTests));
|
||||
if (runner.getCurrentRerunStep() == 1) {
|
||||
// Make sure derived tests are launched, not abstract
|
||||
Assert.assertEquals("Wrong tests after rerun",
|
||||
"Test tree:\n" +
|
||||
"[root]\n" +
|
||||
".rerun_derived\n" +
|
||||
"..TestDerived\n" +
|
||||
"...test_a(-)\n", runner.getFormattedTestTree());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected PyUnitTestProcessRunner createProcessRunner() throws Exception {
|
||||
return new PyUnitTestProcessRunner(myScriptName, 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Run tests, delete file and click "rerun" should throw exception and display error since test ids do not point to correct PSI
|
||||
* from that moment
|
||||
*/
|
||||
@Test
|
||||
public void testCantRerun() throws Exception {
|
||||
startMessagesCapture();
|
||||
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test_with_skips_and_errors.py") {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assert runner.getFailedTestsCount() > 0 : "We need failed tests to test broken rerun";
|
||||
|
||||
startMessagesCapture();
|
||||
|
||||
EdtTestUtil.runInEdtAndWait(() -> {
|
||||
deleteAllTestFiles(myFixture);
|
||||
runner.rerunFailedTests();
|
||||
});
|
||||
|
||||
final List<Throwable> throwables = getCapturesMessages().first;
|
||||
Assert.assertThat("Exception shall be thrown", throwables, not(emptyCollectionOf(Throwable.class)));
|
||||
final Throwable exception = throwables.get(0);
|
||||
Assert.assertThat("ExecutionException should be thrown", exception, instanceOf(ExecutionException.class));
|
||||
Assert.assertThat("Wrong text", exception.getMessage(), equalTo(PyBundle.message("runcfg.tests.cant_rerun")));
|
||||
Assert.assertThat("No messages displayed for exception", getCapturesMessages().second, not(emptyCollectionOf(String.class)));
|
||||
|
||||
|
||||
stopMessageCapture();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that skipped and erroneous tests do not lead to suite ignorance
|
||||
*/
|
||||
@Test
|
||||
public void testUTSkippedAndIgnored() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test_with_skips_and_errors.py") {
|
||||
|
||||
@Override
|
||||
public boolean isLanguageLevelSupported(@NotNull final LanguageLevel level) {
|
||||
// This test requires unittest to have decorator "test" that does not exists in 2.6
|
||||
return level.compareTo(LanguageLevel.PYTHON26) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(4, runner.getAllTestsCount());
|
||||
assertEquals(2, runner.getPassedTestsCount());
|
||||
assertEquals(2, runner.getFailedTestsCount());
|
||||
Assert.assertFalse("Suite is not finished", runner.getTestProxy().isInterrupted());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUTRunner2() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test2.py") {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 3, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 1, runner.getPassedTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getFailedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures pattern is supported
|
||||
*/
|
||||
@Test
|
||||
public void testUTRunnerByPattern() {
|
||||
runPythonTest(
|
||||
new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", PyUnitTestProcessRunner.TEST_PATTERN_PREFIX + "*pattern.py") {
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 4, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getPassedTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 2, runner.getFailedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure "[" in test does not break output
|
||||
*/
|
||||
@Test
|
||||
public void testEscaping() throws Exception {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test_escaping.py") {
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(0, runner.getPassedTestsCount());
|
||||
assertEquals(1, runner.getFailedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClass() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit",
|
||||
TEST_TARGET_PREFIX + "test_file.GoodTest") {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethod() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit",
|
||||
TEST_TARGET_PREFIX +
|
||||
"test_file.GoodTest.test_passes") {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFolder() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "test_folder/") {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(5, runner.getAllTestsCount());
|
||||
assertEquals(3, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures file references are highlighted for python traceback
|
||||
*/
|
||||
@Test
|
||||
public void testUnitTestFileReferences() {
|
||||
final String fileName = "reference_tests.py";
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", fileName) {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
final List<String> fileNames = runner.getHighlightedStringsInConsole().getSecond();
|
||||
Assert.assertTrue(String.format("Not enough highlighted entries(%s) in the following output: %s",
|
||||
StringUtil.join(fileNames, ","),
|
||||
runner.getAllConsoleText()),
|
||||
fileNames.size() >= 3);
|
||||
// UnitTest highlights file name
|
||||
Assert.assertThat("Bad line highlighted", fileNames, hasItem(endsWith(fileName)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDependent() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit", "dependentTests/test_my_class.py") {
|
||||
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(1, runner.getAllTestsCount());
|
||||
assertEquals(1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelativeImports() {
|
||||
runPythonTest(new PyUnitTestProcessWithConsoleTestTask("/testRunner/env/unit/relativeImports",
|
||||
PyUnitTestProcessRunner.TEST_PATTERN_PREFIX + "test_imps.py") {
|
||||
@Override
|
||||
protected void checkTestResults(@NotNull final PyUnitTestProcessRunner runner,
|
||||
@NotNull final String stdout,
|
||||
@NotNull final String stderr,
|
||||
@NotNull final String all) {
|
||||
assertEquals(runner.getFormattedTestTree(), 1, runner.getAllTestsCount());
|
||||
assertEquals(runner.getFormattedTestTree(), 1, runner.getPassedTestsCount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all files in temp. folder
|
||||
*/
|
||||
private static void deleteAllTestFiles(@NotNull final CodeInsightTestFixture fixture) {
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
final VirtualFile testRoot = fixture.getTempDirFixture().getFile(".");
|
||||
assert testRoot != null : "No temp path?";
|
||||
try {
|
||||
for (final VirtualFile child : testRoot.getChildren()) {
|
||||
child.delete(null);
|
||||
}
|
||||
}
|
||||
catch (final IOException e) {
|
||||
throw new AssertionError(String.format("Failed to delete files in %s : %s", testRoot, e));
|
||||
}
|
||||
});
|
||||
public PyUnitTestProcessWithConsoleTestTask(@NotNull String relativePathToTestData,
|
||||
@NotNull String scriptName,
|
||||
int rerunFailedTests) {
|
||||
super(relativePathToTestData, scriptName, rerunFailedTests, PythonUnitTestingTest.this::createTestRunner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user