有没有办法根据其他测试的结果 运行 特定量角器测试?

Is there a way to run particular Protractor test depending on the result of the other test?

这种问题以前有人问过,但是这个问题的大部分背景都很复杂。 场景很简单。假设我们正在测试我们最喜欢的 TODO 应用程序。 接下来是测试用例: TC00-'User should be able to add a TODO item to the TODO list' TC01 - 'User should be able to rename TODO item' TC02 - 'User should be able to remove TODO item' 如果 TC00 失败,我不想 运行 TC01 和 TC02(未添加 TODO 项,所以我没有要删除或重命名的内容)

所以过去 3 天我一直在研究这个问题,这个问题最常见的答案是: • 你的测试不应该相互依赖 • Protractor/Jasmine 没有动态转换 on/off 测试的功能('it' 块) 我在这里问这个问题的原因是因为它看起来像一个非常普遍的案例并且仍然没有明确的建议来处理这个问题(我的意思是我找不到任何) 我的 javascript 技能很差,但我知道我需要玩玩,比方说通过 'done' 或在测试中添加 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' 块)。如果 'parent' 测试失败,我想跳过一些测试。 请注意: 有一个解决方案可以在失败时跳过所有剩余的测试。这不符合我的需要

伙计,我花了好几周的时间研究这个,是的,没有明确的答案,直到我意识到量角器的工作细节。如果你也明白这一点,你就会找到最适合你的选择。

下面是简短理论后的解决方案

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

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

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

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

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

看这个例子

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

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

换句话说,量角器甚至在打开浏览器之前就知道它会 运行 哪个描述块,并且在执行期间无法修改此队列

可能的解决方案

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 块本身,但是您可以跳过 it

中的任何内容

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

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
    }
  });
});
  1. 另一种我发现但一直没有机会检查的可能性是使用 G运行t 任务 运行ner,这可能会帮助您实现以下场景

    • 运行 量角器执行一个规范
    • 检查所需条件
    • 将此条件导出到环境变量
    • 退出量角器
    • 在你的 G运行t 任务中,通过再次启动量角器实现一个条件逻辑来执行其余的条件规范

但老实说,我不明白您为什么要走这条耗时的路线,这需要大量代码...但仅供参考

Protractor 提供了一种方法,它可能会实现您想要实现的目标。 在量角器配置文件中,您可以具有 onPrepare 功能。它实际上是一个回调函数,一旦量角器准备就绪并可用,并且在执行规范之前调用。如果多个功能正在 运行,这将 运行 每个功能一次。

现在据我了解你需要做一个测试或者我们可以说执行一个父函数然后根据它的输出你想要 运行 一些测试而不想 运行 其他测试。

量角器配置文件中的 onPrepare 函数如下所示:

onPrepare: async () => {
        await browser.manage().window().maximize();
        await browser.driver.get('url')
        // continue your parent test steps for adding an item and at the last of function you can assign a global variable say global.itemAdded = true/false based on the result of above test steps. Note that you need to use 'global.' here to make it a global variable which will then be available in all specs 
}

现在在您的规范文件中,您可以 运行 基于 global.itemAdded 变量值

测试 (it())
if(global.itemAdded === true) {
  it('This test should be running' () => {
  })
}

if(global.itemAdded === false) {
  it('This test should not be running' () => {
  })
}