qunit 测试交替失败

qunit tests alternately fail

我有两个测试,test1 和 test2。当我 运行 时,测试要么 test1 成功而 test2 失败,要么 test2 成功而 test1 失败。这两个测试都涉及单击一个按钮,该按钮通过某些 jquery 方法更新 DOM。似乎只有 运行 首先的测试才会触发这些方法,有人知道为什么会这样吗?

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Javascript tests</title>
    <link rel="stylesheet" href="http://code.jquery.com/qunit.css">
  </head>

  <body>
    <div id="qunit"></div>
    <div id="qunit-fixture">
      <div id="div1">
        <button class="selected">Property1</button>
        <button >Property2</button>
      </div> <!-- div1 -->

      <div id="div2">
        <table>
          <tbody>
            <tr>
              <th>Name</th>
              <td></td>
            </tr>
          <tbody>
        </table>
      </div> <!-- div2 -->

      <script src="http://code.jquery.com/jquery.min.js"></script>
      <script>
        $("#div1 button").click(function(){
          console.log("button clicked");
          $(this).addClass("selected"); // clicked button   is set to selected
          var nameElement = $("#div2 table td");
          nameElement.text($(this).text()); // updates the nameElement to   the text contents of the button clicked
          var buttons = $(this).parent().find("button");
          for(i=0; i<buttons.length; i++){
            if(buttons[i] != $(this)[0]){
              $(buttons[i]).removeClass("selected") // other buttons are set to unselected
            }
          }
        });
      </script>
    </div> <!-- qunit-fixture -->

    <script src="http://code.jquery.com/qunit/qunit-1.19.0.js"></script>

    <script>
      test("test clicking on a property button adds the selected class to it", function(){
      console.log("test1");

      var buttons = $("#div1 button");

      $(buttons[1]).click();
      equal($(buttons[0]).hasClass("selected"), false);
      equal($(buttons[1]).hasClass("selected"), true);

      $(buttons[0]).click();
      equal($(buttons[0]).hasClass("selected"), true);
      equal($(buttons[1]).hasClass("selected"), false);

      console.log("end of test1");
      });

      test("test clicking on a property button updates the property details", function(){

      console.log("test2");

      var buttons = $("#div1 button");
      var name = $("#div2 table td");

      buttons[1].click()
      equal(name.text(), "Property2")

      console.log("end of test2");
      });

    </script>

  </body>
</html>

控制台的输出显示按钮点击仅在 运行 的第一个测试中注册。例如

test.html:49 test1
test.html:31 button clicked
test.html:31 button clicked
test.html:61 end of test1
test.html:66 test2
test.html:74 end of test2

QUnit 将在每次测试前实例化 qunit-fixture 并重置它,但它只会重置该元素的 DOM 部分。您已将整个应用程序/脚本置于该夹具中进行测试,但一旦第二次测试 运行.

就不会重新加载

相反,尝试将您的应用程序代码移动到一个单独的文件或至少一个单独的脚本块,并稍微重写它以便它可以引导到某个容器,例如:

function myApp(container) {
    $(container).find("#div1 button").click(function(){
      console.log("button clicked");
      $(this).addClass("selected"); // clicked button   is set to selected
      var nameElement = $(container).find("#div2 table td");
      nameElement.text($(this).text()); // updates the nameElement to   the text contents of the button clicked
      var buttons = $(this).parent().find("button");
      for(i=0; i<buttons.length; i++){
        if(buttons[i] != $(this)[0]){
          $(buttons[i]).removeClass("selected") // other buttons are set to unselected
        }
      }
    });
}

在您的实际应用中,您必须触发该功能,并且在您的测试中,您确保在每次测试之前触发它,这样您就可以开始清理了。例如:

QUnit.module("MyApp", {
    beforeEach: function () {
        myApp($("#qunit-fixture"));
    }
});

有了这个,你所有的测试都被干净地分开了,不会重复使用彼此 DOM。


这是一个完整的 运行ning 示例:

function myApp(container) {
  $(container).find("#div1 button").click(function(){
    console.log("button clicked");
    $(this).addClass("selected"); // clicked button   is set to selected
    var nameElement = $(container).find("#div2 table td");
    nameElement.text($(this).text()); // updates the nameElement to   the text contents of the button clicked
    var buttons = $(this).parent().find("button");
    for(i=0; i<buttons.length; i++){
      if(buttons[i] != $(this)[0]){
        $(buttons[i]).removeClass("selected") // other buttons are set to unselected
      }
    }
  });
}

QUnit.module("MyApp", {
  beforeEach: function () {
    myApp($("#qunit-fixture"));
  }
});

test("test clicking on a property button adds the selected class to it", function(){
  console.log("test1");

  var buttons = $("#div1 button");

  $(buttons[1]).click();
  equal($(buttons[0]).hasClass("selected"), false);
  equal($(buttons[1]).hasClass("selected"), true);

  $(buttons[0]).click();
  equal($(buttons[0]).hasClass("selected"), true);
  equal($(buttons[1]).hasClass("selected"), false);

  console.log("end of test1");
});

test("test clicking on a property button updates the property details", function(){

  console.log("test2");

  var buttons = $("#div1 button");
  var name = $("#div2 table td");

  buttons[1].click()
  equal(name.text(), "Property2")

  console.log("end of test2");
});
<link href="https://code.jquery.com/qunit/qunit-1.19.0.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://code.jquery.com/qunit/qunit-1.19.0.js"></script>

<div id="qunit"></div>
<div id="qunit-fixture">
  <div id="div1">
    <button class="selected">Property1</button>
    <button >Property2</button>
  </div> <!-- div1 -->
  <div id="div2">
    <table>
      <tbody>
        <tr>
          <th>Name</th>
          <td></td>
        </tr>
      <tbody>
    </table>
  </div> <!-- div2 -->
</div> <!-- qunit-fixture -->