自动化测试RobotFramework学习系列--(三)

294 篇文章 5 订阅
3 篇文章 0 订阅

RobotFramework学习系列--(三)

  前两篇文章讲解了Suite的构造,文件到Robot的数据格式的转化。这篇文章继续讲解

  回到入口函数Robotframework().main()

  8行之前已经讲过了,8行为对suite的配置。9行为重点

1 def main(self, datasources, **options):

2        settings = RobotSettings(options)

3        LOGGER.register_console_logger(**settings.console_logger_config)

4        LOGGER.info('Settings:\n%s' % unicode(settings))

5        suite = TestSuiteBuilder(settings['SuiteNames'],

6                                  settings['WarnOnSkipped'],

7                                  settings['RunEmptySuite']).build(*datasources)

8        suite.configure(**settings.suite_config)

9        result = suite.run(settings)

10        LOGGER.info("Tests execution ended. Statistics:\n%s"

11                    % result.suite.stat_message)

12        if settings.log or settings.report or settings.xunit:

13            writer = ResultWriter(settings.output if settings.log else result)

14            writer.write_results(settings.get_rebot_settings())

15        return result.return_code

suite.run()是robot\running\model.py下TestSuite的方法,具体构造已经在上篇文章中简单讲述了

1 def run(self, settings=None, **options):

2        with STOP_SIGNAL_MONITOR:

3            IMPORTER.reset()

4            pyloggingconf.initialize(settings['LogLevel'])

5            init_global_variables(settings)

6            output = Output(settings)

7            runner = Runner(output, settings)

8            self.visit(runner)

9        output.close(runner.result)

10        return runner.result

   这里出现了with STOP_SIGNAL_MONITOR 这个也算是python中的魔法实现了。这篇文章先讲一下这块,with的原理如下

1、紧跟with后面的语句被执行后后,对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量

2、当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法

  示例代码和输出结果如下

1 class Test:

2    def __enter__(self):

3        print "__enter__"

4        return self

5    def __exit__(self, *exc_info):

6        print "__exit__"

7    def output(self, message):

8        print message

9 with Test() as test:

10    test.output('test')

1 C:\Python27\python.exe E:/test/testwith.py

2 __enter__

3 test

4 __exit__

  返回来看STOP_SIGNAL_MONITOR这个类

1 class _StopSignalMonitor(object):

2

3    def __init__(self):

4        self._signal_count = 0

5        self._running_keyword = False

6        self._orig_sigint = None

7        self._orig_sigterm = None

8

9    def __call__(self, signum, frame):

10        self._signal_count += 1

11        LOGGER.info('Received signal: %s.' % signum)

12        if self._signal_count > 1:

13            sys.__stderr__.write('Execution forcefully stopped.\n')

14            raise SystemExit()

15        sys.__stderr__.write('Second signal will force exit.\n')

16        if self._running_keyword and not sys.platform.startswith('java'):

17            self._stop_execution_gracefully()

18

19    def _stop_execution_gracefully(self):

20        raise ExecutionFailed('Execution terminated by signal', exit=True)

21

22    def start(self):

23        # TODO: Remove start() in favor of __enter__ in RF 2.9. Refactoring

24        # the whole signal handler at that point would be a good idea.

25        self.__enter__()

26

27    def __enter__(self):

28        if signal:

29            self._orig_sigint = signal.getsignal(signal.SIGINT)

30            self._orig_sigterm = signal.getsignal(signal.SIGTERM)

31            for signum in signal.SIGINT, signal.SIGTERM:

32                self._register_signal_handler(signum)

33        return self

34

35    def __exit__(self, *exc_info):

36        if signal:

37            signal.signal(signal.SIGINT, self._orig_sigint)

38            signal.signal(signal.SIGTERM, self._orig_sigterm)

39

40    def _register_signal_handler(self, signum):

41        try:

42            signal.signal(signum, self)

43        except (ValueError, IllegalArgumentException), err:

44            # ValueError occurs e.g. if Robot doesn't run on main thread.

45            # IllegalArgumentException is http://bugs.jython.org/issue1729

46            if currentThread().getName() == 'MainThread':

47                self._warn_about_registeration_error(signum, err)

48

49    def _warn_about_registeration_error(self, signum, err):

50        name, ctrlc = {signal.SIGINT: ('INT', 'or with Ctrl-C '),

51                        signal.SIGTERM: ('TERM', '')}[signum]

52        LOGGER.warn('Registering signal %s failed. Stopping execution '

53                    'gracefully with this signal %sis not possible. '

54                    'Original error was: %s' % (name, ctrlc, err))

55

56    def start_running_keyword(self, in_teardown):

57        self._running_keyword = True

58        if self._signal_count and not in_teardown:

59            self._stop_execution_gracefully()

60

61    def stop_running_keyword(self):

62        self._running_keyword = False

  程序开始运行时执行顺序为:

  1、__enter__():

查看signal是否导入成功,导入成功,则获取一下执行signal.getsignal(),对signal.SIGINT和signal.SIGTERM,这两种信号,一个是Crtl+C触发,一个是进程自身要求中断引起,当程序初始运行时,getsignal返回的都是0

调用_register_signal_handler 对两种信号进行注册,以备将来捕获。在注册时候,使用了signal.signal(signum,self)。请注意这块,signale的第二个参数为捕获到对应信号后的处理函数,此时把self传进去,也就是说处理函数为self()也就是_StopSignalMonito()这块,一会再讲

    此时由于信号只能在主线程设置,所以又判断了一下,给出了相应的告警

  2、退出

    分为两种,接收到SIGINIT or SIGTERM

此时会调用_StopSignalMonito()进行信号处理,这块又用到Python的魔法,__call__()

    其中的逻辑是,接到一次信号,判断自身状态,如果测试在跑,则后续不再进行,执行teardown后正常退出;如果再次接到信号,直接调用系统的SystemExit()。也就是说在程序运行过程中,我们要中断测试,需要按两次Ctrl+C

    然后再执行__exit__(),此时又执行了signal.signal,传入的是Stop_SignalMonito的两个变量,在执行__enter__时被初始化,此时应该都是0,也就是singal.SIG_DFL,进程采用默认操作。退出with

    无故障,直接调用__exit__(),和上述接到中断信号调用__exit__()的流程是一样的

最后:

如果大家对于学习Python有任何问题,学习方法,学习路线,如何学习有效率的问题,可以随时来咨询我,或者缺少系统学习资料的,我做这行年头比较久,自认为还是比较有经验的,可以帮助大家提出建设性建议,这是我的Python交流qun:785128166,有任何问题可以随时来咨询我。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值