重写 AppiumService 类,添加默认启动参数,并实时显示启动日志

简介: 重写 AppiumService 类,添加默认启动参数,并实时显示启动日志

一、前置说明


Appium的1.6.0版本中引入了AppiumService类,可以很方便的通过该类来管理Appium服务器的启动和停止。经过测试,使用该类的实例执行关闭server时,并没有释放端口号,会导致第二次启动时失败。另外,使用该类启动server,不能在窗口中实时显示日志,不方便调试。因此,可以重写 AppiumService 类的 start 方法和 stop 方法,实现相应功能。


二、代码实现


import logging
from appium.webdriver.appium_service import *
from appium.webdriver.appium_service import AppiumService as OriginalServer
from libs import path, file_util
from libs.cmd_util import cmd_executor as cmd
logger = logging.getLogger(__name__)
class AppiumService(OriginalServer):
    def __init__(self, port=4723, log_file_path=None, tail_log=False):
        super().__init__()
        self.port = port
        self.log_file_path = log_file_path
        # 用于控制是否开启cmd窗口,实时展示日志内容,当调试代码时建议开启
        self.tail_log = tail_log
        if not self.log_file_path:
            self.log_file_path = os.path.join(path.get_log_dir(), f'appium_server_{port}.log')
        if os.path.exists(self.log_file_path):
            os.remove(self.log_file_path)
        self.default_start_args = ['-p', str(self.port),
                                   '-g', self.log_file_path,
                                   '--session-override',
                                   '--log-timestamp',
                                   '--session-override',
                                   '--local-timezone',
                                   '--allow-insecure',
                                   'chromedriver_autodownload'
                                   ]
    def start(self, **kwargs: Any) -> sp.Popen:
        self.stop()
        env = kwargs['env'] if 'env' in kwargs else None
        node: str = kwargs.get('node') or get_node()
        npm: str = kwargs.get('npm') or get_npm()
        main_script: str = kwargs.get('main_script') or get_main_script(node, npm)
        # A workaround for https://github.com/appium/python-client/issues/534
        default_std = sp.DEVNULL if sys.platform == 'win32' else sp.PIPE
        stdout = kwargs['stdout'] if 'stdout' in kwargs else default_std
        stderr = kwargs['stderr'] if 'stderr' in kwargs else default_std
        timeout_ms = int(kwargs['timeout_ms']) if 'timeout_ms' in kwargs else STARTUP_TIMEOUT_MS
        args: List[str] = [node, main_script]
        if 'args' in kwargs:
            args.extend(kwargs['args'])
        # ==================添加这段逻辑(开始):设置默认启动参数=======================
        if self.port:
            args.extend(self.default_start_args)
        # ==================添加这段逻辑(结束):设置默认启动参数=======================
        self._cmd = args
        self._process = sp.Popen(args=args, stdout=stdout, stderr=stderr, env=env)
        error_msg: Optional[str] = None
        startup_failure_msg = (
            'Appium server process is unable to start. Make sure proper values have been '
            f'provided to \'node\' ({node}), \'npm\' ({npm}) and \'main_script\' ({main_script}) '
            f'method arguments.'
        )
        if timeout_ms > 0:
            status_url_path = make_status_url(args)
            try:
                if not self._poll_status(parse_host(args), parse_port(args), status_url_path, timeout_ms):
                    error_msg = (
                        f'Appium server has started but is not listening on {status_url_path} '
                        f'within {timeout_ms}ms timeout. Make sure proper values have been provided '
                        f'to --base-path, --address and --port process arguments.'
                    )
            except AppiumStartupError:
                error_msg = startup_failure_msg
        elif not self.is_running:
            error_msg = startup_failure_msg
        if error_msg is not None:
            if stderr == sp.PIPE and self._process.stderr is not None:
                err_output = self._process.stderr.read()
                if err_output:
                    error_msg += f'\nOriginal error: {str(err_output)}'
            self.stop()
            raise AppiumServiceError(error_msg)
        # ==================添加这段逻辑(开始):是否启动cmd窗口跟踪log日志=======================
        if self.tail_log:
            file_util.tail_log_file(self.log_file_path)
        # ==================添加这段逻辑(结束):是否启动cmd窗口跟踪log日志=======================
        return self._process
    def stop(self) -> bool:
        status = super().stop()
        # 经过实测,原stop()方法执行之后,进程仍被占用,所以这里添加一个关闭进程的逻辑
        cmd.kill_process_by_port(self.port)
        return status
if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    service = AppiumService(port=4723, tail_log=True)
    service.start()


三、Demo验证


执行代码,顺利启动appium server,并启动了一个命令行窗口,实时展示了server的日志。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
5月前
|
缓存 关系型数据库 MySQL
MySQL Binlog--事务日志和BINLOG落盘参数对磁盘IO的影响
MySQL Binlog--事务日志和BINLOG落盘参数对磁盘IO的影响
50 0
|
6月前
|
JSON Java 测试技术
为了理直气壮怼回去,写了一个日志切面输出接口出入参数
我们在日常排查问题过程中知道,入参传错是导致接口调用失败的常见原因之一。特别是提供给第三方调用的**回调接口和openAPI接口**,由于无法保证第三方开发人员的水平,经常问题不断,反反复复找你问为啥掉不通,甚至吐槽写的“啥玩意接口”,这时候你肯定一脸懵逼,怒火中烧,想展开撕逼甩锅大战,但是对方有可能是甲方金主爸爸并且你没有第一时间掌握证据证明证是对方调用的问题,你只能忍着问他是如何调接口的,卑微请求他把传参发过来看看。。。为了扭转局势,挺直腰杆怼回去:能不能靠谱点?今天我们就来讲讲系统服务中如何优雅地实现统一打印接口API参数日志,方便服务端开发快速甩锅还能拿出证据!!!
71 0
为了理直气壮怼回去,写了一个日志切面输出接口出入参数
|
3月前
|
Java 计算机视觉 Python
我的自描外挂制作日志——FPS类游戏的自瞄【优化改进1】
我的自描外挂制作日志——FPS类游戏的自瞄【优化改进1】
37 1
|
3月前
|
人工智能 算法 计算机视觉
我的自描外挂制作日志——FPS类游戏的自瞄【构思准备】
我的自描外挂制作日志——FPS类游戏的自瞄【构思准备】
45 0
|
4月前
|
前端开发
muduo源码剖析之AsyncLogging异步日志类
AsyncLogging是muduo的日志,程序如果直接让文件写日志可能会发生阻塞,muduo前端设计了2个BufferPtr,分别是currentBuffer_和nextBuffer_,还有一个存放BufferPtr的vector(buffers_)。多个前端线程往currentBuffer_写数据,currentBuffer_写满了将其放入buffers_,通知后端线程读。前端线程将currentBuffer_和nextBuffer_替换继续写currentBuffer_。
26 0
|
3月前
|
Java 计算机视觉
我的自描外挂制作日志——FPS类游戏的自瞄【优化改进2】
我的自描外挂制作日志——FPS类游戏的自瞄【优化改进2】
22 0
|
3月前
|
计算机视觉
我的自描外挂制作日志——FPS类游戏的自瞄【验证猜想】
我的自描外挂制作日志——FPS类游戏的自瞄【验证猜想】
26 1
|
7月前
|
XML Java 数据库连接
mybatis参数配置和日志详解~
mybatis参数配置和日志详解~
100 0
|
9月前
|
缓存 安全 Java
JVM中垃圾回收相关参数介绍:大页和NUMA参数+GC日志相关参数
大页和NUMA参数 本节介绍JVM为使用OS而提供的大页和NUMA特性相关的参数。 该参数控制JVM向OS请求内存时使用大页的粒度。使用该参数时需要对OS进行配置,只有OS允许时才能真正启动。参数的默认值与平台相关,一般为false。 在允许使用大页方式向OS请求内存时,如果堆空间小于该阈值,则强制禁止大页使用。该参数的默认值为128MB。 在允许使用大页方式向OS请求内存时,优先在本地节点进行分配。该参数仅适用于Windows系统。 在允许使用大页方式向OS请求内存时,如果OS提供了多种大页的设置,可通过该参数选择其中的大页设置。参数的默认值为0,表示使用OS默认的大页设置。
107 0
|
9月前
|
监控 Java 编译器
【jvm系列-13】jvm性能调优篇---参数设置以及日志分析
【jvm系列-13】jvm性能调优篇---参数设置以及日志分析
156 0