【问题标题】:how can I add code reuse to my Selenium tests?如何在我的 Selenium 测试中添加代码重用?
【发布时间】:2011-02-08 23:10:50
【问题描述】:

这是我正在处理的情况:

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

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

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

【问题讨论】:

    标签: selenium selenium-rc


    【解决方案1】:

    从 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 类中所有帮助您实现搜索功能的方法。

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

    • 如果 UI 发生变化(字段的 id),您可以使用一种方法,更新 id,一切顺利
    • 如果您的逻辑流程发生变化,您也只有一个地方可以更新
    • 测试您的更改是否有效,您只需运行其中一项测试即可进行验证。所有其他测试都使用相同的代码,因此它应该可以工作。
    • 当您查看代码时,更多表现力。使用命名良好的方法,您可以创建更易于阅读和理解的更高级别的抽象。
    • 灵活且可扩展!可能性是无限的。此时你可以使用条件、循环、异常,你可以自己做报告等等……

    This website 是关于您要完成的工作的极好资源。

    祝你好运!

    【讨论】:

    • 真的吗?我不能拥有 testA 和 testB 并让它们使用相同的“远程控制”实例,或者换句话说,测试之间的相同登录会话?认真的吗?
    【解决方案2】:

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

    1. 消除您自己的代码库中的代码重复——c_maker 谈到了这一点。
    2. 从 Selenium IDE 生成的代码中消除代码重复。

    我应该指出,我的 cmets 严重依赖于您正在使用的单向工作流 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) 的广泛文章。

    【讨论】:

      【解决方案3】:

      您还可以放置一些片段或单行,例如

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-15
        • 1970-01-01
        • 1970-01-01
        • 2011-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多