断言
断言是一个特殊的方法,它执行对它的参数给定的验证,或标识一个错误(通常抛出一个类似AssertionError 异常),或什么也不做。最简单的断言是它期望参数是“真”。断言通常也可接受一个在失败时用于显示的消息。
[javascript] view plaincopy1. assert("Small date difference expected\n '3 days, 2 hours, 16 minutes and " +
2. "10 seconds ago' got\n'" + element.text() + "'",
3. element.text() == "3 days, 2 hours, 16 minutes and 10 seconds ago");
断言以第一个参数为消息。这个主意是要首先说明你的预期,而断言像是用消息来说明(原文:The idea is thattesting is about stating your expectations upfront, and the assertion resemblesa specification with the leading message.)。
你的全部需要通常像上面那个简单断言就能满足,大多的测试框架都附带选择自定义断言的机会。上面我们真正做的就是验证计算值与预期值的对比。绝大多数的测试框架都针对这种情况提供多种重载的assertEquals。(Most testframeworks have something along the lines of assertEquals for thisspecific use case.)
[javascript] view plaincopy1. assertEquals("3 days, 2 hours, 16 minutes and 10 seconds ago", element.text());
注意我们不再指定一个说明。assertEquals 知道我们期望是第二个计算的值和第一个值相等,所以它可以为我们生成一个适当的消息。
测试用例,setUp 和 tearDown
在我们手工的单元测试中,我们有两个独立的测试。当使用测试框架时,通常在一个测试用例中指定为独立的函数。一个测试用例是一组测试相关功能的测试的集合。为了使测试报告更容易查看,测试用例通常都有一个名字。下面的例子使用JsTestDriver测试用例来组织前面我们手工的单元测试。
[javascript] view plaincopy1. var second = 1000;
2. var minute = 60 * second;
3. var hour = 60 * minute;
4. var day = 24 * hour;
5.
6. TestCase("TimeDifferenceInWordsTest", {
7. "test 8 day difference should result in '1 week ago'": function () {
8. var dateStr = new Date(new Date() - 8 * day).toString();
9. var element = jQuery('Replace me');
10. element.differenceInWords();
11.
12. assertEquals("1 week ago", element.text());
13. },
14.
15. "test should display difference with days, hours, minutes and seconds": function () {
16. var diff = 3 * day + 2 * hour + 16 * minute + 10 * second;
17. dateStr = new Date(new Date() - diff).toString();
18. var element = jQuery('Replace me');
19. element.differenceInWords();
20.
21. assertEquals("3 days, 2 hours, 16 minutes and 10 seconds ago", element.text());
22. }
23. });
每个测试之前的注释都转换为测试函数的名称,比较转换为断言。我们甚至可以通过把创建日期对象提取到一个特定的setUp方法调用中来使每个测试更整洁,setUp会在每个测试函数执行之前调用。
[javascript] view plaincopy1. TestCase("TimeDifferenceInWordsTest", {
2. setUp: function () {
3. this.date8DaysAgo = new Date(new Date() - 8 * day);
4. var diff = 3 * day + 2 * hour + 16 * minute + 10 * second;
5. this.date3DaysAgo = new Date(new Date() - diff);
6. },
7.
8. "test 8 day difference should result in '1 week ago'": function () {
9. var element = jQuery('Replace me');
10. element.differenceInWords();
11.
12. assertEquals("1 week ago", element.text());
13. },
14.
15. "test should display difference with days, hours, minutes and seconds": function () {
16. var element = jQuery('Replace me');
17. element.differenceInWords();
18.
19. assertEquals("3 days, 2 hours, 16 minutes and 10 seconds ago", element.text());
20. }
21. });
setUp 方法还有一个对应的tearDown 方法,在每个测试之后执行。这个例子不需要tearDown 方法,但你可以在任何你需要在每个测试之后执行清理时创建一个tearDown 。假想你测试使用localStorage实现缓存一些数据的代码。为了防止测试相互之间干涉,你可能想在每个测试之后清除写进localStorage 中的所有数据。
另外,对代码和测试,你需要指定某种实际运行测试方法。大多的JavaScript单元测试框架需要一个简单的HTML文件来按正确的顺序加载正确的文件(包括测试框架自身)。这个HTML文件然后可以加载到浏览器中。通常所有的测试通过为绿色,有失败的测试时转为有威胁的红色。
自动化,自动化,自动化
通过把基于日志的调试工作转到单元测试,我们确信我们的经验是重复的和自验证的。这样做可节省花费大量的手工劳动,但还有改善的余地。在浏览器中运行包含测试的HTML文件是相当无关痛痒的,但如你注意到的,今天web开发不能在一个浏览器中简单测试就完事。依据你的环境,你可能不得不在至少在3个以上平台的5个以上的浏览器的2个以上最新版本上测试。突然,运行那个HTML文件也是有一点工作量的。