繁体   English   中英

将数据库结果与html表进行比较-Selenium Webdriver-Java

[英]Compare database results to html table - Selenium Webdriver - Java

我需要一些帮助,以便能够获取数据库结果并验证它们是否正确显示在屏幕上。 该表将与数据库中的数据量一样大。

这是表格的一些示例HTML:

<table class="table table-hover">
<thead>
<tbody>
<tr class="ng-scope" ng-repeat="item in PaymentHistoryCtrl.paymentHistoryArray | orderBy: 'date' track by $index ">
<td class="ng-binding" ng-bind="item.date | date:'longDate'">February 12, 2016</td>
<td class="ng-binding" ng-bind="item.policyNumber">BTB1716401</td>
<td class="ng-binding" ng-bind="item.total | currency">$3,000.00</td>
<td class="ng-binding" ng-bind="item.referenceNumber">3***8431</td>
</tr>
<tr class="ng-scope" ng-repeat="item in PaymentHistoryCtrl.paymentHistoryArray | orderBy: 'date' track by $index ">
<td class="ng-binding" ng-bind="item.date | date:'longDate'">February 12, 2016</td>
<td class="ng-binding" ng-bind="item.policyNumber">BTB1716401</td>
<td class="ng-binding" ng-bind="item.total | currency">$55.00</td>
<td class="ng-binding" ng-bind="item.referenceNumber">3***8431</td>
</tr>

这是表格的外观示例:

在此处输入图片说明

我有一个SQL查询来收集屏幕上显示的信息。 但是,如何将记录与表中的行/列进行匹配? 这是我用于连接数据库的Java:

//Load the required JDBC Driver class
Connection conn = null;
Statement stmt = null;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");  

//Create a connection to the database
String connection = "jdbc:sqlserver://" + dbName + ":" + dbPort;
conn = DriverManager.getConnection(connection,dbUsername,dbPassword);

//Execute SQL query
stmt = conn.createStatement();
String sql = "select * from Table";
ResultSet rs = stmt.executeQuery(sql);

很难理解是什么生成了您提供的html,但是如果您完全控制每个数据行的生成,则可以为每个元素分配一个ID。 当您创建Jasper报告(事实证明是html表)时,这特别有用。

假设您的表格行如下所示:

<tr id="result_1" class="ng-scope" ng-repeat="item in PaymentHistoryCtrl.paymentHistoryArray | orderBy: 'date' track by $index ">
    <td id="result_1_date" class="ng-binding" ng-bind="item.date | date:'longDate'">February 12, 2016</td>
    <td id="result_1_policyNum" class="ng-binding" ng-bind="item.policyNumber">BTB1716401</td>
    <td id="result_1_total" class="ng-binding" ng-bind="item.total | currency">$3,000.00</td>
    <td id="result_1_refNum" class="ng-binding" ng-bind="item.referenceNumber">3***8431</td>
</tr>

然后,您可以做一个简单的调用selenium webDriver来获取元素的文本。

WebElement element = driver.findElement(By.id("result_1_total"))

如果不是这种情况,或者您不关心各个<td>元素,除了它们仅存在于页面上的事实之外,您可以简单地遍历它们。

//find the table on the page
WebElement tblEle = driver.findElement(By.id("myTable"))
List<WebElement> tblElements = tblEle.findElements(By.Xpath("/tbody/tr/"));
for (WebElement tblElementRow : tblElements) {
    List<WebElement> allTds = tblElementRow.findElement(By.xpath("td"))
    // do somthing with the list of allTds
}

另外,如果我是您,则可以执行stmt.executeQuery,而不是执行stmt.executeUpdate(),它返回一个结果集。 这样,您可以遍历结果,并将其添加到数组中。 填充数组后,可以向其添加简单的机制,以将其与生成的表相关联。

例如:

List<MyObject> objs = new ArrayList<>();
ResultSet rs = stmt.executeQuery("Select * from Table");
while (rs.next()) {
    // construct obj from rs
    objs.add(myCreatedObj);
}

MyObject findFromObjs(final String id) {
    for (MyObject cool : objs) {
        if (cool.getId().equals(id)) return cool
    }
}

然后,当您调用此函数时:

WebElement element = driver.findElement(By.id(findFromObjs("myFirstRs")))

同样,这一切都取决于您拥有多少功能,粒度和控制。 那将决定您如何解决此问题。 在处理不会产生荒谬的xpath的技术时,有时,更容易挂接到ID上。 相反,如果您不能分配ID,则也可以使用xpath,但是使用起来可能会有点困难。

最后,检查xpath(如果您打算使用此方法)的一种简单方法是在Firefox的控制台中运行它。 这样的事情将是一个好的开始:

$x("//tbody/tr/td[contains(text(), 'news')]")

这个答案对如何从数据库返回数据做了很多假设。 我将假定从您的SQL语句返回的行将与Web表中显示的顺序相同。 我还假设sql结果中的列与Web表上显示的列匹配,如果不匹配,则需要裁剪sql查询以仅选择Web表中可见的列。 您的过程如下所示:

  1. 遍历sql结果中的每一行,调用iterator i
  2. 遍历行中的每个单元格,将其称为迭代器j
  3. 通过XPath从表中获取文本: By.XPath("//table/tbody/tr["+(i+1)+"]/td["+(j+1)+"]").Text
  4. 比较从td返回的文本和存储在sql单元格中的值。
  5. 如果比较失败,则返回false
  6. 如果for循环结束,则返回true。

如果从您的SQL语句返回的行的顺序不同,则您有2个选项,请将ORDER BY添加到您的sql语句中,或将类似的功能应用于Web表,以使顺序匹配。 或者,将每个行与i for循环中的当前行进行比较。 我不建议使用第二个,因为如果您有很多数据,它会减慢很多速度。

希望能有所帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM