断言

  断言是一个特殊的方法,它执行对它的参数给定的验证,或标识一个错误(通常抛出一个类似AssertionError 异常),或什么也不做。简单的断言是它期望参数是“真”。断言通常也可接受一个在失败时用于显示的消息。

  [javascript] view plaincopy1. assert("Small date difference expected '3 days, 2 hours, 16 minutes and " +

  2. "10 seconds ago' got '" + 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文件也是有一点工作量的。