• func1 最后一行是 return func2,func2 不加括号就是返回 func2 这个函数本体,所以执行 func3 = func1(1) 的时候相当于 func3 = func2,再执行 func3(2) 时等同于执行 func2(2)

    python 里函数也是对象,可以用来作为参数传递和赋值,这里贴一个高阶函数的教程https://www.liaoxuefeng.com/wiki/1016959663602400/1017328525009056

  • 之前也见过一些人在做录制回放和云真机平台的集成,确实降低了使用要求和学习成本,作者能够完成这样一个平台并落地,发文章出来,想来也应该是有一定成效,但还是有一些疑问希望提出来大家共同探讨。

    1. UI 通常包含多个部分的内容,例如样式、文案、动态内容和用户状态,使用截图对比的方式会不会 UI 稍微一变动就会报错,缺少容错性;截图对比具体是靠什么指标去判断断言是否通过呢,相似度么,会有一个绝对差值么。

    2. 如果一条用例中有一小部分改动了,这个时候怎样去维护用例呢,修改 solopi 指令不能达到模拟手动操作的效果会需要重新录制脚本么。

    3. 用截图对比和录制的方式,可以做到兼容性测试么,录制的用例能否覆盖多个主流机型。

    4. 开发这样一个 UI 自动化平台大概需要多少人天

  • 同楼上,楼主在避免处理魔术方法时把带__的方法都漏掉了,漏掉了__classcell__,所以报 DeprecationWarning,高版本 python 应该会报 RuntimeError,漏掉了__init__,类创建后默认使用了无参初始化方法,所以报 MetaClassTest() takes no arguments

    class LowerAttrMetaClass_4(type):
        def __new__(mcs, name, bases, attr):
            attr = {key if key[:2] == "__" else key.lower(): value for key, value in attr.items()}
            return type.__new__(mcs, name, bases, attr)
    
    
    class MetaClassTest(metaclass=LowerAttrMetaClass_4):
        Say = "hello world"
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def Run(self):
            print("MetaClassTest run method")
    
    
    tmp_obj = MetaClassTest(name="zzz", age=20)
    tmp_obj.run()
    # >>>
    # MetaClassTest run method
    
    1. 最关键的问题在于不应该把进入 home page 和 rgbcw page 的方法写在 setup class,rgbcw 页面会覆盖 home page
    2. 测试用例应该职责分离,test_in_contexts 和 test_in_rgbcw_page 这两个依赖 home page 的用例不应该出现 TestRgbcw 中,而实际应该出现在 TestHomePage 中,把 self.home_page 和两条 home page 的用例移除掉,TestRgbcw 应该是可以跑的。
    3. 最好每条测试用例都环境隔离,即一个类下面每条 case 的初始页面应该是一样的,每条用例执行完后可以回到初始页面或者重新加载页面。
  • pytest 怎么异步执行用例呢 at 2022年01月26日
    1. 可以安装 pytest-asyncio 插件,安装插件后有两种方式运行异步函数,①使用 pytest.mark.asyncio 标记测试用例,②配置文件里写 asyncio_mode = auto,pytest 会自动识别异步函数然后用异步的方式执行。
    2. 加了异步插件后,不影响之前的同步测试用例和 fixture,如果需要使用异步 fixture,可以加@pytest_asyncio.fixture
    3. pytest-asyncio 插件原理上是把异步协程封装成同步函数,只是给用例执行套了一层壳,原则上不影响 pytest 原有功能和其他插件
    4. 异步协程只能提高并发量,并不能减少网络 io 时间,而 pytest 是按顺序运行测试用例的,所以使用异步并不能减少测试的执行时间。
  • xmind 本质上来讲是一个多叉树数据结构,而测试用例算是一个数据类,这中间的转化过程主要分为两步:

    1. 如何对树的所有节点进行归类 (辨别它们归属于同一条 case)
    2. 如何对归类后的数据进行职能匹配 (识别哪些是标题信息、步骤、预期结果、辅助信息) 简单的解析方式是把一条路径解析成一条 case(对应归类),通过固定路径上节点的 index 来匹配职能 (对应匹配)

    您的问题点在于:

    1. 贴图片、代码、测试思路 => 扩充了节点的职能和数据类型,从编程角度来讲算是增加了测试用例数据类的字段和支持非文本节点解析,难度并不高。
    2. 由扩充节点引发了第二个问题,需求、技术实现、测试思路等辅助信息 (细节) 可能位置相对分散,不容易固定,及如何对这些节点进行归类会相对复杂一点,但我相信一定是有规律可循,您也可以相对制定一些使用规则来方便分类这些信息,最简单的方式是打标记。

    规范不是为了限制 xmind 和使用人原有的能力,而是为了方便抽离转化的普遍规律以及统一使用人的认知和习惯。

    综上,您目前的问题虽说增加了归类和匹配的复杂度,但是并没有超出转化模型的能力范围,是完全能够解决的,编程是把抽象的逻辑信息化,在用例转化这个问题上,只要您能看懂文档 (更希望团队的所有人都能看懂),计算机也就能看懂、识别、转化,并不存在特别的限制。

    1. 首先讲讲 xmind 的优点,利于发散,快捷键生成不同节点比 excel 等编辑更顺畅,格式简单且方便收折...总体来讲编写和阅读体验会比传统的 excel 或者在线编辑更好,这个没什么疑问,所以 xmind 是首选。=> 一定要用 xmind。

    2. 关于强格式规范,虽说有固定解析规则,但解析规则其实并不多,因为测试用例核心要素本就不多,迭代名称取 root 节点,用例标题按照中间的路径生成,倒数两个节点解析为操作步骤、预期结果,比起以往其实只多了一个预期结果。大部分人不喜欢写预期结果,而不喜欢写预期结果的原因在于结果一般是常识性问题,所以预期结果不复杂时可以写得很简单 (例如 “执行成功”,“数据展示 ok”),当然前提是操作步骤和预期结果等算是常识时才尽量精简,如果复杂的话,还是写得准确些更好。说起是规范,但更多的是约定大于配置,这些约定基本是符合人的思考方式和常识的,并不是强制制定一个规范而让大家都来遵守。=> 规则不多,且符合常识和 xmind 使用习惯,推行时学习成本很低。

    3. 从规范上来讲,争议最大的点应该是操作步骤和预期结果是否应该写得很详细以及重复的内容是否应该写几遍,关于这两点,①有操作步骤和预期结果应该是下限,写得完整且准确应该是上限。每一个有追求的测试人员都应该守住下限,提高上限。测试用例是需要评审的,需要用于开发自测,产品验收的,需要后人接手的,如果没有下限,将会是灾难。②重复内容可使用父节点和概要归纳为一个节点,相对减少重复编写的内容。=> 问题看似很难,实际不难。

    4. 关于接受度,我个人使用上来讲非常能够接受,因为和我之前的编写习惯基本一致,反而因为规范,我写的用例比之前更加清晰明了;其他人至少基本没有不能接受的,也有一部分人觉得现在细节还不够,希望再增加一些规则 (例如优先级、编写人) => 基于上面的原因,目前接受度还行。

    贴一份最近写的完全符合解析规则的用例吧,虽说内容相对简单,但是书写思路和复杂用例是一样的,用例编写难在设计,书写反而是简单的 (类似编程)。

  • 现状和道理很多人都或多或少有感触,关键还是要如何去破局,转行转岗就不说了,就说说怎么在这条路坚持下去。
    职业发展往上走,都是需要综合素质和影响力的,看似瓶颈,但实际上能做的还有很多。测开和开发、产品等岗位本质上都是一样的,运用自己的知识、经验,提供交付能力,只是侧重点略微不同而已。

    说点实际的吧,我个人的话是预期在未来往两个方向努力:

    1. 个人能力,提升开发、产品体系、测试经验总结、沉淀
    2. 建立体系的能力,包括业务测试、自动化、效能

    瓶颈归瓶颈,真正遇到瓶颈的人,哪怕晋升再难,实际过得也已经很不错了,慢慢沉淀呗,总是有各个方面需要提升的。另外真有其他打算,也可以换条赛道。

  • 这道题只是一道简单的字符串题,一个遍历就搞定,不涉及动态规划。具体的动态规划可以搜一下动态规划标签的题

  • 我看了下内存占用,开 IJ WS PC DG 四个 IDE+chrome 几个网页 + 一个通讯软件的情况下就占用 16G 了,8G 不够用的

  • 我每天正事不干,光琢磨着怎么炫技去了😂
    正常项目里面我可能会分成两个装饰器去写,尽量避免不同类型的入参和出参

  • 看见 python 代码,手痒,用类的实现方式也写了一个玩玩

    class loop:
    
        def __init__(self, times):
            self.func = times if callable(times) else None
            self.times = times if isinstance(times, int) else 5
    
        def __call__(self, *args, **kwargs):
            if self.func is None:
                self.func = args[0]
                return self.__call__
            for i in range(self.times):
                self.func(*args, **kwargs)
                print(f"运行的第{i + 1}次")
    
  • 这种情况我个人能想到的就还是多模板匹配了,个人比较擅长用图像识别的方式做 UI 自动化。

    1. 把不同座位的图截下来
    2. 遍历座位模板,多模板匹配,找出图中不同座位的分布信息
    3. 组合不同座位的分布信息,就可以得到上面我说的整体座位信息矩阵。分类的话就是按模板来的,匹配什么模板,就对应什么分类信息

    4. 涉及坐标变化,通常坐标变化都是有规律的,操作完之后记录整体的坐标变化量或者复位之后再继续操作也行。

    5. 可能还涉及不同设备的兼容性问题 (用图像识别都会遇到这个问题),先搞定上面的问题再看吧

    这个方案能解决问题,就是需要对图像处理和识别比较熟练。

  • 突然想到自绘的话也是从后端接口拿的数据,可以先请求后端座次信息接口,再计算对应坐标点,通过坐标的方式操作控件。

  • 问题的核心还是在于拿不到控件信息吧,用图像识别的多模板匹配是可以做到获取控件信息的。
    只要实现这样一个函数,就可以解决问题,
    输入:座位截图
    输出:座位信息矩阵
    [
    [Seat(), Seat(), Seat(), Seat(), Seat()],
    [Seat(), Seat(), Seat(), Seat(), Seat()],
    [Seat(), Seat(), Seat(), Seat(), Seat()],
    [Seat(), Seat(), Seat(), Seat(), Seat()],
    ]
    Seat 类里面包含了座位的是否可选、价格、类型等信息

  • 资源池的创建和销毁主要是靠框架维护,按任务隔离,每个任务都给一个 id,在任务执行完 (或执行异常) 时清掉该任务创建的资源。

    我的场景还不太一样,最初的痛点是经常会按不同的维度去划分服务,有时按系统分,有时按场景分,有时又按业务领域分,但是他们的一些基础依赖 (例如各个系统的登录、数据库连接等等) 又是会有重叠的,每个服务都自己创建一遍资源太浪费,每个资源都自己维持一个单例或者资源池又可能会受不同任务的并发影响,索性建立了一个按任务隔离的上下文 + 资源管理池。

    接口间这个数据传参我倒没有像楼主这样按 key、value 去划分,通常粒度控制在 DTO(对象,字典) 范围,我司的跨接口或跨系统传参经常都是按对象去传,比如一个订单要填地址信息,这个地址信息通常不是单个字段,而是包含姓名、电话、地址等多个字段的集合,我从获取地址信息的接口拿到这个集合,更改一下不同的 key 或者类型,多出来的不管,把它传递到下一个下单的接口。

  • 挺不错的实践,我最近在解决类似依赖问题的时候也是采用了同样的方案,用资源池解决上下游的耦合以及避免资源的重复创建,用依赖注入来减少主动去资源池拉资源的代码。
    主要的思想来源是 spring 和recoil

  • json 本质还是一个树结构呀,参考树的遍历,比较简单的就是使用递归或者栈。

  • 我见过的后端代码通常都比较简单粗暴,并不难懂,稍微熟悉一下 spring 框架,了解下分层思想和基础写法就可以了。时常感叹用 python 来写业务,代码少一半都不止。

    这个问题和是否掌握自己调试没关系,我前后端自己都能写,一样把 bug 修复交给开发去做,各个系统都有各种坑,这些坑开发都趟过,代码也是开发自己写的,设计细节,写法这些都是他本人最清楚,测试 debug 还要去理解每个开发的写法、思路、业务细节、实现细节,比开发自己调试慢很多。我通常只有在很明显能判断出大致错误原因时,才会给出自己大致的判断,然后走读代码确认是否和自己的判断一致。走读代码和 debug 程序只是为了提升自己,能提升效率时顺带提升效率,所有 bug 都自己去 debug,就谈不上效率了 。

  • 合理的,之前公司有这样做,研发自测用例其实和冒烟用例差不多的,主要作用在于保证提测时迭代主流程质量,不会因为主流程阻塞导致拖延测试进度。
    提供研发自测用例对于测试来说是好事,能提升提测质量,也给了测试人员卡提测准入的权利,最怕的反而是有规则却不遵守,开发一直忙于赶进度,不自测,联调敷衍了事,把问题留到测试阶段而且阻塞测试流程和进度。

  • 感觉测试类型还是跟着业务走的,之前在在线教育公司,就直播、报表、资讯、线索类挺多的。后来在货运公司,就音视频录制,地图、调度方面内容挺多的。

    感觉按大类分还是可行,比如报表、线索、活动、埋点都偏运营和数据方向。小程序、H5、APP 什么的属于用户端口

  • 没做过两年业务测试,但是居然全都接触测过。。不过感觉不应该这样分,太乱了。可以先分几个大类,再来细分小的

  • 很抱歉,以前用不上特征匹配,对 opencv 特征匹配这块的内容不熟,所以上面的回答有一些误导,今晚重新看了下文档,再回答一下。

    1. 关于我讲的取最大可信度的方法,其实用 flann.match(des1, des2) 就可以,match 方法是取最优结果,knnMatch 通过传入 k 值来取多个结果,我的做法就是用 match 就行了。
    2. 特征匹配这一块,airtest 算是实践相对较多的,去看了一下源码,有题主预期的代码实现,跳过去看就行了。 https://github.com/AirtestProject/Airtest/blob/master/airtest/aircv/sift.py
    1. 单独处理比较麻烦,可以把判断的部分做成参数,比如加个 side 参数,target = driver.sift_detect(source, side="left"),这样去调用就只判断屏幕左半部分的内容,右边的过滤掉,side 就由自己去设计了,上下左右,居中什么的都可以。

    2. 置信度就是相似度,你用来判断两个物体是否相似的阈值,查出来的结果是一个列表,通过相似度排序后取最大,这样虽然不 100% 准确,但是大多数情况下有效。

    1. 通过坐标点过滤,比如这个页面的 “同意” 按钮,坐标会更居中,靠下。
    2. 通过置信度过滤,多个返回结果可以优先取最大的一个。