当前,在添加或更改数据的每个操作之后,我们通过直接查询表来验证是否已在数据库中成功添加/更改了数据。我觉得这是多余的,因为该数据已被应用程序提取,并在应用程序中正确(或不正确)显示。

这是问题的关键所在,但是我将提供一个简化的测试用例来扩展我正在谈论的内容:



转到用户“ John Smith”个人资料,并将他的电话号码从“(999)999-9999”更新为“(666)666-6666”,然后在其中单击保存按钮该应用程序
验证应用程序显示“成功更改了用户配置文件”
转到预览配置文件并验证John Smith的配置文件反映了更改
验证DBusers数据库中的表USER_PROFILE已更新更改



如果我们已经验证了应用程序正确显示了数据,是否需要检查数据库中的表?该应用程序已经从数据库表中提取数据,因此很显然,如果应用程序正确显示数据,则数据库中的数据是正确的。我缺少什么吗?

谢谢您的输入。验证任何数据复制是否成功。我们有使用单独的DBMS的基于Web和控制台的应用程序。我们使用的两个是SQL Server和DB2。将特定数据添加到SQL Server之后,将运行一个作业,将其复制到DB2。它们具有不同的结构,因此两者之间的表/字段都不同。我可以理解验证此复制已成功执行。

#1 楼

您的应用程序使用API​​与数据库进行交互。可以以这样一种方式编写您的API:它向应用程序显示正确的结果,但仍然以错误的方式使用数据库。例如,假设一个数据库中包含一个EMPLOYEE表和一个MANAGER表。桌子是一样的-例如每个表都包含名字,姓氏,公司电子邮件地址和薪水-但是EMPLOYEE表仅适用于非管理人员,而MANAGER表仅适用于管理人员。两节课,每桌一张。程序员首先编写员工代码。经理代码几乎相同,因此程序员会复制员工代码,然后进行编辑。他更改了类的名称,并且更改了方法的名称。然后,在他即将将表格名称从EMPLOYEE更改为MANAGER之前,他分心了:他决定再喝杯咖啡,或者他记得自己没有读过最新的XKCD,或者他注意到了新的,有见地的SQA评论。来自Sam Woods。

当程序员重新开始工作时,他已经忘记了更改表名的想法,因此他编译了代码,然后编写了一些单元测试。员工和经理的测试都做同样的事情。一个测试创建该对象,将其写入,然后将其读回。另一个测试尝试读取数据库中没有的对象。也许有一个更新测试和一个删除测试,或者一个写入多个对象并读回它们的测试。这些测试全部通过,因此程序员宣布胜利。当然,代码中存在一个错误:管理器记录被写入EMPLOYEE表。

您可以使用多种测试来发现此特定问题。一种方法是调用检索每个表的全部内容的方法。但是,如果应用程序不需要该方法,则可能不会出于添加测试目的而添加它。另一种方法是使用比您的数据库API更可信赖的东西来查询数据库,即原始SQL。我的示例是人为设计的,但我认为这很有意义。您可以在使用被测类为测试初始化​​数据库吗?是否可以找到类似的问题(和一些答案)。

#2 楼


不会在应用程序本身中暴露任何数据不一致吗?


也许也许不会。

我已经看到注销后应用程序丢失一些数据的情况。因此,尽管UI看起来不错,但注销后数据库实际上是不正确的。

此外,您确定数据库中的每个元素都将显示在UI中的某个位置吗?根据我的经验,那将是非常罕见的。诸如“上次更新日期”之类的字段通常记录在数据库中,但不会向用户公开。在用户界面中。


因此很明显,如果应用程序正确显示了数据,那么
数据库中的数据是正确的。


如果捕获和存储数据的UI元素以及显示数据的UI元素都犯了相同的错误-那么数据库确实有可能是不正确的,但是UI会隐藏这一事实。我已经看到这种情况偶尔发生。我记得一个数据字段存储不正确,但是对其进行转换的UI与从用户那里接收并存储数据的UI所做的假设相同。结果是后来添加的报告(没有与UI犯同样的错误)最终无法正常工作。

我很少发现仅UI验证就足够了。另一方面,我确实认为在执行每个操作之后查询数据库可能是过大的。也许您可以将一些操作组合在一起,然后只查询数据库?

#3 楼

我不想重复其他人提供的出色答案,但我想分享我在测试中使用数据库的另一堂课。

经常在一个测试中结合数据库断言和UI断言的反馈,对于测试用例设计,测试执行性能和缺陷根源隔离非常有用:


如果在数据库中发现错误,则检查UI中是否也发生错误可以帮助您定义严重性。也许如果未在主屏幕上显示损坏的数据,那么问题就不那么严重了吗?
探索数据库数据并发现有臭味或可疑的东西可以帮助发明新的端到端测试方案,这将证实您的猜测
/>复杂的算法可能会将中间结果记录在数据库中,而在UI中,您只能看到最终输出。在测试报告中包含中间结果将有助于您调查根本原因。在长期的多步骤用户方案中,从将数据保存到数据库并在UI上显示回来之间可能要花费一些时间,例如在电子购物场景中。如果可以缩短测试执行时间并使其快速失败,为什么还要等到最后一步呢?


#4 楼

除了user246的出色示例外,您还需要在场景中验证数据库存储的其他情况包括:


您具有批量更新/插入功能,在这种情况下,通过前端验证结果,例如从CSV文件导入新的用户记录。虽然您可以通过前端检查并确认导入的每条记录在GUI中都存在且正确,但批处理数据库读取并与预期结果进行比较要快很多。记录,例如将所有地址存储在单独的表中。在这里,您需要检查删除是否也删除了相关记录,这在前端检查中不会显示。
正如乔所说,并不是数据库中的所有字段都暴露给前端。计算的字段,时间戳等都需要检查。
在应用程序使用数据库存储过渡记录的地方,您可能需要在每个步骤之后检查相关表,以确保存储和清除了正确的数据。我最了解的示例是购买数量有限的商品。如果可用数量为30,并且某人在购物车中增加了5,则该数量5必须保留,可用数量减少5,直到购买(在这种情况下,保留的5被清除,销售数量增加5)或取消(在这种情况下,保留的5被清除,可用数量增加5)。如果没有这些检查,在以后购买之前,清除可用数量的问题可能不会变得很明显-尤其是如果过渡记录包含相关记录。


#5 楼

我认为这是从数据库中回读的好主意。原因是有时候(或经常)事情并不像看上去那样简单。

在上面的示例中:如果电话号码全为零,会发生什么?如果用户实际拥有这样的电话号码+ 46-728-123456(瑞典的手机号码,不是我的手机号码,希望现在没有人打电话)会发生什么。或者,如果您实际上有带字符的数字,请说(abc)def-ghijkl

,或者如果您输入正确的名称,例如:HåkonHésteier(假名称)。底层和数据库如何处理国际字符-有很多设置可能会影响这一点。不能确定这些字符将完全按照输入的方式存储。

以我的经验,您需要定义所有数据库字段的限制。这并不是完全由测试阶段来完成,但是测试可以反馈设计(要求或您所说的)不够详细。作为测试人员,测试人员应尝试找到接近和超出“限制”范围的情况,并将其纳入测试工具。

一个典型的例子是SQL注入,如果您向部分名称字段输入部分SQL语句,则数据库不仅会损坏数据库,不仅会存储修改后的数据,还会将数据实际上解释为SQL语句。

一个小例子:我最近下载了一个应用程序,据说应该为我提供如何获得更好贷款的建议。您应该在此处输入当前利率。该应用程序确实允许我输入利率为2.12%的一笔贷款,但不能接受利率为3.01的另一笔贷款。他们忘了用x.0x作为贷款利率来测试此案。