你的第一个故事
开始编写自己的测试,并学习什么样的测试才是有用的。
什么是故事?
如前所述,我们将构建一个简单的待办事项应用来学习如何进行测试。我们的第一步是让用户创建任务。在敏捷开发环境中,我们称其为一个 故事。
每个故事都必须包含验收标准。验收标准是对某个功能的描述,该功能必须实现才能完成这个故事。在我们的例子中,验收标准如下:用户必须能够打开应用,输入任务名称,按下回车键,并在任务列表中看到自己的任务。
为什么验收标准如此重要?原因非常明确:它用于编写第一个集成测试。基于这个集成测试,我们再编写单元测试。当单元测试写好并失败后,我们开始编写代码来修复这些单元测试。一旦所有单元测试都通过了,集成测试也应该能通过。
编写集成测试
编写集成测试其实相当简单。你只需根据验收标准(或任何功能的英文描述)将其翻译成 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.waituntil和Bydriver.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 元素。