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

使用Java Selenium WebDriver移除购物车商品后如何正确断言已删除

问题根因
  • 断言逻辑完全错误:你的@Then步骤是要验证购物车为空,但你用了contains(expected)匹配器,这个匹配器的作用是校验列表包含指定元素,完全和需求相反;同时你声明的expected变量没有做任何赋值操作,是空值,必然触发断言失败。
  • 匹配器使用错误:contains是Hamcrest的严格匹配器,要求列表的元素数量、顺序、值完全和入参一致,如果你只是要校验列表是否包含单个元素,应该用hasItem匹配器。
  • 缺少异步等待:前端移除购物车商品一般是异步请求渲染,点击移除按钮后立即获取商品列表,大概率拿到的是操作前的旧数据,导致断言结果不符合预期。
  • 如果你需要校验被移除的商品不在列表中,你现有的代码没有在移除前记录要删除的商品名称,没有预期值可以用来对比。
修复方案

场景1:验证移除后购物车完全为空(匹配你现有@Then注解的逻辑)

第一步:在TrolleyPage中加显式等待逻辑,避免拿旧数据

import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.time.Duration;

public class TrolleyPage {
    // 初始化显式等待,超时时间可根据你的页面响应速度调整
    private WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

    public void removeFromTrolley() {
        List<WebElement> removeProductBtnList = driver.findElements(By.cssSelector("button[data-test='basket-removeproduct']"));
        int size = removeProductBtnList.size();
        System.out.println("Number of size of Added product in trolley " + size);
        WebElement removedWebElement = removeProductBtnList.get(0);
        removedWebElement.click();
    }

    public List<String> getAllProductsInTrolley() {
        List<String> actualList = new ArrayList<>();
        // 先等商品名称元素加载稳定
        wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("a[data-e2e='product-name']")));
        List<WebElement> productWebElements = driver.findElements(By.cssSelector("a[data-e2e='product-name']"));
        for (WebElement product : productWebElements) {
            String productName = product.getText();
            if (!productName.isEmpty()) {
                actualList.add(productName);
                System.out.println("Product :" + productName);
            }
        }
        return actualList;
    }
}

第二步:修改断言逻辑

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.MatcherAssert.assertThat;

@Then("^I should see the the trolley is empty$")
public void i_should_see_the_the_trolley_is_empty()  {
    List<String> actualList = trolleyPage.getAllProductsInTrolley();
    // 校验列表为空
    assertThat(actualList, empty());
    // 也可以用原生断言:Assert.assertTrue(actualList.isEmpty());
}

场景2:验证被移除的指定商品不在购物车中(适用于移除多个商品中的一个的场景)

第一步:修改TrolleyPage的移除方法,返回被移除的商品名称

public class TrolleyPage {
    private WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

    // 移除第一个商品,返回被移除的商品名
    public String removeFirstProductFromTrolley() {
        // 先获取第一个商品的名称
        List<WebElement> productWebElements = driver.findElements(By.cssSelector("a[data-e2e='product-name']"));
        String removedProductName = productWebElements.get(0).getText().trim();
        
        // 点击移除按钮
        List<WebElement> removeProductBtnList = driver.findElements(By.cssSelector("button[data-test='basket-removeproduct']"));
        removeProductBtnList.get(0).click();
        
        return removedProductName;
    }

    // getAllProductsInTrolley方法同上,保留显式等待逻辑
}

第二步:修改测试步骤和断言

import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;

public class RemoveTheProductDefs {
    private TrolleyPage trolleyPage = new TrolleyPage();
    private String removedProductName; // 存储被移除的商品名

    @When("^I remove a product$")
    public void i_remove_a_product()  {
        removedProductName = trolleyPage.removeFirstProductFromTrolley();
    }

    @Then("^the removed product should not exist in trolley$")
    public void the_removed_product_should_not_exist_in_trolley()  {
        List<String> actualList = trolleyPage.getAllProductsInTrolley();
        // 校验列表不包含被移除的商品名
        assertThat(actualList, not(hasItem(removedProductName)));
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:15:06