使用多处理时遇到麻烦

时间:2017-01-10 16:21:35

标签: python python-3.x multiprocessing

我目前正致力于在Python 3.5.2中编写测试运行器并实现并行测试执行的多处理。这是我第一次真正使用任何类型的多处理并运行以使其正常工作。

如果您在run方法下方看到,我可以看到我正在使用mp.Poolpool.map通过self._run_spec运行我的测试。这实际上非常有效。我面临的问题是self._run_spec接收插件的副本而不是实际的实例。这使原始插件实例保持不变。

我知道这是一个基于流程如何工作的限制,但不确定如何更改我的实现来解决此问题。

import sys
from typing import cast, List, Dict, Any
from seleniumspec.spec import Spec, SpecContext
import traceback
import multiprocessing as mp
from functools import partial
from seleniumspec.plugin import *


class Runner(object):
    specs = []
    run_specs = []
    plugins = cast(List[Plugin], [])

    def add_specs(self, specs: List[Spec]):
        [self.add_spec(spec) for spec in specs]

    def add_spec(self, spec: Spec):
        self.specs.append(spec)
        for param in spec.params:
            self.run_specs.append({'spec': spec, 'param': param})

    def add_plugins(self, plugins: List[Plugin]):
        [self.add_plugin(plugin) for plugin in plugins]

    def add_plugin(self, plugin: Plugin):
        self.plugins.append(plugin)

    def run(self):
        runner_start_event = RunnerStartPluginEvent(runner=self)
        runner_stop_event = RunnerStopPluginEvent(runner=self)

        # Hook: Runner Start
        for plugin in self.plugins:
            plugin.runner_start(runner_start_event)

        # Run Tests in Parallel
        p = mp.Pool(2)
        p.map(partial(self._run_spec, plugins=self.plugins), self.run_specs)

        # Hook: Runner Stop
        for plugin in self.plugins:
            plugin.runner_stop(runner_stop_event)

    @staticmethod
    def _run_spec(run_spec, plugins=None):
        spec = run_spec['spec']
        param = run_spec['param']
        spec_context = SpecContext()
        spec_context.param = param

        spec_start_event = SpecStartPluginEvent(spec=spec, context=spec_context)
        spec_stop_event = SpecStopPluginEvent(spec=spec, context=spec_context)
        spec_fail_event = SpecFailPluginEvent(spec=spec, context=spec_context)

        # Hook: Spec Start
        for plugin in plugins:
            plugin.spec_start(spec_start_event)

        # Hook: Spec Setup
        for spec_hook in spec.setup_hooks:
            spec_hook(context=spec_context)

        for i, step in enumerate(spec.steps):
            step_start_event = StepStartPluginEvent(step=step)
            step_stop_event = StepStopPluginEvent(step=step)

            try:
                # Hook: Step Start
                for plugin in plugins:
                    plugin.step_start(step_start_event)

                try:
                    step.fn(context=spec_context)
                except AssertionError as e:
                    raise

                # Hook: Step Stop
                for plugin in plugins:
                    plugin.step_stop(step_stop_event)
            except AssertionError as e:
                error = traceback.format_exc()
                spec_fail_event.error = error

                # Hook: Spec Fail
                for plugin in plugins:
                    plugin.spec_fail(spec_fail_event)

                break

        # Hook: Spec Teardown
        for spec_hook in spec.teardown_hooks:
            spec_hook(context=spec_context)

        # Hook: Spec Stop
        for plugin in plugins:
            plugin.spec_stop(spec_stop_event)

        return True

0 个答案:

没有答案