def execute_run(self, suite_list, extensions, include_suites, robot_arg_dict): """ Sources a series of test suites and then makes the RPC call to the slave to execute the robot run. :param suite_list: List of paths to test suites or directories containing test suites :type suite_list: list :param extensions: String that filters the accepted files extensions for test suites :type extensions: str :param include_suites: List of strings that filter suites to include :type include_suites: list :param robot_arg_dict: Dictionary of arguments that will be passed to robot.run on the remote host :type robot_arg_dict: dict :return: Dictionary containing stdout/err, log html, output xml, report html, return code :rtype: dict """ # Use robot to resolve all of the test suites suite_list = [os.path.normpath(p) for p in suite_list] logger.debug('Suite List: ' + str(suite_list)) # Let robot do the heavy lifting in parsing the test suites builder = TestSuiteBuilder(include_suites, extension=extensions) suite = builder.build(*suite_list) # Now iterate the suite's family tree, pull out the suites with test cases and resolve their dependencies. # Package them up into a dictionary that can be serialized self._package_suite_hierarchy(suite) # Make the RPC logger.info('Connecting to: ' + self._address) response = self._client.execute_robot_run(self._suites, self._dependencies, robot_arg_dict, self._debug) return response
def build(self, name="Untitled Test Suite"): """ Build a test suite """ # pylint: disable=W0212 self.suite = TestSuiteBuilder()._build_suite(self.test_data) self.suite._name = name return self
def execute_ipywidget( kernel: DisplayKernel, data: TestCaseString, listeners: list, silent: bool, display_id: str, name, arguments, values, ): header = getattr(data.testcase_table, "name", "Tasks") or "Tasks" table = f"""\ *** {header} *** {name} {name} {' '.join([values[a[1]] for a in arguments])} """ data.testcase_table.tests.clear() data.populate(table) # Build builder = TestSuiteBuilder() data.source = os.getcwd() # allow Library and Resource from CWD work suite = builder._build_suite(data) suite._name = "Jupyter" with TemporaryDirectory() as path: run_robot_suite(kernel, suite, listeners, silent, display_id, path, widget=True)
def TestSuiteFactory(datasources, **options): settings = RobotSettings(options) if isinstance(datasources, basestring): datasources = [datasources] suite = TestSuiteBuilder().build(*datasources) suite.configure(**settings.suite_config) return suite
def main(self, datasources, **options): settings = RobotSettings(options) LOGGER.register_console_logger(**settings.console_output_config) LOGGER.info('Settings:\n%s' % unic(settings)) builder = TestSuiteBuilder(settings['SuiteNames'], extension=settings.extension, rpa=settings.rpa) suite = builder.build(*datasources) settings.rpa = builder.rpa suite.configure(**settings.suite_config) if settings.pre_run_modifiers: suite.visit( ModelModifier(settings.pre_run_modifiers, settings.run_empty_suite, LOGGER)) with pyloggingconf.robot_handler_enabled(settings.log_level): old_max_error_lines = text.MAX_ERROR_LINES text.MAX_ERROR_LINES = settings.max_error_lines try: result = suite.run(settings) finally: text.MAX_ERROR_LINES = old_max_error_lines LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.stat_message) if settings.log or settings.report or settings.xunit: writer = ResultWriter( settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return result.return_code
def execute_robot( kernel: DisplayKernel, code: str, data: TestCaseString, listeners: list, silent: bool, ): # Build builder = TestSuiteBuilder() data.source = os.getcwd() # allow Library and Resource from CWD work suite = builder._build_suite(data) suite._name = "Jupyter" # Run display_id = str(uuid.uuid4()) if suite.tests: with TemporaryDirectory() as path: reply = run_robot_suite(kernel, suite, listeners, silent, display_id, path) else: last_code = getattr(kernel, "_last_code", "") if code == last_code: setattr(kernel, "_last_code", "") else: inject_ipywidgets(kernel, code, data, listeners, silent, display_id) setattr(kernel, "_last_code", code) reply = {"status": "ok", "execution_count": kernel.execution_count} return reply
def main(self, datasources, **options): settings = RobotSettings(options) LOGGER.register_console_logger(**settings.console_output_config) LOGGER.info('Settings:\n%s' % unic(settings)) builder = TestSuiteBuilder(settings['SuiteNames'], extension=settings.extension, rpa=settings.rpa) suite = builder.build(*datasources) settings.rpa = builder.rpa suite.configure(**settings.suite_config) if settings.pre_run_modifiers: suite.visit(ModelModifier(settings.pre_run_modifiers, settings.run_empty_suite, LOGGER)) with pyloggingconf.robot_handler_enabled(settings.log_level): old_max_error_lines = text.MAX_ERROR_LINES text.MAX_ERROR_LINES = settings.max_error_lines try: result = suite.run(settings) finally: text.MAX_ERROR_LINES = old_max_error_lines LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.stat_message) if settings.log or settings.report or settings.xunit: writer = ResultWriter(settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return result.return_code
def main(self, datasources, **options): settings = RobotSettings(options) LOGGER.register_console_logger(**settings.console_output_config) LOGGER.info('Settings:\n%s' % unic(settings)) if settings['WarnOnSkipped'] is not None: LOGGER.error("Option '--warnonskippedfiles is deprecated and " "has no effect.") builder = TestSuiteBuilder(settings['SuiteNames'], extension=settings.extension, rpa=settings.rpa) suite = builder.build(*datasources) settings.rpa = builder.rpa suite.configure(**settings.suite_config) if settings.pre_run_modifiers: suite.visit( ModelModifier(settings.pre_run_modifiers, settings.run_empty_suite, LOGGER)) with pyloggingconf.robot_handler_enabled(settings.log_level): result = suite.run(settings) LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.stat_message) if settings.log or settings.report or settings.xunit: writer = ResultWriter( settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return result.return_code
def TestSuiteFactory(datasources, **options): settings = RobotSettings(options) if is_string(datasources): datasources = [datasources] suite = TestSuiteBuilder(process_curdir=False).build(*datasources) suite.configure(**settings.suite_config) return suite
class TestCopy(unittest.TestCase): def setUp(self): self.suite = TestSuiteBuilder().build(MISC_DIR) def test_copy(self): self.assert_copy(self.suite, self.suite.copy()) def assert_copy(self, original, copied): assert_not_equal(id(original), id(copied)) self.assert_same_attrs_and_values(original, copied) for attr in ['suites', 'tests', 'keywords']: for child in getattr(original, attr, []): self.assert_copy(child, child.copy()) def assert_same_attrs_and_values(self, model1, model2): assert_equal(dir(model1), dir(model2)) for attr, value1, value2 in self.get_non_property_attrs( model1, model2): if callable(value1) and callable(value2): continue assert_equal(id(value1), id(value2), attr) if isinstance(value1, ModelObject): self.assert_same_attrs_and_values(value1, value2) def get_non_property_attrs(self, model1, model2): for attr in dir(model1): if isinstance(getattr(type(model1), attr, None), property): continue value1 = getattr(model1, attr) value2 = getattr(model2, attr) yield attr, value1, value2 def test_deepcopy(self): self.assert_deepcopy(self.suite, self.suite.deepcopy()) def assert_deepcopy(self, original, copied): assert_not_equal(id(original), id(copied)) self.assert_same_attrs_and_different_values(original, copied) # It would be too slow to test deepcopy recursively like we test copy. def assert_same_attrs_and_different_values(self, model1, model2): assert_equal(dir(model1), dir(model2)) for attr, value1, value2 in self.get_non_property_attrs( model1, model2): if attr.startswith('__') or self.cannot_differ(value1, value2): continue assert_not_equal(id(value1), id(value2), attr) if isinstance(value1, ModelObject): self.assert_same_attrs_and_different_values(value1, value2) def cannot_differ(self, value1, value2): if isinstance(value1, ModelObject): return False if type(value1) is not type(value2): return False # None, Booleans, small numbers, etc. are singletons. try: return id(value1) == id(copy.deepcopy(value1)) except TypeError: # Got in some cases at least with Python 2.6 return True
def test__variable_kw__pass(): suite = TestSuiteBuilder().build( os.path.join(path, 'fixtures/robot/variable.robot')) result = suite.run(output=None, variablefile=os.path.join(path, 'fixtures/robot/common.py')) assert result.return_code == 0
def setUp(self): self.resource_dir = os.path.join(os.path.dirname(__file__), 'rf_client_test_resources') builder = TestSuiteBuilder() parent_suite = builder.build(self.resource_dir) self.ts1 = parent_suite.suites[1] self.test_obj = RemoteFrameworkClient('127.0.0.1')
def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False): # Support %%python module ModuleName cell magic match = re.match('^%%python module ([a-zA-Z_]+)', code) if match is not None: module = match.groups()[0] return self.do_execute_python( code[len('%%python module {0:s}'.format(module)):], module, silent, store_history, user_expressions, allow_stdin) # Populate data = TestCaseString() try: for historical in self.robot_history: data.populate(historical) data.testcase_table.tests.clear() data.populate(code) except Exception as e: if not silent: self.send_error({ 'ename': e.__class__.__name__, 'evalue': str(e), 'traceback': list(format_exc().splitlines()), }) return { 'status': 'error', 'ename': e.__class__.__name__, 'evalue': str(e), 'traceback': list(format_exc().splitlines()), } # Build builder = TestSuiteBuilder() suite = builder._build_suite(data) suite._name = 'Jupyter' # Run if suite.tests: reply = self.run_robot_suite(suite, silent) else: reply = { 'status': 'ok', 'execution_count': self.execution_count, } # Save history if reply['status'] == 'ok': self.robot_history.append(code) return reply
def get_suite_testcases(self, test_suite_path): """ parse test case name from robot test suite :param test_suite_path: :return: test names list """ settings = RobotSettings() builder = TestSuiteBuilder(settings['SuiteNames'], settings['RunEmptySuite']) data = builder._parse(test_suite_path) tests = [test.name for test in data.testcase_table.tests] print('\n'.join(tests)) return tests
def Run(self, path, **options): debug = options.pop('debug', self.debug) # post processed options settings = RobotSettings(**options) builder = TestSuiteBuilder() suite = builder.build(path) with self._context: runner = Runner(self._output, settings) suite.visit(runner) result = runner.result if debug and result.return_code: reraise(*self._output._last_fail_exc) return TestResult(runner.result, **options)
def main(self, datasources, **options): settings = RobotSettings(options) LOGGER.register_console_logger(**settings.console_logger_config) LOGGER.info('Settings:\n%s' % unicode(settings)) suite = TestSuiteBuilder(settings['SuiteNames'], settings['WarnOnSkipped'], settings['RunEmptySuite']).build(*datasources) suite.configure(**settings.suite_config) result = suite.run(settings) LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.stat_message) if settings.log or settings.report or settings.xunit: writer = ResultWriter(settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return result.return_code
def build_suite(code: str, cell_history: Dict[str, str]): # Init data = TestCaseString() data.source = os.getcwd() # allow Library and Resource from CWD work # Populate history, but ignore tests for historical in cell_history.values(): data.populate(historical) data.testcase_table.tests.clear() # Populate current data.populate(code) # Wrap up builder = TestSuiteBuilder() suite = builder._build_suite(data) suite._name = "Jupyter" return suite
def main(self, data_sources, **options): settings = RobotSettings(options) LOGGER.register_console_logger(**settings.console_output_config) LOGGER.info("Settings:\n%s" % unic(settings)) suite = TestSuiteBuilder(settings['SuiteNames'], settings['WarnOnSkipped'], settings['Extension']).build(*data_sources) suite.configure(**settings.suite_config) self._support_python_path(options) self._split_tests(suite) # 递归,找到所有的tests, 写入self.long_names self._assert_data_source( data_sources) # 只取第一个DataSource, 写入self.data_source self._assert_test_count() # 如果没有要测试的, 直接退出, 返回码: 1 self.output_dir = settings['OutputDir'] self.clean_output_dir() # 删掉主要输出目录下所有东东, 类似rm -rf self.output_dir self.log_debug_info(options) p_num = (int(options['processes']) if 'processes' in options else 2 * cpu_count()) start_time, end_time = self.parallel_run(options, p_num) self.merge_report(start_time, end_time)
def _runTest(self, parsed, **options): settings = RobotSettings(options) LOGGER.register_console_logger(width=settings['MonitorWidth'], colors=settings['MonitorColors'], markers=settings['MonitorMarkers'], stdout=settings['StdOut'], stderr=settings['StdErr']) LOGGER.info('Settings:\n%s' % six.text_type(settings)) suite = TestSuiteBuilder( settings['SuiteNames'], settings['WarnOnSkipped'], settings['RunEmptySuite'])._build_suite(parsed) suite.configure(**settings.suite_config) result = suite.run(settings) LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.statistics.message) rc = result.return_code if settings.log or settings.report or settings.xunit: writer = ResultWriter(settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return rc
class RobotFramework(Application): def __init__(self): self.logger1 = new_logger_for_thread() Application.__init__(self, USAGE, arg_limits=(1, ), env_options='ROBOT_OPTIONS', logger=self.logger1) self.settings = None self.suite = None def main(self, datasources, **options): self.settings = RobotSettings(options) self.logger1.register_console_logger( **self.settings.console_output_config) self.logger1.info('Settings:\n%s' % unic(self.settings)) self.suite = TestSuiteBuilder( self.settings['SuiteNames'], self.settings['WarnOnSkipped']).build(*datasources) self.suite.configure(**self.settings.suite_config) if self.settings.pre_run_modifiers: self.suite.visit( ModelModifier(self.settings.pre_run_modifiers, self.settings.run_empty_suite, self.logger1)) with pyloggingconf.robot_handler_enabled(self.settings.log_level): result = self.suite.run(self.settings) self.logger1.info("Tests execution ended. Statistics:\n%s" % result.suite.stat_message) if self.settings.log or self.settings.report or self.settings.xunit: writer = ResultWriter( self.settings.output if self.settings.log else result) writer.write_results(self.settings.get_rebot_settings()) return result.return_code def validate(self, options, arguments): return self._filter_options_without_value(options), arguments def _filter_options_without_value(self, options): return dict((name, value) for name, value in options.items() if value not in (None, []))
def main(self, datasources, **options): self.settings = RobotSettings(options) self.logger1.register_console_logger( **self.settings.console_output_config) self.logger1.info('Settings:\n%s' % unic(self.settings)) self.suite = TestSuiteBuilder( self.settings['SuiteNames'], self.settings['WarnOnSkipped']).build(*datasources) self.suite.configure(**self.settings.suite_config) if self.settings.pre_run_modifiers: self.suite.visit( ModelModifier(self.settings.pre_run_modifiers, self.settings.run_empty_suite, self.logger1)) with pyloggingconf.robot_handler_enabled(self.settings.log_level): result = self.suite.run(self.settings) self.logger1.info("Tests execution ended. Statistics:\n%s" % result.suite.stat_message) if self.settings.log or self.settings.report or self.settings.xunit: writer = ResultWriter( self.settings.output if self.settings.log else result) writer.write_results(self.settings.get_rebot_settings()) return result.return_code
def _runTest(self, parsed, **options): settings = RobotSettings(options) output_config = getattr(settings, 'console_output_config', { 'width': getattr(settings, 'console_width', 78), 'colors': getattr(settings, 'console_colors', 'AUTO'), 'markers': getattr(settings, 'console_markers', 'AUTO'), 'stdout': settings['StdOut'], 'stderr': settings['StdErr'] }) LOGGER.register_console_logger(**output_config) LOGGER.info('Settings:\n%s' % six.text_type(settings)) suite = TestSuiteBuilder( settings['SuiteNames'], settings['WarnOnSkipped'])._build_suite(parsed) suite.configure(**settings.suite_config) result = suite.run(settings) LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.statistics.message) rc = result.return_code if settings.log or settings.report or settings.xunit: writer = ResultWriter(settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return rc
def main(self, datasources, **options): for key, value in options.items(): if not value: options.pop(key) settings = RobotSettings(options) LOGGER.register_console_logger(**settings.console_output_config) LOGGER.info('Settings:\n%s' % unic(settings)) suite = TestSuiteBuilder(settings['SuiteNames'], settings['WarnOnSkipped'], settings['Extension']).build(*datasources) suite.configure(**settings.suite_config) data_sources = '"' + '" "'.join(datasources) + '"' logFolder = settings['OutputDir'] if options.has_key('processes'): p_num = int(options['processes']) else: p_num = 2 * cpu_count() #默认两倍cpu核数 longname = [] testnames = self._split_tests(suite, longname) #递归,找到所有的tests extra_options_cmd = self.unresolve_options(options) #运行前先清理环境,主要是把一些Output文件和图片文件清除 self.clear_env(logFolder) #生成并行运行命令并运行 self.parallel_run(testnames, logFolder, data_sources, extra_options_cmd, p_num) #合并报告 rebotCommand = 'rebot --outputdir "' + logFolder + '" --merge "' + logFolder + '/*_Output.xml"' print(rebotCommand) merge_proc = subprocess.Popen(rebotCommand, shell=True) merge_proc.communicate()
def _runTest(self, parsed, **options): settings = RobotSettings(options) output_config = getattr( settings, 'console_output_config', { 'width': getattr(settings, 'console_width', 78), 'colors': getattr(settings, 'console_colors', 'AUTO'), 'markers': getattr(settings, 'console_markers', 'AUTO'), 'stdout': settings['StdOut'], 'stderr': settings['StdErr'] }) LOGGER.register_console_logger(**output_config) LOGGER.info('Settings:\n%s' % six.text_type(settings)) suite = TestSuiteBuilder( settings['SuiteNames'], settings['WarnOnSkipped'])._build_suite(parsed) suite.configure(**settings.suite_config) result = suite.run(settings) LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.statistics.message) rc = result.return_code if settings.log or settings.report or settings.xunit: writer = ResultWriter(settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return rc
def main(self, datasources, **options): settings = RobotSettings(options) LOGGER.register_console_logger(**settings.console_output_config) LOGGER.info("Settings:\n%s" % unic(settings)) suite = TestSuiteBuilder(settings["SuiteNames"], settings["WarnOnSkipped"]).build(*datasources) suite.configure(**settings.suite_config) if settings.pre_run_modifiers: suite.visit(ModelModifier(settings.pre_run_modifiers, settings.run_empty_suite, LOGGER)) with pyloggingconf.robot_handler_enabled(settings.log_level): result = suite.run(settings) LOGGER.info("Tests execution ended. Statistics:\n%s" % result.suite.stat_message) if settings.log or settings.report or settings.xunit: writer = ResultWriter(settings.output if settings.log else result) writer.write_results(settings.get_rebot_settings()) return result.return_code
def _run(suite_path, test_case, results_dir): suite = TestSuiteBuilder().build(suite_path) suite.configure(include_tests=test_case.decode('utf-8')) result = suite.run(output='{0}/{1}.xml'.format(results_dir, test_case).decode('utf-8')) return {'passed': result.statistics.suite.stat.passed, 'failed': result.statistics.suite.stat.failed}
def setUp(self): self.suite = TestSuiteBuilder().build(MISC_DIR)
class InteractiveRunner(LoggingConfigurable): """ An interactive Robot Framework runner """ def __init__(self, silent=False): super().__init__() self.silent = silent self._tmpdir = TemporaryDirectory() self.path = Path(self._tmpdir.name) self.suite = None self.results = None self.stdout = None self._handlers = defaultdict(list) self.test_data = irobot.TestCaseString() def __del__(self): self._tmpdir.cleanup() @property def failed(self): """ wrapper for crazy-long path """ try: return self.results.statistics.total.critical.failed except AttributeError: return 0 def populate(self, *code): """ Populate with some code lines """ list(map(self.test_data.populate, code)) return self def clear_tests(self): """ Clear the tests table """ self.test_data.testcase_table.tests.clear() return self def build(self, name="Untitled Test Suite"): """ Build a test suite """ # pylint: disable=W0212 self.suite = TestSuiteBuilder()._build_suite(self.test_data) self.suite._name = name return self def on_suite(self, handler): """ Set a listener for start events """ self._handlers[irobot.SuiteEventListener].append(handler) def on_status(self, handler): """ Set a listener for status events """ self._handlers[irobot.StatusEventListener].append(handler) def on_return_value(self, handler): """ Set a listener for return values """ self._handlers[irobot.ReturnValueListener].append(handler) def on_import(self, handler): """ Set a listener for imports """ self._handlers[irobot.ImportListener].append(handler) def run(self): """ Run the built suite """ with importnb.Notebook(): with StringIO() as stdout: self.results = self.suite.run( outputdir=str(self.path), stdout=stdout, listener=sum( [ list(map(klass, handlers)) for klass, handlers in self._handlers.items() ], [], ), ) self.stdout = stdout.getvalue().strip().splitlines() return self
def build(*paths): paths = [normpath(join(DATADIR, p)) for p in paths] suite = TestSuiteBuilder().build(*paths) assert_true(isinstance(suite, TestSuite)) assert_equal(suite.source, paths[0] if len(paths) == 1 else None) return suite
from robot.running import TestSuiteBuilder suite = TestSuiteBuilder().build("./google_search.robot") result = suite.run()
def build(path): return TestSuiteBuilder().build(join(DATADIR, path))
__author__ = 'teemu kanstren' from robot.running import TestSuiteBuilder from robot.api import ResultWriter from io import StringIO #https://robot-framework.readthedocs.io/en/3.0/autodoc/robot.running.html suite = TestSuiteBuilder().build("./include.robot") stdout = StringIO() result = suite.run(output="test_output.xml", include="*crit", stdout=stdout) ResultWriter("test_output.xml").write_results(report='report.html', log="log.html") output = stdout.getvalue() print(output)
__author__ = 'teemu kanstren' from robot.running import TestSuiteBuilder from robot.api import ResultWriter #https://robot-framework.readthedocs.io/en/3.0/autodoc/robot.running.html suite = TestSuiteBuilder().build("./noncritical.robot") result = suite.run(output="test_output.xml", noncritical="*crit") ResultWriter("test_output.xml").write_results(report='report.html', log="log.html")
def test__address__pass(): suite = TestSuiteBuilder().build(os.path.join(os.getcwd(), 'app2.robot')) result = suite.run(output=None) assert result.return_code == 0
class TestCopy(unittest.TestCase): def setUp(self): path = os.path.normpath(os.path.join(__file__, '..', '..', '..', 'atest', 'testdata', 'misc')) self.suite = TestSuiteBuilder().build(path) def test_copy(self): self.assert_copy(self.suite, self.suite.copy()) def assert_copy(self, original, copied): assert_not_equal(id(original), id(copied)) self.assert_same_attrs_and_values(original, copied) for attr in ['suites', 'tests', 'keywords']: for child in getattr(original, attr, []): self.assert_copy(child, child.copy()) def assert_same_attrs_and_values(self, model1, model2): assert_equal(dir(model1), dir(model2)) for attr, value1, value2 in self.get_non_property_attrs(model1, model2): if callable(value1) and callable(value2): continue assert_equal(id(value1), id(value2), attr) if isinstance(value1, ModelObject): self.assert_same_attrs_and_values(value1, value2) def get_non_property_attrs(self, model1, model2): for attr in dir(model1): if isinstance(getattr(type(model1), attr, None), property): continue value1 = getattr(model1, attr) value2 = getattr(model2, attr) yield attr, value1, value2 def test_deepcopy(self): self.assert_deepcopy(self.suite, self.suite.deepcopy()) def assert_deepcopy(self, original, copied): assert_not_equal(id(original), id(copied)) self.assert_same_attrs_and_different_values(original, copied) # It would be too slow to test deepcopy recursively like we test copy. def assert_same_attrs_and_different_values(self, model1, model2): assert_equal(dir(model1), dir(model2)) for attr, value1, value2 in self.get_non_property_attrs(model1, model2): if attr.startswith('__') or self.cannot_differ(value1, value2): continue assert_not_equal(id(value1), id(value2), attr) if isinstance(value1, ModelObject): self.assert_same_attrs_and_different_values(value1, value2) def cannot_differ(self, value1, value2): if isinstance(value1, ModelObject): return False if type(value1) is not type(value2): return False # None, Booleans, small numbers, etc. are singletons. try: return id(value1) == id(copy.deepcopy(value1)) except TypeError: # Got in some cases at least with Python 2.6 return True
def setUp(self): path = os.path.normpath(os.path.join(__file__, '..', '..', '..', 'atest', 'testdata', 'misc')) self.suite = TestSuiteBuilder().build(path)