
本文旨在解决 cypress page object model (pom) 中常见的 `typeerror: [method] is not a function` 错误。此错误通常发生在尝试直接在类定义上调用方法,而非在其实例化对象上调用时。文章将详细解释此错误的原因,并提供正确的类实例化和方法调用方式,确保在 cypress 测试中 page object 能够正常工作。
在 JavaScript 开发中,TypeError: [object].method is not a function 是一个非常常见的错误。它表明你试图调用的 method 并不是 [object] 的一个可执行函数。在 Cypress 的 Page Object Model (POM) 实践中,这个错误通常意味着你正在尝试在一个类的定义上调用其方法,而不是在一个已经创建的该类的实例(对象)上调用。
当你在 Cypress 测试文件中导入一个 Page Object 类并尝试直接调用其方法时,例如 homePage.populateDataBasedOnJsonValues(data),如果 homePage 仅仅是导入的类定义本身,而非该类的一个实例,就会触发此 TypeError。
理解 JavaScript 中的类(Class)和实例(Instance)是解决此类问题的关键。
简而言之,你不能直接在蓝图上“操作”;你必须先根据蓝图“建造”一个东西(即创建一个实例),然后才能对这个东西进行操作。
考虑以下 Cypress 测试文件 homePageTest.cy.js 的初始代码:
// homePageTest.cy.js
import HomePage from '../Hompage.js'; // 假设这里导入的是类定义
it("some test", () => {
cy.fixture("jsonValues").then((data) => {
// 错误:直接在导入的类定义上调用方法
// HomePage 此时是一个类,而不是类的实例
HomePage.populateDataBasedOnJsonValues(data);
});
});以及对应的 Page Object 类 homepage.js:
// homepage.js
class HomePage {
_getcheckBox(question) {
// 这里的 this.get 假设是 cy.get 的误写,或期望有一个内部的 get 方法
// 正确的 Cypress 做法应直接使用 cy.get
return cy.get(`div[class$='checkbox-component-${question}'] > label > input`);
}
populateDataBasedOnJsonValues(answers) {
for (let key in answers) {
// 错误:在类内部调用其他方法时,必须使用 'this' 关键字
// const question = _getcheckBox(answers[key]); // 这会导致 ReferenceError 或其他问题
const questionElement = this._getcheckBox(answers[key]); // 正确
questionElement.click();
}
}
}
export default HomePage;在 homePageTest.cy.js 中,import HomePage from '../Hompage.js' 语句导入的是 HomePage 类本身,而不是 HomePage 类的一个具体对象。因此,当你尝试执行 HomePage.populateDataBasedOnJsonValues(data) 时,JavaScript 引擎会发现 populateDataBasedOnJsonValues 不是 HomePage 类定义上的静态方法(它是一个实例方法),从而抛出 TypeError: HomePage.populateDataBasedOnJsonValues is not a function。
要解决这个问题,你需要在调用 HomePage 类的方法之前,先创建它的一个实例。这通过 new 关键字来实现。
修改 homePageTest.cy.js 如下:
// homePageTest.cy.js
import HomePage from '../Hompage.js';
// 在测试套件或测试用例开始时,创建 HomePage 类的一个实例
const homePage = new HomePage(); // 关键:实例化 HomePage 类
it("some test", () => {
cy.fixture("jsonValues").then((data) => {
// 现在 homePage 是 HomePage 类的一个实例,可以正常调用其方法
homePage.populateDataBasedOnJsonValues(data);
});
});通过 const homePage = new HomePage();,我们创建了一个名为 homePage 的对象,它是 HomePage 类的一个具体实例。现在,homePage 拥有 HomePage 类中定义的所有实例方法,因此 homePage.populateDataBasedOnJsonValues(data) 可以被正确调用。
除了外部测试文件中的实例化问题,Page Object 内部的方法调用也需要遵循规范。在 HomePage 类内部,当一个实例方法需要调用同一个实例的另一个方法时,必须使用 this 关键字来引用当前实例。
修改 homepage.js 如下:
// homepage.js
class HomePage {
// 确保 _getcheckBox 返回 Cypress 命令链
_getcheckBox(question) {
return cy.get(`div[class$='checkbox-component-${question}'] > label > input`);
}
populateDataBasedOnJsonValues(answers) {
for (let key in answers) {
// 正确:使用 'this' 关键字调用当前实例的 _getcheckBox 方法
const questionElement = this._getcheckBox(answers[key]);
questionElement.click();
}
}
}
export default HomePage;在 populateDataBasedOnJsonValues 方法中,this._getcheckBox(answers[key]) 确保你调用的是当前 HomePage 实例的 _getcheckBox 方法。如果省略 this,JavaScript 会尝试在当前作用域查找一个名为 _getcheckBox 的函数,这通常会导致 ReferenceError。
为了清晰地展示正确的实践,以下是修正后的完整代码示例:
homepage.js (Page Object)
// cypress/page-objects/homepage.js
class HomePage {
// 私有辅助方法,用于获取复选框元素
_getcheckBox(question) {
// 使用模板字符串构建选择器,并返回 Cypress 命令链
return cy.get(`div[class$='checkbox-component-${question}'] > label > input`);
}
// 根据 JSON 数据填充页面上的复选框
populateDataBasedOnJsonValues(answers) {
for (let key in answers) {
// 确保使用 'this' 关键字调用当前实例的内部方法
const questionElement = this._getcheckBox(answers[key]);
questionElement.click();
}
}
}
export default HomePage;homePageTest.cy.js (Cypress 测试文件)
// cypress/e2e/homePageTest.cy.js
import HomePage from '../page-objects/homepage.js'; // 确保路径正确
// 在测试文件顶部或 beforeEach 钩子中实例化 Page Object
const homePage = new HomePage(); // 实例化 HomePage 类
describe('Homepage Checkbox Tests', () => {
beforeEach(() => {
// 可选:在每个测试前访问页面
cy.visit('/');
});
it("should populate checkboxes based on json values", () => {
cy.fixture("jsonValues").then((data) => {
// 调用实例方法,传入从 fixture 加载的数据
homePage.populateDataBasedOnJsonValues(data);
});
// 添加断言以验证操作是否成功
// 例如:
// cy.get('input[type="checkbox"]:checked').should('have.length', Object.keys(data).length);
});
});jsonValues.json (Fixture 文件示例)
// cypress/fixtures/jsonValues.json
{
"question1": "optionA",
"question2": "optionB",
"question3": "optionC"
}遵循这些原则,你将能够有效地在 Cypress 项目中构建和使用 Page Object Model,避免常见的 TypeError,并编写出健壮、易于维护的自动化测试。
以上就是Cypress POM 实践:正确实例化类以避免 TypeError的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号