目次
QUnitとは
コードをテストする必要がある理由
QUnit を使用して単体テストを作成する方法
更多断言
比较断言
相同的断言
构建你的断言
异步测试
结论
ホームページ ウェブフロントエンド jsチュートリアル QUnit を使用した JavaScript コードのテスト: ステップバイステップ ガイド

QUnit を使用した JavaScript コードのテスト: ステップバイステップ ガイド

Sep 02, 2023 pm 05:09 PM

jQuery チームによって開発された

QUnit は、JavaScript の単体テストに最適なフレームワークです。このチュートリアルでは、QUnit とは正確には何なのか、そしてなぜコードを厳密にテストする必要があるのか​​を説明します。

QUnitとは

QUnit は、コードのデバッグに役立つ強力な JavaScript 単体テスト フレームワークです。これは jQuery チームのメンバーによって作成され、jQuery の公式テスト スイートです。しかし、QUnit は通常の JavaScript コードをテストするのに十分な汎用性を備えており、Rhino や V8 などの特定の JavaScript エンジンを介したサーバーサイド JavaScript さえもテストできます。

「単体テスト」の概念に詳しくなくても、心配する必要はありません。理解するのは難しくありません:

コンピュータ プログラミングにおける単体テストは、プログラマーがソース コードの個々の単位が使用に適しているかどうかをテストする、ソフトウェアの検証と検証の方法です。ユニットは、アプリケーションのテスト可能な最小の部分です。手続き型プログラミングでは、ユニットは個々の関数またはプロシージャになります。

この内容はWikipediaから引用しています。つまり、コードのすべての機能に対してテストを作成し、これらのテストがすべて合格すれば、コードにバグがないことが保証されます (主にテストの徹底度に依存します)。

コードをテストする必要がある理由

これまでに単体テストを作成したことがない場合は、コードを Web サイトに直接適用し、しばらくクリックして問題が発生するかどうかを確認し、問題を見つけたら修正してみてください。このアプローチには多くの問題があります。

まず第一に、それは非常に面倒です。すべてがクリックされていることを確認する必要があり、1 つや 2 つ見逃してしまう可能性があるため、クリックすることは実際には簡単な作業ではありません。第二に、テストのために行ったものはすべて再利用可能ではないため、回帰を見つけるのは簡単ではありません。回帰とは何ですか?コードを書いてテストし、見つかったバグを修正してリリースしたと想像してください。その後、ユーザーは新しいバグに関するフィードバックを送信し、いくつかの新機能をリクエストします。コードに戻り、新しいバグを修正し、新しい機能を追加します。次に起こる可能性があるのは、古いバグが再び現れることであり、これは「回帰」と呼ばれます。もう一度クリックする必要があるため、これらの古いバグはもう見つからない可能性が高く、たとえ見つかったとしても、問題の原因が回帰であることがわかるまでにはしばらく時間がかかるでしょう。単体テストを使用すると、バグを見つけるためのテストを作成でき、コードが変更されたら、テストで再度フィルタリングすることができます。リグレッションが発生した場合、一部のテストは確実に失敗しますが、コードのどの部分にエラーが含まれているかが分かるため、簡単に特定できます。何を変更したかがわかっているので、簡単に修正できます。

単体テストのもう 1 つの利点は、特に Web 開発に当てはまります。ブラウザ間の互換性のテストが簡素化されます。別のブラウザでテストを実行するだけで、あるブラウザで問題が発生した場合は、それを修正してテストを再度実行し、他のブラウザでリグレッションが発生しないことを確認できます。すべてのターゲット ブラウザがテストに合格すると、それらがすべてサポートされていることを確認できます。

John Resig のプロジェクトの 1 つである TestSwarm について触れたいと思います。分散化することで、JavaScript 単体テストを次のレベルに引き上げます。これは多くのテストを備えた Web サイトであり、誰でもそこにアクセスしていくつかのテストを実行し、結果をサーバーに返すことができます。このようにして、コードはさまざまなブラウザーやさらにはさまざまなプラットフォームにわたって非常に迅速にテストできます。

QUnit を使用して単体テストを作成する方法

それでは、QUnit を使用して単体テストを作成するにはどうすればよいでしょうか?まず、テスト環境をセットアップする必要があります:

リーリー

ご覧のとおり、ここでは QUnit フレームワークのマネージド バージョンが使用されています。

テストするコードは myProject.js に配置し、テストは myTests.js に挿入する必要があります。これらのテストを実行するには、ブラウザでこの HTML ファイルを開くだけです。次に、いくつかのテストを作成します。

単体テストの構成要素はアサーションです。

アサーションは、コードによって返される結果を予測するステートメントです。予測が間違っている場合、アサーションは失敗し、何かが間違っていたことがわかります。

アサーションを実行するには、アサーションをテスト ケースに入れる必要があります:

リーリー

ここでは、数値が偶数かどうかを検出する関数 isEven を定義します。この関数をテストして、間違った答えが返されないことを確認したいと思います。

まず、テスト ケースを構築する test() を呼び出します。最初のパラメーターは結果に表示される文字列、2 番目のパラメーターはアサーションを含むコールバック関数です。このコールバック関数は、QUnit が実行されると呼び出されます。

5 つのアサーションを作成しましたが、それらはすべてブール値です。ブール アサーションは、最初の引数が true であることを期待します。 2 番目のパラメーターも、結果に表示されるメッセージです。

テストを実行すると、次の結果が得られます:

使用 QUnit 测试 JavaScript 代码:分步指南

由于所有这些断言都已成功通过,我们可以非常确定 isEven() 将按预期工作。

让我们看看如果断言失败会发生什么。

// Let's test this function
function isEven(val) {
	return val % 2 === 0;
}

test('isEven()', function() {
	ok(isEven(0), 'Zero is an even number');
	ok(isEven(2), 'So is two');
	ok(isEven(-4), 'So is negative four');
	ok(!isEven(1), 'One is not an even number');
	ok(!isEven(-7), 'Neither does negative seven');

	// Fails
	ok(isEven(3), 'Three is an even number');
})
ログイン後にコピー

结果如下:

使用 QUnit 测试 JavaScript 代码:分步指南

断言失败是因为我们故意写错了,但在你自己的项目中,如果测试没有通过,并且所有断言都是正确的,你就知道发现了一个bug。

更多断言

ok() 并不是 QUnit 提供的唯一断言。在测试项目时,还有其他类型的断言很有用:

比较断言

比较断言 equals() 期望其第一个参数(即实际值)等于其第二个参数(即期望值)。它与 ok() 类似,但同时输出实际值和期望值,使调试更加容易。与 ok() 一样,它采用可选的第三个参数作为要显示的消息。

所以代替:

test('assertions', function() {
	ok( 1 == 1, 'one equals one');
})
ログイン後にコピー

使用 QUnit 测试 JavaScript 代码:分步指南

你应该写:

test('assertions', function() {
	equals( 1, 1, 'one equals one');
})
ログイン後にコピー

使用 QUnit 测试 JavaScript 代码:分步指南

注意最后一个“1”,这是比较值。

如果值不相等:

test('assertions', function() {
	equals( 2, 1, 'one equals one');
})
ログイン後にコピー

使用 QUnit 测试 JavaScript 代码:分步指南

它提供了更多信息,使生活变得更加轻松。

比较断言使用“==”来比较其参数,因此它不处理数组或对象比较:

test('test', function() {
	equals( {}, {}, 'fails, these are different objects');
	equals( {a: 1}, {a: 1} , 'fails');
	equals( [], [], 'fails, there are different arrays');
	equals( [1], [1], 'fails');
})
ログイン後にコピー

为了测试这种相等性,QUnit 提供了另一种断言:相同断言

相同的断言

相同的断言,same(),需要与 equals() 相同的参数,但它是一个深度递归比较断言,不仅适用于基本类型,还适用于数组和对象。在前面的示例中,如果将断言更改为相同的断言,它们将全部通过:

test('test', function() {
	same( {}, {}, 'passes, objects have the same content');
	same( {a: 1}, {a: 1} , 'passes');
	same( [], [], 'passes, arrays have the same content');
	same( [1], [1], 'passes');
})
ログイン後にコピー

请注意,same() 在可能的情况下使用“===”进行比较,因此在比较特殊值时它会派上用场:

test('test', function() {
	equals( 0, false, 'true');
	same( 0, false, 'false');
	equals( null, undefined, 'true');
	same( null, undefined, 'false');
})
ログイン後にコピー

构建你的断言

将所有断言放在一个测试用例中是一个非常糟糕的主意,因为它很难维护,并且不会返回干净的结果。您应该做的是构建它们,将它们放入不同的测试用例中,每个测试用例都针对单一功能。

您甚至可以通过调用模块函数将测试用例组织到不同的模块中:

module('Module A');
test('a test', function() {});
test('an another test', function() {});

module('Module B');
test('a test', function() {});
test('an another test', function() {});
ログイン後にコピー

使用 QUnit 测试 JavaScript 代码:分步指南

异步测试

在前面的示例中,所有断言都是同步调用的,这意味着它们依次运行。在现实世界中,还有很多异步函数,例如ajax调用或setTimeout()和setInterval()调用的函数。我们如何测试这些类型的功能? QUnit 提供了一种特殊的测试用例,称为“异步测试”,专门用于异步测试:

我们先尝试用常规的方式来写:

test('asynchronous test', function() {
	setTimeout(function() {
		ok(true);
	}, 100)
})
ログイン後にコピー

使用 QUnit 测试 JavaScript 代码:分步指南

看到了吗?就好像我们没有写任何断言一样。这是因为断言是异步运行的,当它被调用时,测试用例已经完成。

这是正确的版本:

test('asynchronous test', function() {
	// Pause the test first
	stop();
	
	setTimeout(function() {
		ok(true);

		// After the assertion has been called,
		// continue the test
		start();
	}, 100)
})
ログイン後にコピー

使用 QUnit 测试 JavaScript 代码:分步指南

在这里,我们使用 stop() 暂停测试用例,调用断言后,我们使用 start() 继续。

调用 test() 后立即调用 stop() 是很常见的;所以QUnit提供了一个快捷方式:asyncTest()。您可以像这样重写前面的示例:

asyncTest('asynchronous test', function() {
	// The test is automatically paused
	
	setTimeout(function() {
		ok(true);

		// After the assertion has been called,
		// continue the test
		start();
	}, 100)
})
ログイン後にコピー

有一点需要注意:setTimeout() 将始终调用其回调函数,但如果它是自定义函数(例如 ajax 调用)怎么办?您如何确定回调函数将被调用?如果不调用回调,则不会调用 start(),整个单元测试将挂起:

使用 QUnit 测试 JavaScript 代码:分步指南

所以这就是你要做的:

// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

test('asynchronous test', function() {
	// Pause the test, and fail it if start() isn't called after one second
	stop(1000);
	
	ajax(function() {
		// ...asynchronous assertions

		start();
	})
})
ログイン後にコピー

您将超时传递给 stop(),它告诉 QUnit,“如果在该超时后未调用 start(),则该测试应该失败。”您可以确信整个测试不会挂起,并且如果出现问题您将会收到通知。

多个异步函数怎么样?你把start()放在哪里?你把它放在setTimeout()中:

// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

test('asynchronous test', function() {
	// Pause the test
	stop();
	
	ajax(function() {
		// ...asynchronous assertions
	})

	ajax(function() {
		// ...asynchronous assertions
	})

	setTimeout(function() {
		start();
	}, 2000);
})
ログイン後にコピー

超时应该足够长,以允许在测试继续之前调用两个回调。但是如果其中一个回调没有被调用怎么办?你怎么知道这一点?这就是expect() 发挥作用的地方:

// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

test('asynchronous test', function() {
	// Pause the test
	stop();

	// Tell QUnit that you expect three assertions to run
	expect(3);

	ajax(function() {
		ok(true);
	})

	ajax(function() {
		ok(true);
		ok(true);
	})

	setTimeout(function() {
		start();
	}, 2000);
})
ログイン後にコピー

你向expect()传递一个数字来告诉QUnit你期望运行X个断言,如果其中一个断言没有被调用,数字将不匹配,并且你会被通知有事情发生错了。

expect() 还有一个快捷方式:只需将数字作为第二个参数传递给 test() 或 asyncTest():

// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

// Tell QUnit that you expect three assertion to run
test('asynchronous test', 3, function() {
	// Pause the test
	stop();

	ajax(function() {
		ok(true);
	})

	ajax(function() {
		ok(true);
		ok(true);
	})

	setTimeout(function() {
		start();
	}, 2000);
})
ログイン後にコピー

结论

这就是开始使用 QUnit 所需了解的全部内容。单元测试是在发布代码之前测试代码的好方法。如果您之前没有编写过任何单元测试,那么现在就开始吧!感谢您的阅读!

  • 在 Twitter 上关注我们,或订阅 Nettuts+ RSS Feed 以获取网络上最好的 Web 开发教程。

以上がQUnit を使用した JavaScript コードのテスト: ステップバイステップ ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? 独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? Mar 18, 2025 pm 03:12 PM

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? Mar 18, 2025 pm 03:14 PM

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:16 PM

この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:17 PM

この記事では、ソースマップを使用して、元のコードにマッピングすることにより、Minified JavaScriptをデバッグする方法について説明します。ソースマップの有効化、ブレークポイントの設定、Chrome DevtoolsやWebpackなどのツールの使用について説明します。

Javaのコレクションフレームワークを効果的に使用するにはどうすればよいですか? Javaのコレクションフレームワークを効果的に使用するにはどうすればよいですか? Mar 13, 2025 pm 12:28 PM

この記事では、Javaのコレクションフレームワークの効果的な使用について説明します。 データ構造、パフォーマンスのニーズ、スレッドの安全性に基づいて、適切なコレクション(リスト、セット、マップ、キュー)の選択を強調しています。 コレクションの使用を効率的に最適化します

初心者向けのタイプスクリプト、パート2:基本データ型 初心者向けのタイプスクリプト、パート2:基本データ型 Mar 19, 2025 am 09:10 AM

エントリーレベルのタイプスクリプトチュートリアルをマスターしたら、TypeScriptをサポートするIDEで独自のコードを作成し、JavaScriptにコンパイルできるはずです。このチュートリアルは、TypeScriptのさまざまなデータ型に飛び込みます。 JavaScriptには、NULL、未定義、ブール値、数字、文字列、シンボル(ES6によって導入)とオブジェクトの7つのデータ型があります。 TypeScriptはこれに基づいてより多くのタイプを定義し、このチュートリアルではすべてを詳細に説明します。 ヌルデータ型 JavaScriptのように、Typescriptのnull

chart.js:パイ、ドーナツ、バブルチャートを始めます chart.js:パイ、ドーナツ、バブルチャートを始めます Mar 15, 2025 am 09:19 AM

このチュートリアルでは、chart.jsを使用してパイ、リング、およびバブルチャートを作成する方法について説明します。以前は、4つのチャートタイプのchart.js:ラインチャートとバーチャート(チュートリアル2)、およびレーダーチャートと極地域チャート(チュートリアル3)を学びました。 パイとリングチャートを作成します パイチャートとリングチャートは、さまざまな部分に分かれている全体の割合を示すのに理想的です。たとえば、パイチャートを使用して、サファリの男性ライオン、女性ライオン、若いライオンの割合、または異なる候補者が選挙で受け取る票の割合を示すことができます。 パイチャートは、単一のパラメーターまたはデータセットの比較にのみ適しています。パイチャートのファンの角度はデータポイントの数値サイズに依存するため、パイチャートは値のあるエンティティをゼロ値で描画できないことに注意してください。これは、割合がゼロのエンティティを意味します

See all articles