pytest and nosetest added
[idea/community.git] / python / helpers / pycharm / _jb_tox_runner.py
1 # coding=utf-8
2 """
3 Runs tox from current directory.
4 It supports any runner, but well-known runners (py.test and unittest) are switched to our internal runners to provide
5 better support
6 """
7 import os
8 import sys
9
10 from tox import config as tox_config, session as tox_session
11 from tox.session import Reporter
12
13 from tcmessages import TeamcityServiceMessages
14
15 helpers_dir = str(os.path.split(__file__)[0])
16
17
18 class _Unit2(object):
19     def fix(self, command):
20         if command[0] != "unit2":
21             return None
22         return [os.path.join(helpers_dir, "utrunner.py"), os.getcwd()] + command[1:] + ["true"]
23
24
25 class _PyTest(object):
26     def fix(self, command):
27         if command[0] != "py.test":
28             return None
29         return [os.path.join(helpers_dir, "pytestrunner.py"), "-p", "pytest_teamcity", os.getcwd()] + command[1:]
30
31
32 class _Nose(object):
33     def fix(self, command):
34         if command[0] != "nosetests":
35             return None
36         return [os.path.join(helpers_dir, "noserunner.py"), os.getcwd()] + command[1:]
37
38
39
40 _RUNNERS = [_Unit2(), _PyTest(), _Nose()]
41
42 teamcity = TeamcityServiceMessages()
43
44
45 class _Reporter(Reporter):
46     def logaction_start(self, action):
47         super(_Reporter, self).logaction_start(action)
48         if action.activity == "getenv":
49             teamcity.testSuiteStarted(action.id)
50             self.current_suite = action.id
51
52     def logaction_finish(self, action):
53         super(_Reporter, self).logaction_finish(action)
54         if action.activity == "runtests":
55             teamcity.testSuiteFinished(action.id)
56
57     def error(self, msg):
58         super(_Reporter, self).error(msg)
59         name = teamcity.current_test_name()
60         if name:
61             if name != teamcity.topmost_suite:
62                 teamcity.testFailed(name, msg)
63             else:
64                 teamcity.testFailed("ERROR", msg)
65                 teamcity.testSuiteFinished(name)
66         else:
67             sys.stderr.write(msg)
68
69     def skip(self, msg):
70         super(_Reporter, self).skip(msg)
71         name = teamcity.current_test_name()
72         if name:
73             teamcity.testFinished(name)
74
75
76 config = tox_config.parseconfig()
77 for env, tmp_config in config.envconfigs.items():
78     if not tmp_config.setenv:
79         tmp_config.setenv = dict()
80     tmp_config.setenv.update({"_jb_do_not_call_enter_matrix": "1"})
81     commands = tmp_config.commands
82     if not isinstance(commands, list) or not len(commands):
83         continue
84     for fixer in _RUNNERS:
85         for i, command in enumerate(commands):
86             fixed_command = fixer.fix(command)
87             if fixed_command:
88                 commands[i] = fixed_command
89     tmp_config.commands = commands
90
91 session = tox_session.Session(config, Report=_Reporter)
92 teamcity.testMatrixEntered()
93 session.runcommand()