Qunitシリーズ--1.紹介ユニットテスト(上)
55080 ワード
ユニットテストはコードの品質を保証する上で重要であることはよく知られていますが、クライアントコードに対してユニットテストを行うのは難しいことが多いです.JavaScriptコードはバックグラウンドコードやhtmlと密接に結合しているため、真のユニットの概念が欠けているという難しい問題があります.例えばdomの操作では,jqueryのようなクラスライブラリを用いてjsコードを1つのファイルに単独で置くか,埋め込みコードを直接使用するかの実装にかかわらず,テスト可能なユニットはない.
では、ユニットとは何でしょうか.一般的に、ユニットは機能関数であり、同じ入力であり、出力結果は一定である.この場合の関数は、ユニットテストはかなり簡単ですが、domの操作など、特殊な状況を処理する必要がある場合があります.私たちにとって彼は依然として役に立ち、どのコードがユニットに構築されるかを指摘し、対応するテストを行うことができます.
ユニットテストの作成
上記の指導思想があれば、私たちが新しい仕事を始め、ユニットテストを導入するときにかなり簡単な仕事です.しかし、本稿で紹介する内容は、既存のコードに対してユニットテストを改善するのに役立ちます.私たちは以下の難題を解決する必要があります.既存のコードを抽出し、重要な部分をテストします.潜在的な問題を発見し、修復します.
既存のコードを抽出して彼を異なる場所に置いて、既存の機能に影響を与えないで、私たちはこの過程を再構築と呼んで、再構築はコード設計を改善するのにかなり役立つ方法です.コードの修正は既存の機能に影響を与える可能性があります.これはユニットテストの重要性を体現しています.彼はあなたの仕事をより保障します.この場合、ユニットテストはまだ行われていないので、手動テストでコードの修正が新しいバグを生じないことを保証する必要があります.私たちは今理論の基礎を持っています.次にしなければならないのは例を探して実践することです.次のコードは、
コードを実行すると、すべての時間が置き換えられるわけではありません.コードは、ページ内のtitle属性を含むすべての接続をクエリーし、titleに対してprettyDate関数を実行し、関数が結果を返すとリンクのinnerHTML属性を更新します.
コードをテスト可能にする
問題は、31日以上の場合、prettyDateはundefinedを返すだけで、リンクの内容は変化しません.仮定によって何が起こったかを見るには、現在の時間をハードコーディングする必要があります.
インスタンスの実行
リンクには「2 hours ago」「Yesterday」などが表示されますが、現在のコードは実際にテスト可能なユニットではありません.コードをさらに改造しない前提で,我々がテストできるのはDOMの変更結果だけである.これで作業できますが、htmlコードの小さな修正でテストが破れる可能性があります.このテストの効果は低いです.
リファクタリング:1
彼がユニットテストできるようにコードを再構築する必要があります.私たちは2つの変更をする必要があります:1.パラメータの形式でprettyDate関数に現在の時間を渡して、このようにプログラムの中でnew Dateを使う必要はありません;2.関数を別のファイルに抽出すると、再利用可能になります.
prettydate.jsコード:
インスタンスの実行
テストできるものがありますユニットテストをします
インスタンスの実行(firebugやchromeなどのコンソールの使用が許可されていることを確認します)
これにより、コンソールを使用して結果を出力する特定のテストアーキテクチャを作成しました.彼はDOMに依存しないので、ブラウザのないJavaScript環境で実行できます.例えばNode.jsまたはRhino.テストに失敗すると、期待値と実績値が表示されます.最後に、失敗と成功の合計数が表示されます.すべてが成功した場合、結果は次のようになります.
失敗した場合:
特定のソリューションを使用してテストを完了することができますが、既存のテストフレームワークを使用すると、より良い作業を完了することができます.彼は、より良い結果を示し、より多くのコマンドなどを提供してくれます.次の節ではQunitの使用について説明します.
出典:http://qunitjs.com/intro/
では、ユニットとは何でしょうか.一般的に、ユニットは機能関数であり、同じ入力であり、出力結果は一定である.この場合の関数は、ユニットテストはかなり簡単ですが、domの操作など、特殊な状況を処理する必要がある場合があります.私たちにとって彼は依然として役に立ち、どのコードがユニットに構築されるかを指摘し、対応するテストを行うことができます.
ユニットテストの作成
上記の指導思想があれば、私たちが新しい仕事を始め、ユニットテストを導入するときにかなり簡単な仕事です.しかし、本稿で紹介する内容は、既存のコードに対してユニットテストを改善するのに役立ちます.私たちは以下の難題を解決する必要があります.既存のコードを抽出し、重要な部分をテストします.潜在的な問題を発見し、修復します.
既存のコードを抽出して彼を異なる場所に置いて、既存の機能に影響を与えないで、私たちはこの過程を再構築と呼んで、再構築はコード設計を改善するのにかなり役立つ方法です.コードの修正は既存の機能に影響を与える可能性があります.これはユニットテストの重要性を体現しています.彼はあなたの仕事をより保障します.この場合、ユニットテストはまだ行われていないので、手動テストでコードの修正が新しいバグを生じないことを保証する必要があります.私たちは今理論の基礎を持っています.次にしなければならないのは例を探して実践することです.次のコードは、
title
のプロパティを含むすべての接続を見つけ、状況に応じて「5 days ago」などの時間が経過したかを示します.<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Mangled date examples</title>
<script>
function prettyDate(time){
var date = new Date(time || ""),
diff = (((new Date()).getTime() - date.getTime()) / 1000),
day_diff = Math.floor(diff / 86400);
if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
return;
return day_diff == 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" ||
diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
diff < 7200 && "1 hour ago" ||
diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
day_diff == 1 && "Yesterday" ||
day_diff < 7 && day_diff + " days ago" ||
day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}
window.onload = function() {
var links = document.getElementsByTagName("a");
for ( var i = 0; i < links.length; i++ ) {
if ( links[i].title ) {
var date = prettyDate(links[i].title);
if ( date ) {
links[i].innerHTML = date;
}
}
}
};
</script>
</head>
<body>
<ul>
<li class="entry" id="post57">
<p>blah blah blah...</p>
<small class="extra">
Posted <span class="time"><a href="/2008/01/blah/57/" title="2008-01-28T20:24:17Z"><span>January 28th, 2008</span></a></span>
by <span class="author"><a href="/john/">John Resig</a></span>
</small>
</li>
<!-- ... -->
</ul>
</body>
</html>
コードを実行すると、すべての時間が置き換えられるわけではありません.コードは、ページ内のtitle属性を含むすべての接続をクエリーし、titleに対してprettyDate関数を実行し、関数が結果を返すとリンクのinnerHTML属性を更新します.
コードをテスト可能にする
問題は、31日以上の場合、prettyDateはundefinedを返すだけで、リンクの内容は変化しません.仮定によって何が起こったかを見るには、現在の時間をハードコーディングする必要があります.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Mangled date examples</title>
<script>
function prettyDate(now, time){
var date = new Date(time || ""),
diff = (((new Date(now)).getTime() - date.getTime()) / 1000),
day_diff = Math.floor(diff / 86400);
if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
return;
return day_diff == 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" ||
diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
diff < 7200 && "1 hour ago" ||
diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
day_diff == 1 && "Yesterday" ||
day_diff < 7 && day_diff + " days ago" ||
day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}
window.onload = function() {
var links = document.getElementsByTagName("a");
for ( var i = 0; i < links.length; i++ ) {
if ( links[i].title ) {
var date = prettyDate("2008-01-28T22:25:00Z", links[i].title);
if ( date ) {
links[i].innerHTML = date;
}
}
}
};
</script>
</head>
<body>
<ul>
<li class="entry" id="post57">
<p>blah blah blah...</p>
<small class="extra">
Posted <span class="time"><a href="/2008/01/blah/57/" title="2008-01-28T20:24:17Z"><span>January 28th, 2008</span></a></span>
by <span class="author"><a href="/john/">John Resig</a></span>
</small>
</li>
<-- ... -->
</ul>
</body>
</html>
インスタンスの実行
リンクには「2 hours ago」「Yesterday」などが表示されますが、現在のコードは実際にテスト可能なユニットではありません.コードをさらに改造しない前提で,我々がテストできるのはDOMの変更結果だけである.これで作業できますが、htmlコードの小さな修正でテストが破れる可能性があります.このテストの効果は低いです.
リファクタリング:1
彼がユニットテストできるようにコードを再構築する必要があります.私たちは2つの変更をする必要があります:1.パラメータの形式でprettyDate関数に現在の時間を渡して、このようにプログラムの中でnew Dateを使う必要はありません;2.関数を別のファイルに抽出すると、再利用可能になります.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Refactored date examples</title>
<script src="prettydate.js"></script>
<script>
window.onload = function() {
var links = document.getElementsByTagName("a");
for ( var i = 0; i < links.length; i++ ) {
if ( links[i].title ) {
var date = prettyDate("2008-01-28T22:25:00Z", links[i].title);
if ( date ) {
links[i].innerHTML = date;
}
}
}
};
</script>
</head>
<body>
<ul>
<li class="entry" id="post57">
<p>blah blah blah...</p>
<small class="extra">
Posted <span class="time"><a href="/2008/01/blah/57/" title="2008-01-28T20:24:17Z"><span>January 28th, 2008</span></a></span>
by <span class="author"><a href="/john/">John Resig</a></span>
</small>
</li>
<-- ... -->
</ul>
</body>
</html>
prettydate.jsコード:
function prettyDate(now, time){
var date = new Date(time || ""),
diff = (((new Date(now)).getTime() - date.getTime()) / 1000),
day_diff = Math.floor(diff / 86400);
if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
return;
return day_diff == 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" ||
diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
diff < 7200 && "1 hour ago" ||
diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
day_diff == 1 && "Yesterday" ||
day_diff < 7 && day_diff + " days ago" ||
day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}
インスタンスの実行
テストできるものがありますユニットテストをします
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Refactored date examples</title>
<script src="prettydate.js"></script>
<script>
function test(then, expected) {
results.total++;
var result = prettyDate("2008/01/28 22:25:00", then);
if (result !== expected) {
results.bad++;
console.log("Expected " + expected + ", but was " + result);
}
}
var results = {
total: 0,
bad: 0
};
test("2008/01/28 22:24:30", "just now");
test("2008/01/28 22:23:30", "1 minute ago");
test("2008/01/28 21:23:30", "1 hour ago");
test("2008/01/27 22:23:30", "Yesterday");
test("2008/01/26 22:23:30", "2 days ago");
test("2007/01/26 22:23:30", undefined);
console.log("Of " + results.total + " tests, " + results.bad + " failed, "
+ (results.total - results.bad) + " passed.");
</script>
</head>
<body>
</body>
</html>
インスタンスの実行(firebugやchromeなどのコンソールの使用が許可されていることを確認します)
これにより、コンソールを使用して結果を出力する特定のテストアーキテクチャを作成しました.彼はDOMに依存しないので、ブラウザのないJavaScript環境で実行できます.例えばNode.jsまたはRhino.テストに失敗すると、期待値と実績値が表示されます.最後に、失敗と成功の合計数が表示されます.すべてが成功した場合、結果は次のようになります.
Of 6 tests, 0 failed, 6 passed.
失敗した場合:
Expected 2 day ago, but was 2 days ago.
Of 6 tests, 1 failed, 5 passed.
特定のソリューションを使用してテストを完了することができますが、既存のテストフレームワークを使用すると、より良い作業を完了することができます.彼は、より良い結果を示し、より多くのコマンドなどを提供してくれます.次の節ではQunitの使用について説明します.
出典:http://qunitjs.com/intro/