测试设计模式

文字翻译有待矫正,仅供学习参考
大纲
  1. 测试设计介绍
  2. 测试类型
    1. 静态内容测试
    2. 链接测试
    3. 功能测试
    4. 动态元素测试
    5. Ajax测试
  3. 结果验证
    1. 断言与验证
  4. 定位策略
    1. 选择定位方式
    2. 查找动态元素
    3. 查找Ajax元素
  5. 封装会话
    1. 元素存在的“安全操作”
  6. 映射用户界面
  7. 页面对象设计模式
  8. 数据驱动测试技术
  9. 数据库验证技术
正文:
  1. 测试设计注意事项内容介绍
  1. 描述最常见的自动化测试类型。
  2. 描述了测试自动化中常用的“设计模式”,以改进您的自动化套件的维护和扩展性。
  1. 测试类型
你应该测试哪些部分的应用程序?这取决于项目的各个方面:用户期望,项目允许的时间,项目经理设定的优先级等。一旦项目的维度被定义了,你,测试人员肯定会对测试的内容做出很多决定。
我们在此创建了一些术语,用于对您可能在Web应用程序上执行的测试类型进行分类。尽管我们在这里介绍的概念是典型的Web应用程序测试,但是这些术语绝非标准。
    1. 静态内容测试
最简单的测试类型是内容测试,它是进行静态的、不变的、简单UI元素的测试。例如
  • 每个页面是否都有预期的页面标题?这可以用来验证链接是否跳转到预期的页面。
  • 应用程序的主页是否在预期页面顶部包含图像?
  • 网站的每个页面是否包含一个页脚区域,该区域中包含公司联系信息,隐私政策和商标信息的链接?
  • 每个页面是否都使用<h1>标签标题文本开头?而且,每个页面在该标题中的文本信息是否正确?
您可能需要也可能不需要内容测试。如果您的页面内容不可能受到影响,那么手动测试页面内容可能会更有效。但如果您的应用程序涉及将文件移动到不同的位置,则内容测试可能证明是有价值的。如何理解这句话呢?
    1. 链接跳转测试
网站的常见错误是链接跳转后链接断开或缺少页面。测试用例包括点击每个链接并验证跳转到期望页面。如果静态链接很少改变,那么手动测试可能就足够了。但是,如果您的网页设计师经常更改链接,或者偶尔重新定位文件,则链接测试最好是自动的。
    1. 功能测试
这些将是您的应用程序中特定功能的测试,需要某种类型的用户输入,并返回某种类型的结果。通常一个函数测试用例将涉及多个页面,其中包含一个包含一组输入字段集合的基于表单的输入页面,提交和取消操作以及一个或多个响应页面。用户输入可以通过文本输入字段,复选框,下拉列表或任何其他浏览器支持的输入。
功能测试用例通常是您执行的最复杂的自动化测试用例,但通常是最重要的。典型的测试用例可以用于登录,登录到站点,用户账户操作,账户设置变化,复杂的数据检索操作等等。功能测试通常反映用于指定功能、设计、用户场景或业务流程。
    1. 动态元素测试
通常,网页元素具有唯一标识符,用于在页面中唯一地定位该元素。通常这些都是使用html标签的'id'属性或其'name'属性实现的。这些名称可以是静态的,即不变的字符串常量。它们也可以是动态生成的值,可以改变页面的每个实例。例如,某些Web服务器可能会将显示的文档doc3861命名为页面的一个实例,而对于不同的页面实例则会命名为“doc6148”,具体取决于用户正在查看的“文档”。写验证这类文档存在的测试脚本时可能没有用于定位该文档的唯一标识符比如id。通常,基于用户操作,在同一页面上某种类型的元素其标识符内容不同。这当然取决于Web应用程序的功能。
这是一个例子。
<input type="checkbox" value="true" id="addForm:_ID74:_ID75:0:_ID79:0: checkBox"/>
这显示了一个复选框的HTML标记。它的ID(addForm:_ID74:_ID75:0:_ID79:0:checkBox)(ID就是标识符)是一个动态生成的值。下一次打开同一页面时,它可能会是一个不同的值。
    1. Ajax测试
Ajax是一种支持动态更改的用户界面元素的技术,可以动态更改,而无需浏览器重新加载页面,如动画,RSS源和实时数据更新等。Ajax有无数种方法用来更新网页上的元素。但是,利用这一简单的方法是,在Ajax驱动的应用程序中,可以从应用程序服务器检索数据,然后在再页面上显示数据,而无需重新加载整个页面。这样只有一部分页面,或整个元素本身被重新加载。
  1. 结果验证
    1. 断言(ssert)与验证(Verify)
什么时候应该使用断言命令,什么时候应该使用验证命令?这取决于你。不同之处在于检查失败后想要做什么。你想让你的测试脚本终止,还是继续执行并记录检查失败结果?
这是一个权衡。如果您使用断言Assert,测试将在该点停止并且不运行任何后续检查。有时候,也许经常,这就是你想要的。如果测试执行失败,您将立即得知测试未通过。像TestNG和JUnit这样的测试引擎为常用的开发环境提供了插件(第5章Selenium 1 (Selenium RC)),这些插件方便地将这些测试脚本标记为失败。优点:您可以立即看到检查是否通过。缺点:当检查失败时,还有其他从未执行过的检查将不会执行,因此您不会有其它状态的信息。
相反,验证verify命令不会终止测试。如果你的测试只使用验证命令(假设没有例外),那么测试将运行直到完成,无论这些检查是否发现缺陷。缺点:你必须做更多的操作来检查你的测试结果。也就是说,你不会从TestNG或JUnit获得反馈。您需要查看控制台打印输出或日志输出的结果。每次运行测试时,您都需要花时间浏览一下这个输出。如果您正在运行数百个测试,每个测试都有对应的日志,这将非常耗时,所以断言的即时反馈将更加合适测试。由于能立即反馈,断言比验证命令更常用。
  1. 定位策略
    1. 选择定位方式
在页面上选择对象有多种方法,8种。但是,这些定位方式的作用是什么?回想一下,我们假设要找到一个对象
    • 元素的ID
    • 元素的名称属性
    • 一个XPath语句
    • 通过link's text
    • 文档对象模型(DOM)
使用元素ID或名称定位器在测试执行性能方面效率最高,并且还会使测试代码更具可读性,前提是页面源中的ID或名称是完整的。由于浏览器必须运行其XPath处理器,因此执行XPath语句需要更多长时间。已知XPath在Internet Explorer版本7中速度特别慢。通过链接的文本来定位通常很方便且性能良好。尽管这种技术是只适用于有链接文本的定位。另外,如果链接文本会频繁变化,那么通过<a>元素的ID进行定位将是更好的选择。注意链接文本中的关键字查询功能。
有时候,您必须使用XPath定位器。如果页面代码中没有ID或name属性,您可能别无选择,只能使用XPath定位。(DOM定位器不再被广泛使用,因为XPath可以做它做的所有事情甚至更多.DOM定位器可以简单地支持传统测试。被废弃)
使用XPath定位与通过ID或名称属性定位比较是没有优势的。使用XPath(和DOM),您可以在页面上找到相对于另一个对象的对象。例如,如果在<div>部分的第二段内必须出现链接,则可以使用XPath来指定该链接。使用ID和name定位时,只能指定它们出现在页面的某处。如果您必须测试显示公司徽标的图像出现在页眉部分的页面顶部,则XPath可能是更好的定位器。
    1. 定位动态元素
正如前面在“测试类型”部分中所述,动态元素是页面元素,其标识符因页面的每个实例而异。例如,
<a class="button" id="adminHomeForm" onclick="return oamSubmitForm('adminHomeForm', 'adminHomeForm:_ID38');" href="#">View Archived Allocation Events</a>
这个HTML定位标记定义了一个ID属性为“adminHomeForm”的按钮。与大多数HTML标签相比,它是一个相当复杂的锚标签,但它仍然是一个静态标签。每次在浏览器中加载该页面时,HTML都将保持不变。它的ID在本页面的所有实例中保持不变。也就是说,当该页显示时,此UI元素将始终具有同样标识符。所以,为了让你的测试脚本点击这个按钮,你只需要使用下面的Selenium命令。
click adminHomeForm
或者,在Selenium 1.0中
selenium.click("adminHomeForm");
但是,您的应用程序可能会在网页的不同实例中标识符不同的情况下动态生成HTML。例如,动态页面元素的HTML可能如下所示。
<input type="checkbox" value="true" id="addForm:_ID74:_ID75:0:_ID79:0:checkBox" name="addForm:_ID74:_ID75:0:_ID79:0:checkBox"/>
这定义了一个复选框。它的ID和name属性(都是addForm:_ID74:_ID75:0:_ID79:0:checkBox)是动态生成的值。在这种情况下,使用标准定位器将如下所示。
click addForm:_ID74:_ID75:0:_ID79:0:checkBox
或者,在Selenium-RC中
selenium.click("addForm:_ID74:_ID75:0:_ID79:0:checkBox");
对于动态生成的标识符,这种方法是行不通的。下次加载该页面时,标识符将与Selenium命令中的值不同,因此不会被找到。点击操作将失败,并显示“找不到元素”错误。
为了解决这个问题,一个简单的解决方案就是使用XPath定位器替代ID定位器。所以,对于复选框,您可以简单地使用
click //input
或者,如果它不是页面上的第一个输入元素(很可能不是这样),请尝试更详细的XPath语句。
click //input[3]
要么
click //div/p[2]/input[3]
但是,如果您确实需要使用ID来定位元素,则需要使用不同的解决方案。在使用Selenium命令之前,您可以从网站捕获此ID。例如:
String[] checkboxids = selenium.getAllFields(); // Collect all input IDs on page. for(String checkboxid:checkboxids) { // 遍历搜集到的id if(checkboxid.contains("addForm")) {// 判断是否包含addForm selenium.click(checkboxid); } }
如果只有一个复选框,其ID包含文本“addForm”,则此方法将起作用。
总结一句话,定位动态元素要用xpath语句。
    1. 定位Ajax元素
定位、验证AJAX元素的最好的方式是使用Selenium 2.0 webdriver的API,它专门解决Selenium 1.0测试AJAX元素的一些限制。
  在Selenim 2.0中,可以使用waitfor()方法来等待一个页面元素变得可用。该参数是一个WebDriver用来实现定位的By对象。这是WebDriver的章节(Selenium WebDriver)中详细解释。
  在Selenium 1.0(Selenium-RC的)中,要做到这一点需要编写更多的编码,但它并不难。首先检查元素,如果它存在,等待预定义的时间段,然后再重新检查。这在循环内执行,如果超过一个预定的超时,元素不存在则终止循环。
  让我们尝试在页面上点击按钮(不刷新页面)时跳转链接(link= ajaxLink)如何处理,使用循环处理:
// Loop initialization.
for (int second = 0;; second++) {
 
     // If loop is reached 60 seconds then break the loop.
     if (second &gt;= 60) break;
 
     // Search for element "link=ajaxLink" and if available then break loop.
     try { if (selenium.isElementPresent("link=ajaxLink")) break; } catch (Exception e) {}
 
     // Pause for 1 second.
     Thread.sleep(1000);
 
}
  这当然不是唯一的解决办法。Ajax是一个共同的话题,在用户论坛上,查找一下之前的讨论,看看别人是如何做的。
  1. 封装selenium接口
与任何编程一样,您需要使用工具函数来处理在测试代码中重复的代码。防止这种情况的一种方法是将经常使用的selenium方法调用与自己设计的函数或类方法进行封装。例如,测试时会频繁地点击页面上的元素并等待页面加载。
selenium.click(elementLocator); selenium.waitForPageToLoad(waitPeriod);
为不重复上述代码,你可以编写方法封装这两个功能。
/** * Clicks and Waits for page to load. * * param elementLocator * param waitPeriod */ public void clickAndWait(String elementLocator, String waitPeriod) { selenium.click(elementLocator); selenium.waitForPageToLoad(waitPeriod); }
    1. 判断元素是否存在的“安全操作”
封装Selenium方法的另一个常见做法是在执行某些操作之前检查页面上是否存在元素。这有时被称为“安全操作”。例如,下面的方法可用于实现一个依赖期望元素存在的安全操作
/** * Selenum-RC -- Clicks on an element only if it is available on a page. * * param elementLocator */ public void safeClick(String elementLocator) { if(selenium.isElementPresent(elementLocator)) { selenium.click(elementLocator); } else { // Using the TestNG API for logging Reporter.log("Element: " + elementLocator + ", is not available on a page - " +selenium.getLocation()); } }
这个例子使用Selenium 1 API,但Selenium 2也支持这个。
/** * Selenium-WebDriver -- Clicks on an element only if it is available on a page. * * param elementLocator */ public void safeClick(String elementLocator) { WebElement webElement = getDriver().findElement(By.XXXX(elementLocator)); if(webElement != null) { selenium.click(webElement); } else { // Using the TestNG API for logging Reporter.log("Element: " + elementLocator + ", is not available on a page - " + getDriver().getUrl()); } }
在这第二个例子中,'XXXX'只是定位方法之一的占位符,如它可以代表ID,name等。
是否使用安全操作取决于测试开发人员的决定。因此,即使在页面上缺少元素的情况下,要继续执行测试,可以使用安全操作,并将消息发布到关于缺少元素的日志中。这基本上是通过报告机制实现“验证”,而不是异常声明。但是,如果一个元素必须在页面上出现才能执行进一步的操作(例如,门户主页上的登录按钮),则应该直接报错终止而不是继续执行。
  1. 用户界面映射
用户界面(UI)映射是一种机制,它将测试套件的所有定位器存储在一个地方,以便在被测试应用程序(AUT)中UI元素的标识符或路径发生更改时能轻松进行修改。测试脚本使用UI 映射方式来定位被测试元素。基本上,UI映射是封装了被测应用的UI元素的对象库。
UI映射有什么用?它的主要目的是使测试脚本管理更容易。当需要编辑定位器时,有一个集中的文件可以轻松找到该对象,而不必搜索测试脚本代码。此外,它能在该文件统一更改标识符,而不必在测试脚本中的多个地方或在多个测试脚本中进行更改。
总而言之,UI图有两个显着的优点
  • 将UI对象放在集中的位置,而不是将它们分散在整个脚本中。提高测试脚本可维护性。
  • 用自定义别名的方式替代HTML标识符和专业名称,提高测试脚本可读性。
思考下面让人理解困难的例子( Java中)。
public void testNew() throws Exception { selenium.open("http://www.test.com"); selenium.type("loginForm:tbUsername", "xxxxxxxx"); selenium.click("loginForm:btnLogin"); selenium.click("adminHomeForm:_activitynew"); selenium.waitForPageToLoad("30000"); selenium.click("addEditEventForm:_IDcancel"); selenium.waitForPageToLoad("30000"); selenium.click("adminHomeForm:_activityold"); selenium.waitForPageToLoad("30000"); }
对于那些不熟悉AUT页面源代码的人来说,这个脚本很难理解。即使应用程序的常规用户可能也难以理解该脚本的功能。更好的脚本可以是:
public void testNew() throws Exception { selenium.open("http://www.test.com"); selenium.type(admin.username, "xxxxxxxx"); selenium.click(admin.loginbutton); selenium.click(admin.events.createnewevent); selenium.waitForPageToLoad("30000"); selenium.click(admin.events.cancel); selenium.waitForPageToLoad("30000"); selenium.click(admin.events.viewoldevents); selenium.waitForPageToLoad("30000"); }
现在,使用一些注释和空白以及UI Map标识符可以创建一个非常易读的脚本。
public void testNew() throws Exception { // Open app url. selenium.open("http://www.test.com"); // Provide admin username. selenium.type(admin.username, "xxxxxxxx"); // Click on Login button. selenium.click(admin.loginbutton); // Click on Create New Event button. selenium.click(admin.events.createnewevent); selenium.waitForPageToLoad("30000"); // Click on Cancel button. selenium.click(admin.events.cancel); selenium.waitForPageToLoad("30000"); // Click on View Old Events button. selenium.click(admin.events.viewoldevents); selenium.waitForPageToLoad("30000"); }
UI Map有多种实现方式。人们可以创建一个类或结构,它只存放每个定位符(如ID、name)的公共字符串变量。或者,可以使用存储键值对的文本文件。在Java中,包含键/值对的属性文件可能是最好的方法。
考虑一个属性文件prop.properties,它为前面例子中的UI元素赋予“别名”是标识符便于读者理解。
admin.username = loginForm:tbUsername admin.loginbutton = loginForm:btnLogin admin.events.createnewevent = adminHomeForm:_activitynew admin.events.cancel = addEditEventForm:_IDcancel admin.events.viewoldevents = adminHomeForm:_activityold
定位器仍将引用HTML对象,但我们在测试脚本和UI元素之间引入了抽象层。从文件参数读取值并在测试类中使用以实现UI映射。有关Java属性文件的更多信息,请参阅以下链接
  1. 页面对象设计模式
页面对象是一种设计模式,它已经在自动化测试中流行,以加强测试维护并减少代码重复。页面对象是一个面向对象的类,用作AUT的页面接口。只要需要与该页面的UI进行交互,被测应用脚本中就会调用此页面对象类的方法。好处是,如果页面的UI发生变化,被测应用脚本本身不需要修改,只需改变页面对象内的代码。并且,支持该新UI的所有更改都位于同一位置。
页面对象设计模式提供以下优点:
1.让被测应用脚本代码和特定页面的代码之间完全分离,特定页面是指如定位器(您调用UI映射那样来使用他们)以及某些模块布局。
2.通过页面对象来作为服务和操作模块的一个库,远比将这些服务和操作模块零散的分散到被测应用脚本的其它地方要好。
在这两种情况下,即使UI所需的任何修改都可以在同一个文件完成。这种技术的有用信息可以在许多博客中找到,因为这种“测试设计模式”正在被广泛使用。 我们鼓励希望了解更多的读者在这个主题上搜索互联网上的博客。 许多人都写过这种设计模式,可以提供超出本用户指南范围的有用提示。不过,为了让你开始,我们将用一个简单的例子来说明页面对象。
首先,考虑一个典型的测试自动化示例,它不使用页面对象。用的是selenium1.0的方法
/*** * Tests login feature */ public class Login { public void testLogin() { selenium.type("inputBox", "testUser"); selenium.type("password", "my supersecret password"); selenium.click("sign-in"); selenium.waitForPageToLoad("PageWaitPeriod"); Assert.assertTrue(selenium.isElementPresent("compose button"), "Login was unsuccessful"); } }
这种方法有两个问题:
  1. 测试方法和AUT的定位器之间没有分离(本例中的ID); 两者都是以单一方式交织在一起的。如果AUT的UI更改其标识符、布局或登录输入和逻辑,则整个测试脚本都要修改。
  2. ID定位器将分散在多个测试中,在所有必须使用此登录页面的测试中。
应用页面对象技术,上面的例子将被重写为下面有页面对象的登录页面例子。
/** * Page Object encapsulates the Sign-in page.页面对象封装到登录页面中,页面对象1SignInPage */ public class SignInPage { private Selenium selenium; public SignInPage(Selenium selenium) { this.selenium = selenium; if(!selenium.getTitle().equals("Sign in page")) { throw new IllegalStateException("This is not sign in page, current page is: " +selenium.getLocation()); } } /** * Login as valid user * * @param userName * @param password * @return HomePage object */ public HomePage loginValidUser(String userName, String password) { selenium.type("usernamefield", userName); selenium.type("passwordfield", password); selenium.click("sign-in"); selenium.waitForPageToLoad("waitPeriod"); return new HomePage(selenium); // 这里是对登录后是否跳转到首页做判断 } }
并且登录后到主页的页面对象可能如下所示。
/** * Page Object encapsulates the Home Page,页面对象2HomePage */ public class HomePage { private Selenium selenium; public HomePage(Selenium selenium) { if (!selenium.getTitle().equals("Home Page of logged in user")) { throw new IllegalStateException("This is not Home Page of logged in user, current page" + "is: " +selenium.getLocation()); } } public HomePage manageProfile() { // Page encapsulation to manage profile functionality return new HomePage(selenium); } /*More methods offering the services represented by Home Page of Logged User. These methods in turn might return more Page Objects for example click on Compose mail button could return ComposeMail class object;提供由登录用户主页表示的服务的更多方法。这些方法反过来可能会返回更多的页面对象,例如,点击合成邮件按钮就可以返回组合类对象。*/ }
所以现在,登录测试将使用这两个页面对象SignInPage和HomePage,如下所示。
/*** * Tests login feature 这里的代码便是文中多次提到的测试代码或测试本身或测试脚本或被测应用脚本,而上面的两个类则是页面对象,文字翻译有待矫正,仅供学习参考 */ public class TestLogin { public void testLogin() { SignInPage signInPage = new SignInPage(selenium); HomePage homePage = signInPage.loginValidUser("userName", "password"); Assert.assertTrue(selenium.isElementPresent("compose button"), "Login was unsuccessful"); } }
在设计页面对象方面有很大的灵活性,但是获得测试代码所需的可维护性有一些基本规则。
页面对象设计规则:
1、页面对象本身不应该进行验证或断言。这是你测试的一部分,应该始终在测试代码中,而不是在页面对象中。页面对象将包含页面的表示形式,以及页面通过方法提供的服务,但与被测应用脚本有关的代码不应在页面对象中。
2、有一个单一的验证功能应该写进页面对象内,它用于验证页面以及页面上可能的关键元素是否已正确加载。这个验证应该在实例化页面对象时完成。在上面的示例中,SignInPage和HomePage构造函数都先检查期望的页面是否可用,然后再进行其它测试操作。这好像前面说的安全操作。
3、页面对象不一定需要包括整个页面功能。页面对象设计模式可以用来表示页面上的组件。如果AUT中的页面具有多个组件,那么如果每个组件都有单独的页面对象,则可以提高可维护性。比如订单列表有创建、编辑、删除等功能,每个功能都有一定的流程或逻辑,则可以将其单独封装到不同的pageobject中,便于维护。
其它设计模式Page Factory:
还有其他可用于测试的设计模式。有些人使用Page Factory来实例化他们的页面对象。讨论所有这些超出了本用户指南的范围。在这里,我们只想介绍一些概念,让读者了解一些可以完成的事情。正如前面提到的,许多人在这个主题上发表了博文,我们鼓励读者搜索关于这些主题的博客。虽然还有其它设计模式,但笔者建议使用主流的即可,其它的仅供学习参考便可,想把学到的东西应用在工作中应该先考虑其实用性。
  1. 数据驱动测试
数据驱动测试指的是通过不同数据执行多次相同的测试用例或不同的测试用例。这些数据集通常来自外部文件,即.csv文件,文本文件或可能从数据库加载。数据驱动测试是一种常用的测试自动化技术,用于验证应用程序是否适用于多种不同的输入。当测试设计用于变化数据时,输入数据可以扩展,实质上创建额外的测试内容,而不需要更改测试代码。
在Python中:
# Collection of String values , source = open("input_file.txt", "r") values = source.readlines() source.close() # Execute For loop for each String in the values array for search in values: driver.get('http://www.google.com') driver.find_element_by_name("q").send_keys(search) driver.find_element_by_id("btnG").click() element = WebDriverWait(driver, 5).until(ExpectedConditions.presence_of_element_located((By.XPATH, "//*[contains(., 'Results')]")) assert search in element.text
上面的Python脚本打开了一个文本文件。该文件在每行上包含一个不同的搜索字符串。然后代码将其保存在一个字符串数组中,然后遍历数组,对每个字符串执行搜索和断言。
这是一个非常基本的例子,但这个想法表明,使用编程或脚本语言可以轻松完成使用不同数据的测试。此外,这是测试自动化专业人士中的一个众所周知的话题,包括那些不使用Selenium的人,因此在“数据驱动的测试”中搜索互联网应该会揭示许多关于此主题的博客。
 
  1. 数据库验证技术
另一种常见类型的测试是将UI中的数据与实际存储在AUT数据库中的数据进行比较。由于您也可以使用编程语言进行数据库查询,假设您有数据库支持功能,则可以使用它们检索数据,然后使用数据验证AUT显示的内容是否正确。
考虑从数据库中检索注册电子邮件地址的示例,然后再与UI进行比较。建立数据库连接并从数据库检索数据的例子如下所示
在Java中:
// Load Microsoft SQL Server JDBC driver.倒入数据库驱动 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); // Prepare connection url.设定数据库变量 String url = "jdbc:sqlserver://192.168.1.180:1433;DatabaseName=TEST_DB"; // Get connection to DB.连接数据库 public static Connection con = DriverManager.getConnection(url, "username", "password"); // Create statement object which would be used in writing DDL and DML // SQL statement.创建sql操作声明 public static Statement stmt = con.createStatement(); // Send SQL SELECT statements to the database via the Statement.executeQuery // method which returns the requested information as rows of data in a // ResultSet object.执行查询操作将请求结果返回给一个对象 ResultSet result = stmt.executeQuery ("select top 1 email_address from user_register_table"); // Move cursor from default position to first row of result set.将光标从默认位置移动到结果集的第一行。 result.next(); // Fetch value of "email_address" from "result" object.从“result”对象中获取“email_address”的值。 String emailaddress = result.getString("email_address"); // Use the emailAddress value to login to application.使用emailAddress值登录到应用程序。 driver.findElement(By.id, "userID").sendKeys(emailaddress); driver.findElement(By.id, "password").sendKeys(secretPassword); driver.findElement(By.id, "loginButton").click(); WebElement element = driver.findElement(By.xpath, "//*[contains(.,'Welcome back ')]"); Assert.assertTrue(element.getText().contains(emailaddress), "Unable to log in for user" + emailaddress)
这是一个从数据库中检索数据的简单Java示例。
 
 
posted @ 2019-06-04 13:57  HenryZ.Tang  阅读(186)  评论(0编辑  收藏  举报