• 聊一聊游戏的压测 at 2020年11月07日
    1. 游戏服务器的承载力似乎都是转换到最大承载玩家 PCU 估值。并发数量级可以按照上行 tcp 包每秒数量计算,单接口的压测这样计算是没有问题的。不过游戏跟 http 压测不同的部分,很多功能要考虑能够承载同时对多少个客户端进行消息广播,n 个上行并发可能导致 n*n 个下行广播。我这边交报告的时候,1)估算一个整体的 PCU,2)单接口给一个最大 TPS,3)广播消息给实际 PCU。
    2. 数据标准参考一下大厂就好了。CPU 整体不超过 80%,单核不要到 100%(大概率是死循环)。内存除了关注整体占用,以及压测结束后能否按预定释放。儒雅一点的办法是找程序确认内存释放的预定是怎样,然后针对性的找突破点,做了内存缓存数据的就测到最高限制,有些内存释放后并不直接释放给系统可以用多轮压测不断塞数据清数据。粗暴的办法,就是跑长时间的压测了。还有流量、文件操作符、慢查询、日志错误数量、进程状态,这些要看一下监控。要想保障不出问题,CPU、内存是需要主动去尝试触发故障的,而不仅仅是记录压测脚本执行时的数值。
  • 献上膝盖

  • python 版 appcrawler at 2020年11月07日

    👍 这个真的很棒,学习了

  • idb ui 系列的命令没法在真实设备使用,所以以前用 wda 的短期可能还要用 wda。
    目前真是设备上的测试,idb 是比较好用的 XCUITest 启动器和辅助工具。原生的 XCUITest 完全可以解决应用的自动化不需要使用 wda,纯个人经验。

  • 知道原理可能更难过,因为不会做。
    另外,用 Dell Mobile Connect 吧,这个不收费。

  • 不过最近的技术发展是很快的,分享一些个人的研究心得吧。

    1. OCR:结论是用开源的 PaddleOCR 就好了。探索过程比较坎坷,避免别人重新踩坑吧。下决心搭之前去官网的 demo 看看效果。
    2. 脚本编排:只要是按顺序编排脚本的,不愿意用 sleep,就只能使用 wait_until_apear 等特定图片出现。不过现在有腾讯开源的 GameAISDK,其中 UIReg 那块儿就是另外的思路,这个框架很酷,他们有专门出一本工具书,买一本还是值得的。
    3. 图片识别:大家可能真的有些误解,目前大部分能用于自然场景的图像算法用在游戏中算是绰绰有余的,比如 airtest 用的特征匹配只需要稍微过滤一下误匹配点就好了。之前帮友人用 python 翻译了用在自然场景里的处理方式,感兴趣的可以来看一下https://github.com/MishimaAsuka/svf 。另外的结论是:文字最好用 OCR,3d 模型最好自己用 yolov3 训练个分类器。
    4. AI 自动化:结论是用 GameAISDK 吧。别想太多,非利益相关,咱自己有一套框架,而且因为整过这个活儿才得出这个结论。还有一个实际问题,缺游戏的数据集,非常缺。
  • 我可以看到你实现了一个简单的 socket 客户端,但是用于自动化测试或者压测都过于简陋了。在游戏自动化测试中,你需要处理服务器主动推送的消息,例如同场竞技的其他玩家的操作同步,以短连接的同步通信思路去设计测试框架其应用范围是及其有限的。在压测中,你需要学会引入异步 IO 来增加目前压测工具的并发处理能力,尝试用 gevent 或者其他异步 IO 网络库去实现压测客户端。更重要的是无论是自动化测试或者压测,让通信过程顺利运行起来只是一部分工作。游戏的接口返回值真的可以满足功能验证的要求吗?最后,游戏测试技术落后 5 年并非是所有游戏测试从业者的感受,游戏测试有其特殊的情况存在,引擎技术方案不统一、各大公司间的直接竞争关系导致游戏测试技术很难直接参照和公开交流。但或许只是我的自我感觉,归根结底像是王者荣耀、阴阳师这些游戏的测试技术水平到底是领先还是落后,谁又说的清呢?

  • gatling 获取 cookie at 2020年06月14日

    这行代码设置的 cookie 是类似这样的东西:
    {
    "Name" : "foo",
    "Value" : "newName",
    "Domain" : "foo.com"
    }
    打开浏览器 F12,进入 application,查看一下 testerhome.com 的 cookie 就能稍微理解一下它们的含义

  • gatling 获取 cookie at 2020年05月03日

    .exec(getCookieValue(CookieKey("foo").withDomain("foo.com").saveAs("newName")))

  • 聊一聊游戏的压测 at 2020年04月26日

    确实是体力活,说到这,我以前还用过一种很狂野的写法压缩代码量。都是黑历史了,不过可以贴出来供大家乐一乐
    def use_item_42413(response):
    locals().update(response)
    try:
    bag_type != 2 and get_bag(2) and 1/0
    bag_type == 2 and item_list[42413] < 100 and add_item(2, 42413, 100) and 1/0
    use_item(2, 42413, 100)
    except:
    return False
    简单解释一下就是:1.通过把字典塞到 locals() 里,然后就能直接把字典的 key 当局部变量取值 2.用 and/or 组成的条件链省去写 if/else 和调整缩进的时间 3.条件链里面不能通过 return 跳过后面几行的语句执行,用了 try/catch 和主动抛异常的取巧办法。