首页 > web前端 > js教程 > 正文

Cypress POM 实践:正确实例化类以避免 TypeError

DDD
发布: 2025-10-28 10:43:11
原创
863人浏览过

Cypress POM 实践:正确实例化类以避免 TypeError

本文旨在解决 cypress page object model (pom) 中常见的 `typeerror: [method] is not a function` 错误。此错误通常发生在尝试直接在类定义上调用方法,而非在其实例化对象上调用时。文章将详细解释此错误的原因,并提供正确的类实例化和方法调用方式,确保在 cypress 测试中 page object 能够正常工作。

引言:理解 TypeError: is not a function

在 JavaScript 开发中,TypeError: [object].method is not a function 是一个非常常见的错误。它表明你试图调用的 method 并不是 [object] 的一个可执行函数。在 Cypress 的 Page Object Model (POM) 实践中,这个错误通常意味着你正在尝试在一个类的定义上调用其方法,而不是在一个已经创建的该类的实例(对象)上调用。

当你在 Cypress 测试文件中导入一个 Page Object 类并尝试直接调用其方法时,例如 homePage.populateDataBasedOnJsonValues(data),如果 homePage 仅仅是导入的类定义本身,而非该类的一个实例,就会触发此 TypeError。

JavaScript 类与实例:核心概念

理解 JavaScript 中的类(Class)和实例(Instance)是解决此类问题的关键。

  • 类 (Class):类是创建对象的蓝图或模板。它定义了对象将拥有的属性(数据)和方法(行为)。例如,HomePage 类定义了一个网页的结构和与之交互的方式。
  • 实例 (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。

解决方案:正确实例化 Page Object

要解决这个问题,你需要在调用 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) 可以被正确调用。

ViiTor实时翻译
ViiTor实时翻译

AI实时多语言翻译专家!强大的语音识别、AR翻译功能。

ViiTor实时翻译 116
查看详情 ViiTor实时翻译

Page Object 内部方法调用规范

除了外部测试文件中的实例化问题,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"
}
登录后复制

总结与最佳实践

  1. 实例化是关键:在 JavaScript 中,当你定义一个类并希望使用其非静态方法时,必须首先使用 new 关键字创建该类的一个实例。TypeError: is not a function 最常见的原因就是忘记了这一步。
  2. this 关键字的正确使用:在类的实例方法内部,如果需要调用同一个实例的其他方法或访问实例属性,请务必使用 this. 前缀。
  3. Cypress POM 的优势:Page Object Model 旨在提高测试代码的可读性、可维护性和复用性。通过将页面元素和交互逻辑封装在独立的类中,可以使测试脚本更简洁,并且当 UI 发生变化时,只需修改 Page Object 文件,而无需修改所有相关的测试用例。
  4. 清晰的导入路径:确保 import 语句中的路径是正确的,指向你的 Page Object 文件。

遵循这些原则,你将能够有效地在 Cypress 项目中构建和使用 Page Object Model,避免常见的 TypeError,并编写出健壮、易于维护的自动化测试。

以上就是Cypress POM 实践:正确实例化类以避免 TypeError的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号