【问题标题】:Determine whether or not web application is running in UI test mode确定 Web 应用程序是否在 UI 测试模式下运行
【发布时间】:2013-08-06 20:36:16
【问题描述】:

我正在尝试找出确定我是否正在为 Web 应用程序运行 UI 测试的最佳方法。我尝试这样做的原因是因为如果我正在运行 UI 测试,这些测试的唯一目的是确保 UI 正常工作并且要做到这一点,它们应该针对模拟 API 运行(我们有一个单独的集合集成测试,以确保 UI 和真正的后端 API 一起正常工作)。此外,模拟 API 调用将使测试测试运行得更快,这是模拟它们的另一个原因。我认为这些 UI 的“单元测试”。

我也不想拥有相同代码库的 2 个单独副本,其中除了 UI 测试版本包含模拟 UI 测试正常运行所需的所有必需调用的 javascript 文件外,其他所有内容都相同。如果我能够确定我在 UI 测试模式下运行应用程序,那么我将能够知道是否包含 javascript 文件来模拟调用。

有没有“标准”或“公认”的方式来做这样的事情?

【问题讨论】:

    标签: testing web-applications gui-testing


    【解决方案1】:

    当您开始运行测试时 - 在数据库中提出一个标志并拥有一个您可以调用的服务来检查该标志。确保在测试结束后关闭该标志。

    【讨论】:

    • 理想情况下,我希望完全不必与数据库进行此类测试,但这是一种选择。
    • @ryanzec 相反,如果它是一个测试 - 尽可能多地与数据库交谈,只有当它是运行的生产代码时,你应该考虑优化/缓存等。
    • 通常您使用属性文件来配置您的应用程序。测试有不同的配置集,你可以使用它。除此之外,您当然可以使用系统变量或全局变量,但这更难看
    【解决方案2】:

    对“是否有任何标准公认方式来做这样的事情?”的简短回答?应该是:没有。

    这主要是因为您根本不希望您的 UI 知道此类信息。您希望您的 UI 成为您的 UI。一旦你的 UI 开始根据它是处于“测试模式”还是“生产模式”做出一些决定,你就会走上一个滑坡,最终将导致噩梦般的代码库。

    这并不意味着您的问题无法解决;只是应该以不同的方式处理解决方案。我将首先解释一般原则,不涉及任何语言细节,然后提供一些 javascript 指南。

    一般原则

    您为此苦苦挣扎的唯一原因是您的 UI 与 API 的耦合过于紧密。

    解决方案恰好与您希望使用模拟的任何情况完全相同。

    1. 编程到接口,而不是实现。 (确保您的 UI 仅绑定到 API 的抽象,而不是“真正/生产 API”。)
    2. 将实例化与交互分开。 (不要让您的 UI 创建其任何 API 依赖项,因为这会将其绑定到特定的实现 - 而是在 UI 上提供接口,以便为其提供应该使用的特定 API 实例。)

    编程到接口

    首先请注意,上述短语并不意味着您的语言需要支持“interface”结构。 (这只是一些语言实现者对名称的不幸选择。)

    • 定义一个基类/对象,它定义了您的 API 应该支持的每个方法/消息。 (但是,这些实际上都不会在基类/对象上实现。)
    • 您的 UI 应该有一个对 APIInterface 的变量/字段/引用。
    • 您的 UI 将通过接口引用从 API 调用它需要的方法。例如。 APIRef.DoMethod1(...)APIRef->DoMethod1(...)[APIRef DoMethod1:...]

    将实例化与交互分开

    这里要避免的是:

    CreateUI {
      APIRef = CreateAPI;
    }
    

    以上内容将您的 UI 绑定到特定实现,并强制您在 UI 代码中包含这些文件/依赖项。您宁愿让您的 UI 被告知要使用哪个 API。例如

    CreateUI(APIInterface APIToUse) { //NB: Notice that the type use to refer 
                                      //to the API is the abstract base type 
                                      //defined earlier (keeping to the "Program 
                                      //to an interface" principle).
      APIRef = APIToUse;
    }
    //or
    SetAPI(APIInterface APIToUse) {
      APIRef = APIToUse;
    }
    

    现在您的生产应用程序可能如下所示:

    API = CreateTrueAPI;
    UI = CreateUI(API);
    

    而您的测试应用程序可能看起来像这样:

    API = CreateMockAPI;
    UI = CreateUI(API);
    

    请注意,使用此解决方案时,您的 UI 不知道“测试模式”或“生产模式”。它只是使用它提供的 API。唯一知道“测试模式”(从某种意义上说)和模拟 API 是测试应用程序。

    将这些原则应用于 Javascript

    首先声明一下:虽然我熟悉Javascript的语言原理,但是我从来没有做过JS开发。所以可能会出现一些无法预料的并发症。不过,在最坏的情况下,只要稍加调整和研究,我相信你会想出办法的。

    Javascript 支持鸭子类型,这基本上意味着您可以向任何对象发送任何消息,并且在运行时对象将决定它是否可以实际处理该消息。您会在编译时检查您没有犯任何拼写错误,但据我了解:您根本不需要定义抽象基接口。
    所以...

    • 只需确保您的 UI 具有对 API 对象的引用。
    • 确保您的 UI 不包含任何 API 实现文件(无论是真实/生产版本还是模拟版本)。
    • 在您的生产主机中创建真正的 API,创建 UI 并将真正的 API 传递给 UI。
    • 在您的测试主机中创建模拟 API,创建 UI 并将模拟 API 传递给 UI。

    【讨论】:

      猜你喜欢
      • 2015-11-26
      • 1970-01-01
      • 2016-12-29
      • 1970-01-01
      • 2020-02-24
      • 2017-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多