javascript - 有没有办法根据其他测试的结果来运行特定的 Protractor 测试?

标签 javascript jasmine protractor

此类问题以前曾被问过,但大多数问题都有相当复杂的背景。 场景很简单。假设我们正在测试我们最喜欢的 TODO 应用程序。 接下来是测试用例: TC00 - “用户应该能够将 TODO 项目添加到 TODO 列表中” TC01 - “用户应该能够重命名 TODO 项目” TC02 - “用户应该能够删除 TODO 项目” 如果 TC00 失败,我不想运行 TC01 和 TC02(未添加 TODO 项,因此我没有任何可删除或重命名的内容)

过去三天我一直在研究这个问题,这个问题最常见的答案是: • 您的测试不应相互依赖 • Protractor/Jasmine 没有动态打开/关闭测试的功能(“it” block ) 我在这里问这个问题的原因是因为它看起来是一个非常普遍的案例,但仍然没有明确的建议来处理这个问题(我的意思是我找不到任何建议) 我的 JavaScript 技能很差,但我知道我需要尝试一下,比如说“传递“完成””或在内部测试中添加 if...

it('should add a todo' ()=> {
  todoInput.sendKeys('test')
  addButton.click();
  let item = element(by.cssContainingText('.list-item','test')
  expect(item.isPresent()).toBe(true)
}

就我而言,将项目添加到列表后大约有 15 个测试(“it” block )。如果“父”测试失败,我想跳过一些测试。 请注意: 有一种解决方案允许在失败时跳过所有剩余测试。这不符合我的需求

最佳答案

伙计,我花了好几周的时间研究这个问题,是的,没有明确的答案,直到我意识到 Protractor 的详细工作原理。如果您也了解这一点,您就会找到最适合您的选择。

简短理论后的解决方案如下

1) 如果您尝试将异步函数传递给describe,您会发现它会失败,因为它只接受同步函数

这对你来说意味着,无论你想传递给它的条件是什么,它都不能是基于 Promise 的(Promise == 有时会解析,但不会立即解析)。你想做的本质上是一个 promise (打开页面,做一些事情,然后看看条件是否满足你的标准)

if (conditionIsTrue) { // can't be Promise
  it('name', () => {
  })
}

这是首先要考虑的事情......

2) 当您运行 Protractor 时,它会选取配置中指定的规范文件并构建 describe/itbeforeAll/afterAll block 的队列。这里重要的细节是它发生在浏览器启动之前。

看这个例子

let conditionIsTrue; // undefined
  it('name', () => {
    conditionIsTrue = true;
  })
if (conditionIsTrue) { // still undefined
  it('name', () => {
  })
}

当 Protractor 到达 if() 语句时,conditionIsTrue 的值仍然是未定义。当浏览器稍后启动时,它可能会在 it block 内部被覆盖,但在构建队列时不会。所以它会跳过它。

换句话说, Protractor 在打开浏览器之前就知道它将运行哪些描述 block ,并且在执行过程中无法修改该队列

可能的解决方案

1.1 在describe之外定义全局变量

let conditionIsTrue; // undefined
describe("describe", () => {
  it('name1', async () => {
    conditionIsTrue = await element.isPresent(); // NOW IT'S TRUE if element is present
  })

  it('name2', async () => {
    if (conditionIsTrue) {
      //do whatever you want if the element is present
    } else {
      console.log("Skipping 'name2' test")
    }
  })
})

因此您不会跳过 it block 本身,但您可以跳过 it 内部的任何内容

1.2 使用环境变量,可以使用相同的方法跨不同规范跳过 it block 。示例:

spec_1.js

describe(`Suite: 1`, () => {
  it("element is present", async () => {
    if (await element.isPresent()) {
      process.env.FLAG = true
    } else {
      process.env.FLAG = false
    }
  });
});

spec_2.js

describe(`Suite: 2`, () => {
  it("element is present", async () => {
    if (process.env.FLAG) {
      // do element specific actions
    }
  });
});
  • 我发现但从未有机会检查的另一种可能性是使用 Grunt 任务运行程序,它可以帮助您实现以下场景

    • 运行 Protractor 来执行一项规范
    • 检查所需条件
    • 将此条件导出到环境变量
    • 退出 Protractor
    • 在您的 Grunt 任务中,通过再次启动 Protractor 来实现条件逻辑,以执行其余的条件规范
  • 但说实话,我不明白你为什么要走这条耗时的路线,这需要大量代码......但仅供引用

    关于javascript - 有没有办法根据其他测试的结果来运行特定的 Protractor 测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56898145/

    相关文章:

    javascript - 在 jQuery 中合并对象,具有 $.extend 函数的相反效果

    javascript - 使用 Jasmine 测试 TypeScript 生成的类

    javascript - Protractor - 将元素值从 pageObject 传递到 spec

    Protractor - 如何为不同的测试重用相同的规范文件

    javascript - 根据搜索显示 div

    javascript - 选择 5 个随机元素

    javascript - jquery.load() 的问题

    javascript - Jasmine :我如何声明 'its' 循环而不是 'expects' 循环来测试 Angular 工厂?

    javascript - Exercism 机器人名称、构造函数和 Jasmine 测试套件

    javascript - 如何在 Protractor 测试中获取 Web 服务响应