Selenium UI 自动化测试中遇到的问题,希望可以获得大佬们的解答

漆黑的橘子 · 2020年12月01日 · 最后由 lam 回复于 2023年10月08日 · 3200 次阅读

公司要求搭建 UI 的自动化测试,我用的 pytest+Python3+ChromeDriver+selenium,现在写了几百个 case,但是遇到了很多问题,并且执行时间很长,我搜索了很多的网站,但是并没有搜索到针对我的问题而言很有用的资料,所以在这里发帖求助,看看大家是否有什么思路可以供给我,万分感谢
问题:
1、抛开连接 SQL 外,有什么其他好的方法回收么?公司不允许我这边连接生产的库,所以我在 case 中手写的数据回收,如在 case 中建数据 A,依据 A 执行用例,而后删除 A,这样有个隐患就是一旦 case 执行失败了,那么后续数据回收的步骤也全部受到影响,导致我这边的环境会有大量的垃圾数据,因为系统之中有些垃圾数据影响是全局的,会影响其他使用同样的用例,从而造成连锁反应,导致用例成功率不稳定,忽上忽下的,并且执行完成后还需要手动删除垃圾数据。
2、公司做的是 ToB 的 Web 端 SaaS 服务,用域名 + 用户账号来进行分离,并且账号不允许多端登录,如何进行并发?之前是单线程执行,现在希望提速,我准备用 redis,每次执行自动化测试时,将这些账号放到 redis 账号池中,每个用例从池子中取出账号后,将其状态标识为不可用,后续的 case 不能使用该账号,只能选取其他账号,case 执行完成后,释放该账号,将其状态变为可用,我不知道这样是不是最佳实践,但是目前能解决我的困境,如果有好的方案,希望可以和我分享
3、系统中存在的 ajax 请求、异步操作的情况下,如何提高 UICase 的成功率?比如 A 账号登录后,更新其某个状态,这里面会有一些异步操作,比如 MYSQL、ES 的读写,触发相关服务的 sidekiq 操作等,因为在异步操作执行期间,前端会有一个状态变更成功的假象,所以用 UI 定位状态变更成功,但是后续执行时可能会导致异步操作没有处理完,状态更新操作执行后,后端数据没有更新完毕,导致 case 执行失败,在这些问题上,我现在迫不得已用 sleep 来解决的,ajax 的请求也一样,我不知道是否有更优的解决方案,这很困扰我,同时也影响了 case 的成功率及执行速度

现在我在优化我自己的框架,但是思路很混乱,我不知道这样做是对是错,网上包括 GitHub 中的框架都很简单,我找不到太多和我类似的情况的问题

共收到 25 条回复 时间 点赞

问题 1 考不考虑在 teardown 里直接删除所有数据

狂天 回复

想过,但是我没想好怎么告诉 teardown 方法我要删除那条数据,传参给 teardown 么?我不能直接删除最新的一条数据,这样就会给后续的并发埋坑😂

看了一眼想说换接口吧,其次做个基础数据,跑完自动化全部回滚,不要在一个问题上纠结太深,换个角度就简单了。

TestOps 云层 回复

测试环境可以这么做,生产环境数据回滚肯定不让操作😂

生产数据做一个标志位,让开发在代码里面把这些数据写影子库。。或者多租户,这个账户就给测试用。。。

TestOps 云层 回复

刚刚跟负责 DBA 的同事沟通了一下,这个方案给否了,说风险太大,为了自动化测试做这么个功能不值当,他提出可以单独在 SQL 上切个 shard 出来,这个 shard 上给自动化测试专用,但是需要 money,我司扣得一匹,批钱这条路可太难了

生产上就别做那么大规模的自动化测试了:)这东西都是需要在底层上提前实现好的

文中不是讲的不让在生产库中操作么?
问题 1. 你需要知道自己的操作到底操作哪些数据,case 都固定的步骤,怎么会不知道操作了哪些数据了呢? 放在 TearDown 里面去清除数据,这个大家应该都是这么做的。框架都是提供给你让你这么玩的。
问题 2:提速可能会有个问题,如果多用户同时操作,那么对于用例之间的隔离很重要,多个用例同时操作这个系统,随时可能会造成对多用户对同一数据操作导致用例失败。
问题 3:其实可以想一下,在手动点点点的测试过程中,我们是如何判断测试通过与否呢(或者说系统更新成功与否呢)?然后用代码替代人为判断就可以了。

1 和 3 都遇到过
1、回收数据如果无法使用 SQL,在事后处理确实容易受到用例本身运行情况的影响,可以考虑把回收工作做到测试的事前处理。这样的好处一是稳定,不受测试用例本身的影响。二是如果测试失败,还留有测试数据更容易复现问题。
3、对于异步处理,如果页面直接反馈的信息不准确,可以直接根据后端数据的变化来进行断言。设置一个比正常处理时间稍长的阀值,对结果数据做轮询。前提是在前端能查到用来做标志位的数据。

1.把用例回收改写成初始化,让所有用例在同样环境执行。
2.多弄点账号,并发时根据并发数分配不同账号
3.我一般也 sleep

Ouroboros 回复

初始化不了,因为并发的时候会有多个 case 一起建数据,一旦初始化了,其他并发 case 可能受影响;sleep 的话我看好多人都说不要写 sleep,但是真的找不到更好地解决方法啊,唉

t-bug 回复

好的,谢谢,我再想想怎么做

fiskeryang 回复

事前处理是什么意思呢?提前建好么?

他的意思应该是在 setup 中数据初始化,保证数据库是干净的。

t-bug 回复

单线程可以,并发的话一旦初始化不就影响其他并发的 case 了么

不管是在 setup 和 teardown 里面做这些事情,都会遇到你说的并发的问题。个人觉得现在有两种方案:

  1. 简单粗暴一点的: 对于 case 强制分类,数据会影响的放到一组。 不影响的放到另外一组,所以在并发的时候,多组之间的用例是不会相互影响的。
  2. 高级一点的:在每个用例运行的时候,初始化自己的数据库,如 H2, 这样所有的用例都是有自己的数据库(运行完毕后释放即可),就不会相互影响了。

不是事前建 而是事前删 😂
不清楚你的具体情况,各个用例之间的数据会有依赖吗,
设计用例时 最好是每个用例都能单独跑 这是一个原则

1.先把用例分类,把相互影响的用例拎出来。
2.该拆的拆,该分隔的分隔(设计好并发方案)
3.理论上可以做到大部分独立不会相互影响的

fiskeryang 回复

没法事前删,数据都是按照 ‘功能名称’+ 随机字符串写的,如果根据名称正则匹配的,则不知道是不是以前 case 遗留的数据,有些数据是全局影响的,所以实际上 case 之间会有依赖的

Ouroboros 回复

嗯,不大范围改动代码的情况下这样处理是最优解了

可以在初始化的时候 就对数据进行清理,以前我是这样写的

我个人建议 不要把账号放在 redis 中 ,redis 只是起到放临时数据,你还是把账号放到 mysql 中吧

自动化的理念中就有一条 不要在生产上做自动化测试

我也有碰到你说的问题 1 和 2。
针对问题 1,我的处理方式跟你一样,另外,我是在每个用例执行前再检查一下这个用例可能涉及的业务是否存在脏数据并清除,但是我觉得也并不是最优解。但是其实我认为可能最优解是一个 class 下就一个用例,这样这个用例就有一个对应的 teardown,这样就算用例失败,teardown 也会执行的。
针对问题 2,我也很苦恼。不知道问题 2 你是否实践成功。你是用 pytest-xdist 实现并发的吗

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册