如何在Selenium测试中添加代码重用?

时间:2011-02-08 23:10:50

标签: selenium selenium-rc

以下是我正在处理的情况:

  • 在Selenium中构建测试
  • 让所有测试正常运行(在Firefox中)
  • 将所有测试导出到MSTest(以便每个测试都可以在IE,Chrome和FF中运行)
  • 如果需要修改任何测试,请在Selenium IDE中进行编辑

所以这是一个非常单向的工作流程。但是,我现在想做更多的自动化。例如,我希望每个测试都在两个帐户中运行。我正陷入维护问题。如果我有6个测试我想在两个帐户下运行,突然间我需要在Selenium IDE测试中进行12次测试。编辑太多了。但是大量的代码完全一样。

如何在测试中共享大量的Selenium测试?我应该使用Selenium IDE第一次开发测试然后再也不用它(之后只在VS中进行编辑)?

3 个答案:

答案 0 :(得分:3)

从IDE导出后,Selenium代码非常线性。

例如(忽略语法):

  someTestMethod() {
     selenium.open("http://someLoginPage.com");
     selenium.type("usernameField", "foo");
     selenium.type("passwordField", "bar");
     selenium.click("loginButton");
     selenium.waitForPageToLoad("30000");
     assertTrue(selenium.isTextPresent("Welcome * foo"));
  }

这是登录页面。您的每一项测试都必须使用它。你应该将它重构为一个方法。

  someTestMethod(){
     selenium.open("http://someLoginPage.com");
     String username = "foo";
     String password = "bar";
     performLogin(username, password);
  }

  performLogin(String username, String password){
      selenium.type("usernameField", username);
      selenium.type("passwordField", password);
      selenium.click("loginButton");
      selenium.waitForPageToLoad("30000");
      assertTrue(selenium.isTextPresent("Welcome * foo"));
  }

performLogin()方法不必与测试代码本身位于同一文件中。您可以使用您的方法为它创建一个单独的类,并在测试之间共享它。

我们的UI对应于某些功能。例如,我们有很多方法可以在我们的应用中进行搜索。所有可以帮助您进行搜索功能的方法都在 SearchUtil 类中。

以类似方式构建测试将带来以下优势:

  • 如果用户界面更改(字段的ID),则转到您的一种方法,更新ID并且您很高兴
  • 如果逻辑的流程发生变化,您还只有一个地方需要更新
  • 测试 更改是否有效,您只需运行其中一项测试即可验证。所有其他测试使用相同的代码,因此它应该工作。
  • 在查看代码时,还有更多富有表现力。通过命名良好的方法,您可以创建更高级别的抽象,更易于阅读和理解。
  • 灵活且可扩展!可能性是无限的。此时,您可以使用条件,循环,例外,您可以进行自己的报告等...

This website是您想要实现的目标的绝佳资源。

祝你好运!

答案 1 :(得分:2)

代码重用需要考虑两个方面:

  1. 消除您自己的代码库中的代码重复 - c_maker涉及此问题。
  2. 消除Selenium IDE 生成的代码中的代码重复。
  3. 我应该指出,我的评论非常依赖于您正在使用的单向工作流jcollum,但更重要的是:我使用IDE为给定的测试用例生成代码一次 。我永远不会回到IDE来修改测试用例并重新导出它。 (当我想在代码中调整和自定义测试用例(在我的例子中是C#)时,我想将IDE测试用例作为诊断工具保留,当我想要进行实验时。

    我赞成仅将IDE测试用作起点的原因是:

    • IDE测试总是会有很多代码重复从一个测试到另一个测试;有时甚至在一次测试中。这只是野兽的本质。
    • 在代码中,我可以使测试用例更加“用户友好”,即我可以将奥术定位器封装在有意义的属性或方法中,这样测试用例就更清楚了。
    • 使用代码而不是IDE只是提供了更大的灵活性。

    回到IDE生成的代码:它总是有大量的重复。例如:

    verifyText "//form[@id='aspnetForm']/div[2]/div/div[2]/div[1]/span" Home
    

    生成此代码块:

    try
    {
      Assert.AreEqual("Home",
        selenium.GetText("//form[@id='aspnetForm']/div[2]/div/div[2]/div[1]/span"));
    }
    catch (AssertionException e)
    {
      verificationErrors.Append(e.Message);
    }
    

    每个后续的 verifyText 命令都会生成相同的代码块,区别仅在于两个参数。

    我对这种刺鼻的代码气味的解决方案是开发 Selenium Sushi ,一个Visual Studio C#项目模板和库,可以让你消除大部分(如果不是全部)重复。使用库我可以简单地编写这一行代码以匹配IDE测试用例中的原始代码行:

    Verify.AreEqual("Home",
      selenium.GetText("//form[@id='aspnetForm']/div[2]/div/div[2]/div[1]/span"));
    

    2011年2月,我在Simple-Talk.com上发表了大量文章(Web Testing with Selenium Sushi: A Practical Guide and Toolset)。

答案 2 :(得分:0)

你也可以放一些片段或单行,例如

note( "now on page: " .  $sel->get_location() . ", " . $sel->get_title() ; 

进入IDE的“code snippets”集合(我使用Eclipse)。

这不是真正的重用,但是它对我来说是一次性测试脚本或现有测试脚本的快速增强。