JavaScript 函数的单元测试用例,它从 FORM 访问 HTML 元素

unit test case for JavaScript function which access HTML elements from FORM

我是 JavaScript 单元测试的新手。

我们正在将 PHP 遗留应用程序转换为 Symfony2 框架。我们计划使用遗留 javascript 库。 TDD 方法适用于控制器和服务(PHP 代码)。

对于 Javascript 函数不需要 TDD,因为我们可以通过使元素 ID 类似于新 Symfony2 形式(树枝)中的旧代码来成功地使用遗留 Javascript 函数。

为了将来对 javascript 代码进行增强和单元测试,我们还需要为这些遗留功能编写单元测试用例。我们计划为此使用 Qunit

示例函数是

function DetailDrop(fieldname) {
  fn = fieldname.id;
  var field = fn.substring(0, fn.length - 2);
  if (document.getElementById(field + "_C") && document.getElementById(field + "_C").checked == true && document.getElementById(field + "_D")) {
    document.getElementById(field + "_D").style.display = 'inline';
  }
  else if (((document.getElementById(field + "_Y") && document.getElementById(field + "_Y").checked == true) || (document.getElementById(field + "_/") && document.getElementById(field + "_/").checked == true)) && document.getElementById(field + "_D")) {
    document.getElementById(field + "_D").style.display = 'none';
    document.getElementById(field + "_D").selectedIndex = 0;
  }
  else if (((document.getElementById(field + "_N") && document.getElementById(field + "_N").checked == true) || (document.getElementById(field + "_P") && document.getElementById(field + "_P").checked == true)) && document.getElementById(field + "_D")) {
    document.getElementById(field + "_D").style.display = 'inline';
  }
}

考虑到上面的问题上下文,我无法找到对此类 javascript 函数进行单元测试的方法,这些函数从 Web 表单访问 HTML 元素。

在这种情况下,我应该寻找模拟完整 Web 表单的选项

或 我是不是完全断章取义了?

你说的是 keeping your tests atomic 与 DOM 的关系,这太棒了!不要放弃!

基本思想是在 "fixture" 中有一个表单版本,每个测试都会重置 before/after,以免一个测试影响另一个测试(确保原子性)。您可以通过两种方式执行此操作:(1) 将 HTML 代码添加到 QUnit HTML 文件中的“#qunit-fixture”div,或者 (2) 只需访问您的模块 beforeEach()afterEach() 来创建你需要的东西。

(1) HTML 方法:将 <form> 添加到 #qunit-fixture:

<html>
  ...
  <body>
    <div id="qunit"></div>
    <div id="qunit-fixture">
      <form ...>
        <!-- only what MUST be there for JS to work -->
      </form>
    </div>
    ...
  </body>
</html>

QUnit 会在每次测试 运行 之前重置 #qunit-fixture 元素内的所有内容,因此您根本不需要担心它。这可能是最简单的方法,但无法为您提供广泛的控制。

(2) 使用模块 beforeEach()afterEach() 方法来设置你的 HTML (注意我的代码使用 jQuery,但你不需要到):

// 在你的 JavaScript 测试文件中...

var fixture = $( "#qunit-fixture" );
QUnit.module("form tests", {
  beforeEach: function() {
    fixture.html("<form> ..... </form>");
  },
  afterEach: function() {
    fixture.find("form").remove();
    // any other cleanup (events maybe?)
  }
});

无论哪种情况,您现在都可以在测试中访问 <form>,并且每个 运行:

之前都将是 "refreshed"
QUnit.test("test form submission", function(assert) {
  $("form").submit();
  // maybe make sure an Ajax call was made?
  // or that there is an error on the page?
});