测试浏览器扩展

时间:2013-02-10 14:02:18

标签: javascript testing tdd bdd browser-extension

我要写一堆浏览器扩展(每个流行的浏览器都有相同的功能)。我希望,一些代码将被共享,但我还不确定。当然,一些扩展将使用本机API。我对TDD / BDD没有多少经验,我认为现在是开始从这个项目中获取这些想法的好时机。

问题是,我不知道如何处理它。我应该为每个浏览器编写不同的测试吗?我应该走多远这些测试?这些扩展非常简单 - 本地存储中的一些数据,刷新页面和通过Web套接字进行监听。

我的观察为什么对我来说很难 - 因为有很多行为,而不是那些依赖于平台的模型。

2 个答案:

答案 0 :(得分:57)

我练习了两种不同的测试浏览器扩展的方法:

  • 单元测试
  • 整合测试

简介

我将在整个答案中使用跨浏览器YouTube Lyrics by Rob W扩展名作为示例。此扩展的核心是用JavaScript编写的,并使用AMD模块进行组织。构建脚本为每个浏览器生成扩展文件。使用r.js,我简化了特定于浏览器的模块的包含,例如用于跨源HTTP请求和持久存储(用于首选项)的模块,以及用于IE的具有大量polyfill的模块。

该扩展程序会在YouTube,Grooveshark和Spotify上为当前播放的歌曲插入带有歌词的面板。我无法控制这些第三方网站,因此我需要一种自动方式来验证扩展程序是否仍能正常运行。

工作流

在开发过程中:

  1. 实现/编辑功能,如果功能不重要,则编写单元测试。
  2. 运行所有单元测试以查看是否有任何损坏。如果有任何问题,请返回1.
  3. 承诺给git。
  4. 发布前:

    1. 运行所有单元测试以验证各个模块是否仍在工作。
    2. 运行所有集成测试以验证整个扩展程序是否仍在运行。
    3. Bump版本,构建扩展。
    4. 将更新上传到官方扩展画廊和我的网站(Safari和IE扩展必须由您自己托管)并提交给git。
    5. 单元测试

      我使用mocha + expect.js来编写测试。我不会测试每个模块的每个方法,只测试那些重要的方法。例如:

      • DOM解析方法。大多数DOM解析方法(包括jQuery)都存在缺陷:加载任何外部资源并执行JavaScript 我验证DOM解析方法正确地解析DOM而没有负面的副作用。

      • 首选项模块:我验证可以保存并返回数据。

      • 我的扩展程序从外部来源获取歌词。这些源在单独的模块中定义。 InfoProvider模块识别并使用这些定义,该模块接受查询(黑盒子)并输出搜索结果。

        • 首先,我测试InfoProvider模块是否正常运行。
        • 然后,对于17个源中的每一个,我将预定义的查询传递给源(使用InfoProvider)并验证结果是否是预期的:
          • 查询成功
          • 返回的歌曲标题匹配(通过applying单词相似度算法)
          • 返回歌词的长度属于预期范围。
      • UI是否明显不受影响,例如点击“关闭”按钮。

      这些测试可以直接从本地服务器运行,也可以在浏览器扩展中运行。本地服务器的优点是您可以编辑测试并刷新浏览器以查看结果。如果所有这些测试都通过,我会从浏览器扩展中运行测试 通过将额外的参数debug传递给我的构建脚本,单元测试与我的扩展名捆绑在一起。

      在网页中运行测试是不够的,因为扩展程序的环境可能与普通页面不同。例如,在Opera 12扩展中,没有全局location对象。

      备注:我没有在发布版本中包含测试。大多数用户都不会努力报告和调查错误,他们只会给出较低的评分并说出类似“不能工作”的内容。在发货之前,请确保您的扩展功能没有明显的错误。

      摘要

      • 将模块视为黑盒子。只要输出匹配是预期的或给定的输入,你就不在乎里面的内容。
      • 开始测试扩展程序的关键部分。
      • 确保可以在非扩展环境中轻松构建和运行测试。
      • 不要忘记在扩展程序的执行环境中运行测试,以确保在扩展程序的上下文中没有任何约束或意外情况会破坏您的代码。

      集成测试

      我使用Selenium 2来测试我的扩展程序是否仍适用于YouTube,Grooveshark(3x)和Spotify。

      最初,我只是使用Selenium IDE来记录测试并查看它是否有效。这很顺利,直到我需要更多的灵活性:我想有条件地运行测试,具体取决于测试帐户是否已登录。使用默认的Selenium IDE是不可能的(FlowControl plugin可以说它是可能的 - 我还没试过)。

      Selenium IDE提供了以其他格式导出现有测试的选项,包括JUnit 4测试(Java)。不幸的是,这个结果并不令人满意。很多命令都没有被识别出来。

      所以,我放弃了Selenium IDE,转而使用Selenium 请注意,当您搜索" Selenium"时,您会找到有关Selenium RC(Selenium 1)和Selenium WebDriver(Selenium 2)的信息。第一个是旧的并且已弃用,后者(Selenium WebDriver)应该用于新项目。

      一旦您发现文档的工作原理,它就非常容易使用 我更喜欢项目页面上的文档,因为它通常简洁(wiki)和完整(Java docs)。

      如果您想快速入门,请阅读Getting Started wiki page。如果您有空闲时间,请查看documentation at SeleniumHQ,特别是Selenium WebDriverWebDriver: Advanced UsageSelenium Grid也值得一读。此功能允许您跨不同(虚拟)计算机分发测试。如果你想在IE8,9和10,同时中测试你的扩展,那就太好了(要运行多个版本的Internet Explorer,你需要虚拟化)。

      自动化测试很不错。什么更好?自动安装扩展!
      ChromeDriverFirefoxDriver支持扩展的安装,如this example中所示。

      对于SafariDriver,我已经编写了两个类来安装自定义Safari扩展。我已将其发布并发送给了Selenium,因此未来可能会向所有人发布:https://github.com/SeleniumHQ/selenium/pull/87

      OperaDriver不支持安装自定义扩展程序(从技术上讲,它应该是可行的) 请注意,随着Chromium-powered Opera的出现,旧的OperaDriver不再适用。

      有一个Internet Explorer Driver,而且这个绝对不允许安装自定义扩展程序。 Internet Explorer没有内置的扩展支持。扩展是通过MSI或EXE安装程序安装的,这些安装程序甚至没有集成到Internet Explorer中。因此,为了在IE中自动安装扩展,您需要能够以静默方式运行安装IE插件的安装程序。我还没有尝试过

答案 1 :(得分:4)

测试浏览器扩展也给我带来了一些困难,但我已经决定在几个不同的领域实现测试,我可以同时从Selenium驱动的浏览器中调用。

我使用的步骤是:

首先,我编写集成到扩展代码中的测试代码,只需转到特定的URL即可激活。当扩展程序看到该URL时,它开始运行测试。

然后,在激活扩展中的测试的页面中,我执行服务器端测试以确保API执行,并在那里记录和记录问题。我记录了调用的方法,它们花费的时间以及任何错误。所以我可以看到扩展调用的方法,Web性能,业务逻辑性能和数据库性能。

最后,我自动调用浏览器指向该特定URL,并使用Selenium在任何给定的客户端系统上记录其性能以及其他测试信息,错误等:

http://docs.seleniumhq.org/

这样我可以根据浏览器,扩展,服务器,应用程序和数据库分解测试,并根据特定的测试集将它们全部链接在一起。将它们放在一起需要花费一些工作,但一旦完成,你就可以拥有一个非常好的扩展测试框架。

通常对于跨浏览器扩展开发,为了维护单个代码库,我使用crossrider,但是您可以使用任何框架或使用本机扩展来执行此操作,Selenium不会关心,它只是驱动扩展到特定页面并允许您进行交互并执行测试。

这种方法的一个好处是你也可以将它用于实时用户。如果您为扩展程序提供支持,请让用户转到您的测试网址,然后您将立即看到扩展程序和服务器端性能。当然,您不会获得Selenium测试,但是您将以这种方式捕获许多问题 - 在对各种浏览器和浏览器版本进行编码时非常有用。