循环检查重复产品标题:现有代码逻辑异常求助
Fixing Your Selenium Duplicate Title Check Logic
Let's break down exactly why your current code isn't working as you expected, then walk through two solid fixes:
The Core Problem with Your Current Code
Your main issue is re-fetching the productTitles element collection inside the outer loop. Here's what happens:
- When you first get
productTitles, you have a collection of element references. You pick one asx. - Then you re-run
FindElements, which creates a brand new set of element references (even if they're the same UI elements, they're different objects in code). - When you call
productTitles.IndexOf(x), the new collection doesn't contain the oldxreference, so it returns-1. That makesSkip(-1 + 1) = Skip(0), which completely breaks your intended "compare each element to all elements after it" logic. - On top of that, re-fetching elements repeatedly is inefficient and risks stale element errors if the page updates mid-check.
Fix 1: Pre-Fetch All Titles to a String List
The easiest fix is to pull all the title texts into a simple list first, then work with that list for your duplicate check. This avoids element reference confusion and redundant Selenium calls:
// Grab all product title texts in one single fetch var productTitles = SeleniumContext.Driver.FindElements(By.XPath(ComparisonTableElements.ProductTitle)) .Select(element => element.Text) .ToList(); // Check each title against all titles that come after it for (int i = 0; i < productTitles.Count; i++) { var currentTitle = productTitles[i]; for (int j = i + 1; j < productTitles.Count; j++) { if (currentTitle == productTitles[j]) { Assert.Fail("Found duplicate product in the table"); } } }
Fix 2: Use a HashSet for Faster Duplicate Detection
If you don't need to know exactly which pairs are duplicates and just want to confirm there are none, a HashSet is a more efficient option (it runs in O(n) time instead of O(n²) like nested loops):
var seenTitles = new HashSet<string>(); var productElements = SeleniumContext.Driver.FindElements(By.XPath(ComparisonTableElements.ProductTitle)); foreach (var element in productElements) { var title = element.Text; // HashSet.Add() returns false if the value is already in the set if (!seenTitles.Add(title)) { Assert.Fail("Found duplicate product in the table"); } }
Why These Fixes Work
- Both approaches only fetch the UI elements once, so you're working with a consistent set of values throughout the check.
- The string list approach keeps your original pairwise comparison logic intact but removes the element reference issues.
- The HashSet approach is cleaner and faster, as it automatically tracks which titles you've already seen.
内容的提问来源于stack exchange,提问作者Brian Mitchell
相关产品推荐
相关产品推荐

