You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cucumber.js Examples表格遍历异常:仅首页执行,次页无操作求助

问题:Cucumber自动化测试第二页无操作,步骤定义不匹配

问题描述

我在自动化测试中需要自动完成答题,每完成对应questionNum的页面后点击「next」按钮进入下一页。目前仅第一页能正常运行并跳转,第二页无任何操作。原本认为When步骤会自动读取Examples表格的每一行,无需额外编写循环,且表格中部分数据为N/A,我已编写条件过滤这些数据,但仍无法解决问题。

Feature文件代码

When User answer question <questionNum> by <answer1> and <answer2> and <answer3> and <answer4> and <answer5> and click Next button to the next question
         Examples:
         | questionNum | answer1 | answer2 | answer3 | answer4 | answer5 |
         |      1      |    1    |    2    |    3    |    4    |    5    |
         |      2      |    1    |    2    |   N/A   |   N/A   |   N/A   |

条件函数与步骤定义代码

//Condition function
async function answerQuestion(questionNum, ...answers) {
    await World.driver.sleep(1500);
    for (let i = 0; i < answers.length; i++) {
        const ans = answers[i];
        if (ans !== 'N/A') {
            const xpath=`(//input[@name='row-radio-buttons-group'])[${6*i + ans}]`;
            const element = await World.driver.findElement(By.xpath(xpath));
            // Scroll to the element
            await World.driver.executeScript("arguments[0].scrollIntoView();", element);
            // Wait for the element to be clickable
            await World.driver.wait(until.elementLocated(By.xpath(xpath)), 15000); // Wait for element to be located
            await World.driver.wait(async () => {
                try {
                    await element.click();
                    return true;
                } catch (e) {
                    return false;
                }
            }, 10000); // Wait for element to be clickable and click on it

        }
    }
    await World.driver.sleep(5000);
}

//Step_Definition
When('User answer question {int} by {int} and {int} and {int} and {int} and {int} and click Next button to the next question', async (questionNum, answer1, answer2, answer3, answer4, answer5) => {
    await answerQuestion(questionNum, answer1, answer2, answer3, answer4, answer5);
    try{
        const nextButtonXpath = `//div[@id='root']/div/main/div[2]/div/div[2]/div/div/div[3]/div/button${questionNum === 1 ? "[2]" : "[3]"}`;
        await World.driver.findElement(By.xpath(nextButtonXpath),5000).click();

    } catch(error){
        console.error('Error occurred while clicking the Next button', error.message);
        throw error;
    } 
    
});

错误输出

? When User answer question 2 by 1 and 2 and N/A and N/A and N/A and click Next button to the next question
       Undefined. Implement with the following snippet:
       
         When('User answer question {int} by {int} and {int} and N\/A and N\/A and N\/A and click Next button to the next question', function (int, int2, int3) {
         // When('User answer question {int} by {int} and {float} and N\/A and N\/A and N\/A and click Next button to the next question', function (int, int2, float) {
         // When('User answer question {int} by {float} and {int} and N\/A and N\/A and N\/A and click Next button to the next question', function (int, float, int2) {
         // When('User answer question {int} by {float} and {float} and N\/A and N\/A and N\/A and click Next button to the next question', function (int, float, float2) {
         // When('User answer question {float} by {int} and {int} and N\/A and N\/A and N\/A and click Next button to the next question', function (float, int, int2) {
         // When('User answer question {float} by {int} and {float} and N\/A and N\/A and N\/A and click Next button to the next question', function (float, int, float2) {
         // When('User answer question {float} by {float} and {int} and N\/A and N\/A and N\/A and click Next button to the next question', function (float, float2, int) {
         // When('User answer question {float} by {float} and {float} and N\/A and N\/A and N\/A and click Next button to the next question', function (float, float2, float3) {
           // Write code here that turns the phrase above into concrete actions
           return 'pending';
         });

解决方法

1. 修改步骤定义的参数类型

核心问题是步骤定义中用{int}匹配所有answer参数,但第二行Examples里的N/A不是整数,导致Cucumber无法找到对应步骤定义。将answer的参数类型改为{string},兼容数字和N/A:

When('User answer question {int} by {string} and {string} and {string} and {string} and {string} and click Next button to the next question', async (questionNum, answer1, answer2, answer3, answer4, answer5) => {
    await answerQuestion(questionNum, answer1, answer2, answer3, answer4, answer5);
    // 后续代码保持不变
});

2. 统一Feature文件占位符(可选)

将Feature中的<answerX>改为与步骤定义匹配的占位符格式:

When User answer question {int} by {string} and {string} and {string} and {string} and {string} and click Next button to the next question
         Examples:
         | questionNum | answer1 | answer2 | answer3 | answer4 | answer5 |
         |      1      |    1    |    2    |    3    |    4    |    5    |
         |      2      |    1    |    2    |   N/A   |   N/A   |   N/A   |

3. 优化答案参数处理(可选)

由于传入的answer是字符串类型,需将有效答案转为数字后再用于XPATH拼接:

async function answerQuestion(questionNum, ...answers) {
    await World.driver.sleep(1500);
    for (let i = 0; i < answers.length; i++) {
        const ans = answers[i];
        if (ans !== 'N/A') {
            const ansNum = parseInt(ans, 10); // 转换为整数
            const xpath=`(//input[@name='row-radio-buttons-group'])[${6*i + ansNum}]`;
            // 后续代码保持不变
        }
    }
    await World.driver.sleep(5000);
}

4. 其他优化建议

  • 点击next按钮后增加等待逻辑,等待下一页的问题元素加载完成,避免因元素未就绪导致操作失败。
  • 检查第二页next按钮的XPATH判断逻辑questionNum === 1 ? "[2]" : "[3]",确保与实际页面结构一致。

内容的提问来源于stack exchange,提问作者Shirley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:24:50