Logo
Section 1 / 4

你的第一个故事

开始编写自己的测试,并学习什么样的测试才是有用的。

导入

你的第一个故事

开始编写自己的测试,并学习什么样的测试才是有用的。

什么是故事?

如前所述,我们将构建一个简单的待办事项应用来学习如何进行测试。我们的第一步是让用户创建任务。在敏捷开发环境中,我们称其为一个 故事。

每个故事都必须包含验收标准。验收标准是对某个功能的描述,该功能必须实现才能完成这个故事。在我们的例子中,验收标准如下:用户必须能够打开应用,输入任务名称,按下回车键,并在任务列表中看到自己的任务。

为什么验收标准如此重要?原因非常明确:它用于编写第一个集成测试。基于这个集成测试,我们再编写单元测试。当单元测试写好并失败后,我们开始编写代码来修复这些单元测试。一旦所有单元测试都通过了,集成测试也应该能通过。

...
典型的TDD工作流程

编写集成测试

编写集成测试其实相当简单。你只需根据验收标准(或任何功能的英文描述)将其翻译成 JavaScript 代码即可。为此,你需要了解几个 Selenium 函数:

  • driver.get(url):打开一个网页。
  • driver.wait(condition, timeout):等待某个条件满足。通常用于等待页面加载时元素出现。
  • driver.findElement / driver.findElements:在网页上查找元素。

以及一些辅助函数:

  • By:此函数作为参数用于查找元素。例如:
    • By.id("textInput")
    • By.className("wrapper")
    • By.xpath("//input")
    • driver.findElement(By.tagName("div"))
  • until:此函数作为 wait 函数的参数使用。例如:
    • until.elementLocated(By.id("submitBtn"))
    • until.titleContains("abacaba")
    • wait(until.elementLocated(By.name("wrapper")), 1000)

现在我们可以开始写测试了。将 integration-tests 目录下的文件 sample.test.js 重命名为 create-task.test.js,并将测试用例名称改为 should create tasks,删除除 driver.get("http://localhost:3000") 以外的所有内容。添加以下导入语句:

1import {until, By, Key} from 'selenium-webdriver';

测试任务创建的第一步是等待任务输入框渲染完成。你可以通过以下代码实现:

1await driver.wait(until.elementLocated(By.xpath("//input[@placeholder='Enter new task']")), 1000);

这行代码指示驱动程序最多等待一秒钟,直到具有指定占位符的输入元素被渲染出来。

我们使用 XPath 语法来查找元素。如果你不熟悉 XPath,本课程末尾会提供一份速查表。

元素渲染完成后,我们需要向其中输入文本并按下回车键。可以通过以下代码实现:

1await driver.findElement(By.xpath("//input[@placeholder='Enter new task']")) 2 .sendKeys('new todo!' + Key.ENTER);

这行代码找到目标元素,并发送一系列按键操作,最后按回车键。

输入新任务后,需要等待该任务在页面上显示出来:

1await driver.wait(until.elementLocated(By.xpath("//*[text()='new todo!']")), 1000);

这行代码查询文档中是否存在包含文本 "new todo!" 的任意元素。

最终你应该得到如下结果:

No configuration found for ID: 3825df1e321597365b870d0e27fadeb50de1bc5da3dafe02aa6d504dff7c7a7b

由于这是一个集成测试,你需要先通过 npm start 启动开发服务器,然后使用 npm run integration-tests 来运行测试。你会看到如下输出:

1 RUNS integration-tests/create-task.test.js 2 3 FAIL integration-tests/create-task.test.js (6.529s) 4 × should create tasks (4755ms) 5 6 ● should create tasks 7 8 TimeoutError: Waiting for element to be located By(xpath, //input[@placeholder='Enter new task']) 9 Wait timed out after 1041ms 10 11 at node_modules/selenium-webdriver/lib/webdriver.js:842:17 12 13Test Suites: 1 failed, 1 total 14Tests: 1 failed, 1 total 15Snapshots: 0 total 16Time: 7.332s 17Ran all test suites matching /integration-tests/i.

注意错误信息:TimeoutError: Waiting for element to be located By(...)。这意味着 Selenium 在等待元素出现,但始终没有等到。这是预料之中的,因为我们还没有编写对应的代码。

你可能会注意到,这个测试非常简单;它并不对页面结构或已有待办事项的数量做任何假设。这正是你在集成测试中所期望的。测试应尽可能简单,以确保应用的实现不依赖于测试的具体实现方式。测试只需描述行为,而将实现细节留白。

快速回顾

在本节课中,我们学习了如何将英文描述的故事转化为集成测试。我们使用了 selenium-webdriver 中的以下函数:

  • driver.wait
  • until 和 By
  • driver.findElement

在下一节课中,我们将从这个集成测试出发,编写单元测试。

XPath 速查表

选择标签:

  • //h1:选择所有 H1 元素。
  • //article//p:选择所有位于 ARTICLE 元素内部的 P 元素。

排序:

  • //ul/li[1]:选择 UL 元素的第一个子 LI。
  • //a[last()]:选择文档中最后一个 A 元素。

属性:

  • //*[@id='input']:选择 id 属性为 'input' 的元素。
  • //div[@class='wrapper']:选择所有具有 class 属性为 'wrapper' 的 DIV 元素。

简介

TDD 生命周期回顾