有人可以解释在使用 QUnit 进行单元测试时使用 qunit-fixture 吗?
Could someone explain the use of qunit-fixture when unit testing with QUnit?
我刚刚开始使用 QUnit 进行 ui 测试,所以我确定我缺少 qunit-fixture 的一些基本用例。我认为这对测试 DOM 操作很有用,但后来我意识到 none 我的 DOM 操作函数知道任何关于 qunit-fixture 的事情(他们也不应该?)。
示例:
<div id="container">
<form id="my-form">
<input type="hidden" name="field1" id="field1">
<input type="hidden" name="field2" id="field2">
</form>
</div>
<div id="qunit-fixture"></div>
我正在将 URL 参数传递给函数以填充此表单。如果这些参数不存在,我希望删除该字段,以便 JQuery.serialize()
不会捆绑空字段。
function populate(params){
if( params.field1 ){
$("#field1").val(params.field1);
} else {
$("#field1").remove();
}
if( params.field2 ){
$("#field2").val(params.field2);
} else {
$("#field2").remove();
}
}
我原来的想法是"oh, cool. I can use qunit-fixture
to repeatedly emulate my form!"这样的:
QUnit.test("populate - field1=text", function(assert){
$("#qunit-fixture").html($("#container").html());
populate( {field1: "text"} );
assert.deepEqual($("#field1").val(), "text");
assert.deepEqual($("#field2").val(), undefined);
});
QUnit.test("populate - field1="text", function(assert){
$("#qunit-fixture").html($("#container").html());
populate( {field1: "text", field2: "text"} );
assert.deepEqual($("#field1").val(), "text");
assert.deepEqual($("#field2").val(), "text");
});
这当然失败了,因为第一个测试对 populate()
的调用改变了 DOM 并从页面的主窗体中删除了 #field2
以及放置到 qunit-fixture
(非唯一 ID.. 哎呀)。
那我错过了什么?我真的很喜欢使用 QUnit 测试逻辑模块的能力,并且终于开始看到更多测试驱动开发风格的优点。我也希望能够测试我的 DOM 操作。
注意:这是一个简化的示例。我项目中的实际 DOM 操作要复杂得多,因此希望对其进行测试。
qunit-fixture
元素是一些 HTML 的容器,您的测试可以针对这些元素进行断言。每次测试后,QUnit 都会将其重置回测试开始前的状态,这样下一次测试就可以 运行 而不必担心之前的测试添加或删除了什么。
当然,如果您的测试开始对 qunit-fixture
之外的元素进行修改,那么您将开始看到影响其他测试的测试,因此请尽量不要这样做。
在您的例子中,您正在创建一个空 qunit-fixture
div 并从另一个 div 复制内容。更好的方法是使用 qunit-fixture
元素来包含要测试的 HTML,例如:
<div id="qunit-fixture">
<div id="container">
<form id="my-form">
<input type="hidden" name="field1" id="field1">
<input type="hidden" name="field2" id="field2">
</form>
</div>
</div>
(我不知道你是否需要容器div。我在上面的示例中保留了它,但如果不需要,请随意删除它。)
因为您不再需要将 HTML 从容器 div 复制到 qunit-fixture
div,您可以从测试中删除这些行:
$("#qunit-fixture").html($("#container").html());
您也不再有重复 ID 的问题,并且由于 QUnit 会在每次测试后重置 qunit-fixture
,因此您不应该遇到一个测试影响另一个测试的问题。
QUnit 的目的是您 运行 从专门为测试目的而创建的页面中获取它。此页面应如下所示:
<html>
<head>
<!-- load various JS and CSS files -->
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<!-- sample markup for testing against -->
</div>
</body>
因为 qunit-fixture
之外没有标记,除了 QUnit 将用于测试结果的 qunit
div 之外,没有 "portion of the page outside qunit-fixture
",如您所写在您的评论中,也没有重复的 ID。
我刚刚开始使用 QUnit 进行 ui 测试,所以我确定我缺少 qunit-fixture 的一些基本用例。我认为这对测试 DOM 操作很有用,但后来我意识到 none 我的 DOM 操作函数知道任何关于 qunit-fixture 的事情(他们也不应该?)。
示例:
<div id="container">
<form id="my-form">
<input type="hidden" name="field1" id="field1">
<input type="hidden" name="field2" id="field2">
</form>
</div>
<div id="qunit-fixture"></div>
我正在将 URL 参数传递给函数以填充此表单。如果这些参数不存在,我希望删除该字段,以便 JQuery.serialize()
不会捆绑空字段。
function populate(params){
if( params.field1 ){
$("#field1").val(params.field1);
} else {
$("#field1").remove();
}
if( params.field2 ){
$("#field2").val(params.field2);
} else {
$("#field2").remove();
}
}
我原来的想法是"oh, cool. I can use qunit-fixture
to repeatedly emulate my form!"这样的:
QUnit.test("populate - field1=text", function(assert){
$("#qunit-fixture").html($("#container").html());
populate( {field1: "text"} );
assert.deepEqual($("#field1").val(), "text");
assert.deepEqual($("#field2").val(), undefined);
});
QUnit.test("populate - field1="text", function(assert){
$("#qunit-fixture").html($("#container").html());
populate( {field1: "text", field2: "text"} );
assert.deepEqual($("#field1").val(), "text");
assert.deepEqual($("#field2").val(), "text");
});
这当然失败了,因为第一个测试对 populate()
的调用改变了 DOM 并从页面的主窗体中删除了 #field2
以及放置到 qunit-fixture
(非唯一 ID.. 哎呀)。
那我错过了什么?我真的很喜欢使用 QUnit 测试逻辑模块的能力,并且终于开始看到更多测试驱动开发风格的优点。我也希望能够测试我的 DOM 操作。
注意:这是一个简化的示例。我项目中的实际 DOM 操作要复杂得多,因此希望对其进行测试。
qunit-fixture
元素是一些 HTML 的容器,您的测试可以针对这些元素进行断言。每次测试后,QUnit 都会将其重置回测试开始前的状态,这样下一次测试就可以 运行 而不必担心之前的测试添加或删除了什么。
当然,如果您的测试开始对 qunit-fixture
之外的元素进行修改,那么您将开始看到影响其他测试的测试,因此请尽量不要这样做。
在您的例子中,您正在创建一个空 qunit-fixture
div 并从另一个 div 复制内容。更好的方法是使用 qunit-fixture
元素来包含要测试的 HTML,例如:
<div id="qunit-fixture">
<div id="container">
<form id="my-form">
<input type="hidden" name="field1" id="field1">
<input type="hidden" name="field2" id="field2">
</form>
</div>
</div>
(我不知道你是否需要容器div。我在上面的示例中保留了它,但如果不需要,请随意删除它。)
因为您不再需要将 HTML 从容器 div 复制到 qunit-fixture
div,您可以从测试中删除这些行:
$("#qunit-fixture").html($("#container").html());
您也不再有重复 ID 的问题,并且由于 QUnit 会在每次测试后重置 qunit-fixture
,因此您不应该遇到一个测试影响另一个测试的问题。
QUnit 的目的是您 运行 从专门为测试目的而创建的页面中获取它。此页面应如下所示:
<html>
<head>
<!-- load various JS and CSS files -->
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<!-- sample markup for testing against -->
</div>
</body>
因为 qunit-fixture
之外没有标记,除了 QUnit 将用于测试结果的 qunit
div 之外,没有 "portion of the page outside qunit-fixture
",如您所写在您的评论中,也没有重复的 ID。