1 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 """this module contains base classes for windmill integration |
|
19 |
|
20 :todo: |
|
21 |
|
22 * import CubicWeb session object into windmill scope to be able to run RQL |
|
23 * manage command line option from pytest to run specific use tests only |
|
24 """ |
|
25 |
|
26 |
|
27 import os, os.path as osp |
|
28 from logging import getLogger, ERROR |
|
29 import sys |
|
30 |
|
31 # imported by default to simplify further import statements |
|
32 from logilab.common.testlib import TestCase, unittest_main, Tags |
|
33 |
|
34 try: |
|
35 import windmill |
|
36 from windmill.dep import functest |
|
37 from windmill.bin.admin_lib import configure_global_settings, setup, teardown |
|
38 except ImportError: |
|
39 windmill = None |
|
40 |
|
41 from cubicweb.devtools.httptest import CubicWebServerTC, CubicWebServerConfig |
|
42 |
|
43 if windmill is None: |
|
44 class CubicWebWindmillUseCase(CubicWebServerTC): |
|
45 tags = CubicWebServerTC.tags & Tags(('windmill',)) |
|
46 |
|
47 def testWindmill(self): |
|
48 self.skipTest("can't import windmill") |
|
49 else: |
|
50 # Excerpt from :ref:`windmill.authoring.unit` |
|
51 class UnitTestReporter(functest.reports.FunctestReportInterface): |
|
52 def summary(self, test_list, totals_dict, stdout_capture): |
|
53 self.test_list = test_list |
|
54 |
|
55 unittestreporter = UnitTestReporter() |
|
56 functest.reports.register_reporter(unittestreporter) |
|
57 |
|
58 class CubicWebWindmillUseCase(CubicWebServerTC): |
|
59 """basic class for Windmill use case tests |
|
60 |
|
61 If you want to change cubicweb test server parameters, define a new |
|
62 :class:`CubicWebServerConfig` and override the :var:`configcls` |
|
63 attribute: |
|
64 |
|
65 configcls = CubicWebServerConfig |
|
66 |
|
67 From Windmill configuration: |
|
68 |
|
69 .. attribute:: browser |
|
70 identification string (firefox|ie|safari|chrome) (firefox by default) |
|
71 .. attribute :: edit_test |
|
72 load and edit test for debugging (False by default) |
|
73 .. attribute:: test_dir (optional) |
|
74 testing file path or directory (windmill directory under your unit case |
|
75 file by default) |
|
76 |
|
77 Examples: |
|
78 |
|
79 browser = 'firefox' |
|
80 test_dir = osp.join(__file__, 'windmill') |
|
81 edit_test = False |
|
82 |
|
83 If you prefer, you can put here the use cases recorded by windmill GUI |
|
84 (services transformer) instead of the windmill sub-directory |
|
85 You can change `test_dir` as following: |
|
86 |
|
87 test_dir = __file__ |
|
88 |
|
89 Instead of toggle `edit_test` value, try `python <test script> -f` |
|
90 """ |
|
91 browser = 'firefox' |
|
92 |
|
93 edit_test = "-i" in sys.argv # detection for pytest invocation |
|
94 # Windmill use case are written with no anonymous user |
|
95 anonymous_allowed = False |
|
96 |
|
97 tags = CubicWebServerTC.tags & Tags(('windmill',)) |
|
98 |
|
99 def _test_dir(self): |
|
100 """access to class attribute if possible or make assumption |
|
101 of expected directory""" |
|
102 try: |
|
103 return getattr(self, 'test_dir') |
|
104 except AttributeError: |
|
105 if os.path.basename(sys.argv[0]) == "pytest": |
|
106 test_dir = os.getcwd() |
|
107 else: |
|
108 import inspect |
|
109 test_dir = os.path.dirname(inspect.stack()[-1][1]) |
|
110 return osp.join(test_dir, 'windmill') |
|
111 |
|
112 def setUp(self): |
|
113 # Start CubicWeb session before running the server to populate self.vreg |
|
114 CubicWebServerTC.setUp(self) |
|
115 # XXX reduce log output (should be done in a cleaner way) |
|
116 # windmill fu** up our logging configuration |
|
117 for logkey in ('windmill', 'logilab', 'cubicweb'): |
|
118 getLogger(logkey).setLevel(ERROR) |
|
119 self.test_dir = self._test_dir() |
|
120 msg = "provide a valid 'test_dir' as the given test file/dir (current: %s)" |
|
121 assert os.path.exists(self.test_dir), (msg % self.test_dir) |
|
122 # windmill setup |
|
123 windmill.stdout, windmill.stdin = sys.stdout, sys.stdin |
|
124 configure_global_settings() |
|
125 windmill.settings['TEST_URL'] = self.config['base-url'] |
|
126 if hasattr(self,"windmill_settings"): |
|
127 for (setting,value) in self.windmill_settings.iteritems(): |
|
128 windmill.settings[setting] = value |
|
129 self.windmill_shell_objects = setup() |
|
130 |
|
131 def tearDown(self): |
|
132 teardown(self.windmill_shell_objects) |
|
133 CubicWebServerTC.tearDown(self) |
|
134 |
|
135 def testWindmill(self): |
|
136 if self.edit_test: |
|
137 # see windmill.bin.admin_options.Firebug |
|
138 windmill.settings['INSTALL_FIREBUG'] = 'firebug' |
|
139 windmill.settings.setdefault('MOZILLA_PLUGINS', []).extend( |
|
140 ['/usr/share/mozilla-extensions/', |
|
141 '/usr/share/xul-ext/']) |
|
142 controller = self.windmill_shell_objects['start_' + self.browser]() |
|
143 self.windmill_shell_objects['do_test'](self.test_dir, |
|
144 load=self.edit_test, |
|
145 threaded=False) |
|
146 # set a breakpoint to be able to debug windmill test |
|
147 if self.edit_test: |
|
148 import pdb; pdb.set_trace() |
|
149 return |
|
150 |
|
151 # reporter |
|
152 for test in unittestreporter.test_list: |
|
153 msg = "" |
|
154 self._testMethodDoc = getattr(test, "__doc__", None) |
|
155 self._testMethodName = test.__name__ |
|
156 # try to display a better message in case of failure |
|
157 if hasattr(test, "tb"): |
|
158 msg = '\n'.join(test.tb) |
|
159 self.assertEqual(test.result, True, msg=msg) |
|
160 |
|