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

漆黑的橘子 · 2020年12月01日 · 最后由 lipenglo 回复于 2021年01月16日 · 597 次阅读

公司要求搭建 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 中的框架都很简单,我找不到太多和我类似的情况的问题

共收到 24 条回复 时间 点赞

问题 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 中吧

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

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