测试驱动javascript开发 -- 2.单元测试一例:学习断言、测试用例函数的编写

简介:   本篇我们将通过对Date.strftime编写单元测试的例子,学会断言、测试用例函数的相关知识。   首先我们先来看Date.strftime的实现代码。 Date.prototype.strftime = (function () {   function strftime(form...

  本篇我们将通过对Date.strftime编写单元测试的例子,学会断言、测试用例函数的相关知识。

  首先我们先来看Date.strftime的实现代码。

Date.prototype.strftime = (function () {
  function strftime(format) {
    var date = this;
    return (format + "").replace(/%([a-zA-Z])/g,
      function (m, f) {
        var formatter = Date.formats && Date.formats[f];
        if (typeof formatter == "function") {
          return formatter.call(Date.formats, date);
        } else if (typeof formatter == "string") {
          return date.strftime(formatter);
        }
        return f;
      });
  }
  // 内部帮助函数
  function zeroPad(num) {
    return (+num < 10 ? "0" : "") + num;
  }
  Date.formats = {
    // Formatting 方法
    d: function (date) {
      return zeroPad(date.getDate());
    },
    m: function (date) {
      return zeroPad(date.getMonth() + 1);
    },
    y: function (date) {
      return zeroPad(date.getYear() % 100);
    },
    Y: function (date) {
      return date.getFullYear();
    },
    // Format 速记方式
    F: "%Y-%m-%d",
    D: "%m/%d/%y"
  };
  return strftime;
}());

  Date.prototype.strftime函数整体是一个即时匿名函数,该函数会自动执行,把strftime函数作为结果返回。strftime()通过正则表的式判断格式化标示符,返回正确的结果。 zeroPad()在1-9的数据前加0 。Date.formats 对象提供一系列辅助方法,用来处理时间。

  如果代码有哪里看不懂可以给我留言,我会尽量讲解。

 

  断言

  单元测试的核心是断言,通过它的自动运行来比较开发者对于系统的预期结果是否和执行结果一致。两者一致则说明我们的系统一切正常,否则就存在问题,需要我们进一步确认。我们先来看一个简单的断言函数:

function assert(message, expr) {
  if (!expr) {
    throw new Error(message);
  }
  assert.count++;
  return true;
}
assert.count = 0;

  上面的函数只是简单的验证第二个参数是否是真值(除了false, null, undefined, 0, "", 和 NaN这些值之外的都可以)。断言成功,assert.count会加1,失败则抛出异常。

  我们可以使用他来测试strftime() 方法。

var date = new Date(2009, 9, 2);
try {
  assert("%Y should return full year", date.strftime("%Y") === "2009");
  assert("%m should return month", date.strftime("%m") === "10");
  assert("%d should return date", date.strftime("%d") === "02");
  assert("%y should return year as two digits", date.strftime("%y") === "09");
  assert("%F should act as %Y-%m-%d", date.strftime("%F") === "2009-10-02");
  console.log(assert.count + " tests OK");
} catch (e) {
  console.log("Test failed: " + e.message);
}

  在自动化测试中,我们经常使用绿色代表成功,红色代表失败。我们可以创建一个output方法输出不同颜色的信息条,代替console.log的功能。

function output(text, color) {
  var p = document.createElement("p");
  p.innerHTML = text;
  p.style.color = color;
  document.body.appendChild(p);
}
// 可以用它来代替上面断言例子中的 console.log
output(assert.count + " tests OK", "#0c0");
// 失败的时候使用下面的方法:
output("Test failed: " + e.message, "#c00");

 

  测试用例函数

  在创建断言函数之后,我们需要创建测试用例函数,以便把断言组织起来。测试用例里面包含很多子的测试方法,每个测试方法针对被测对象的一部分行为进行测试。下面我们看一个简单的测试用例函数的实现,其中name是测试用例的名称,tests是一组测试方法,其中每个测试方法以‘test’开头。

function testCase(name, tests) {
  assert.count = 0;
  var successful = 0;
  var testCount = 0;
  
for (var test in tests) {     if (!/^test/.test(test)) {       continue;     }
    testCount
++;
    
try {       tests[test]();       output(test, "#0c0");       successful++;     } catch (e) {       output(test + " failed: " + e.message, "#c00");     }   }
  
var color = successful == testCount ? "#0c0" : "#c00";   output("<strong>" + testCount + " tests, " + (testCount - successful) + " failures</strong>", color); }

  下面我们使用上面的方法测试strftime()。

var date = new Date(2009, 9, 2);
testCase("strftime test", {
  "test format specifier %Y": function () {
    assert("%Y should return full year", date.strftime("%Y") === "2009");
  },
  "test format specifier %m": function () {
    assert("%m should return month", date.strftime("%m") === "10");
  },
  "test format specifier %d": function () {
    assert("%d should return date", date.strftime("%d") === "02");
  },
  "test format specifier %y": function () {
    assert("%y should return year as two digits", date.strftime("%y") === "09");
  },
  "test format shorthand %F": function () {
    assert("%F should act as %Y-%m-%d", date.strftime("%F") === "2009-10-02");
  }
});

  这组测试方法针对strftime()不同功能点进行测试,组合起来实现了对其全部功能的测试,最后把测试结果展现给用户。可以说效果还是相当不错的。

  Setup 和 Teardown

  接下来我们介绍setup()和teardown()方法的实现。这两个方法分别在tests执行之前和之后运行,setup()可以用来初始化测试条件,teardown()可以用来销毁相关条件。下面我们完善之前的testCase()方法,添加对setup和teardown()的支持。

function testCase(name, tests) {
  assert.count = 0;
  var successful = 0;
  var testCount = 0;
  var hasSetup = typeof tests.setUp == "function";
  var hasTeardown = typeof tests.tearDown == "function";
  for (var test in tests) {
    if (!/^test/.test(test)) {
      continue;
    }
    testCount++;
    try {
      if (hasSetup) {
        tests.setUp();
      }
      tests[test]();
      output(test, "#0c0");
      if (hasTeardown) {
        tests.tearDown();
      }
      successful++;
    } catch (e) {
      output(test + " failed: " + e.message, "#c00");
    }
  }
  var color = successful == testCount ? "#0c0" : "#c00";
  output("<strong>" + testCount + " tests, " + (testCount - successful) + " failures</strong>", color);
}

  下面我们用改进后的testCase()重新测试strftime()方法。

testCase("strftime test", {
  setUp: function () {
    this.date = new Date(2009, 9, 2, 22, 14, 45);
  },
  "test format specifier Y": function () {
    assert("%Y should return full year", this.date.strftime("%Y") == 2009);
  },
  // ...
});

 

  总结

  本文提供的断言和测试用例函数比较简单,相信大家一看就会,其他复杂的测试框架则要相对复杂的多。但是他们在基本原理上没有太大差别,只是代码实现方式不同,再者就是api提供的更多些。本文主要目地在于抛砖引玉,向大家介绍测试框架中相关方法大致的实现方式,以及如何使用测试框架进行单元测试。要想更好的精通单元测试,除了继续加强理论知识的学习、不断的实践之外,还可以看看其他框架的源代码,相信对你定会有比较大的帮助。

adpics.aspx?source=kbh1983&sourcesuninfo
目录
相关文章
|
17天前
|
消息中间件 Java 数据库
【消息队列开发】 实现 VirtualHostTests 类——测试虚拟主机操作
【消息队列开发】 实现 VirtualHostTests 类——测试虚拟主机操作
|
17天前
|
消息中间件 存储 测试技术
【消息队列开发】 实现MemoryDataCenterTests类——测试管理内存数据
【消息队列开发】 实现MemoryDataCenterTests类——测试管理内存数据
|
23天前
|
机器学习/深度学习 人工智能 自然语言处理
探索软件测试的未来:AI 驱动的自动化测试方法
【5月更文挑战第29天】随着人工智能(AI)技术的不断发展和成熟,其在软件测试领域的应用也日益广泛。本文旨在探讨 AI 如何改变软件测试的面貌,特别是自动化测试方法。我们将分析当前自动化测试的挑战,并介绍 AI 如何提供解决方案,包括智能化测试用例生成、测试执行优化、以及结果分析等。通过实际案例研究,我们还将讨论 AI 在提高测试效率、减少错误和提升软件质量保障中的作用。最后,文章将预测 AI 在自动化测试领域的未来趋势,并提出对测试工程师的建议。
|
2天前
|
JSON Java 测试技术
SpringBoot实用开发篇第二章(测试操作)
SpringBoot实用开发篇第二章(测试操作)
|
17天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的新时代:AI驱动的自动化
【6月更文挑战第4天】随着人工智能技术的不断进步,软件测试领域正经历着一场革命。本文将探讨AI如何改变传统的软件测试方法,提高测试效率和准确性,以及这一趋势对测试工程师未来技能要求的影响。
23 6
|
20天前
|
机器学习/深度学习 人工智能 安全
探索软件测试的新时代:AI驱动的测试自动化
本文深入探讨了人工智能(AI)如何革新软件测试领域,特别是测试自动化。随着AI技术的不断进步,它为测试自动化带来了前所未有的效率和准确性,从而极大地提高了软件开发的速度和质量。本文将详细介绍AI在软件测试中的应用,以及它如何帮助测试人员克服传统测试方法的局限性。
|
17天前
|
消息中间件 Java 测试技术
【消息队列开发】 测试MessageFileManager(对硬盘中的消息操作)类
【消息队列开发】 测试MessageFileManager(对硬盘中的消息操作)类
|
22天前
|
人工智能 自然语言处理 安全
构建未来:AI驱动的自适应网络安全防御系统提升软件测试效率:自动化与持续集成的实践之路
【5月更文挑战第30天】 在数字化时代,网络安全已成为维护信息完整性、保障用户隐私和企业持续运营的关键。传统的安全防御手段,如防火墙和入侵检测系统,面对日益复杂的网络攻击已显得力不从心。本文提出了一种基于人工智能(AI)技术的自适应网络安全防御系统,该系统能够实时分析网络流量,自动识别潜在威胁,并动态调整防御策略以应对未知攻击。通过深度学习算法和自然语言处理技术的结合,系统不仅能够提高检测速度和准确性,还能自主学习和适应新型攻击模式,从而显著提升网络安全防御的效率和智能化水平。 【5月更文挑战第30天】 在快速迭代的软件开发周期中,传统的手动测试方法已不再适应现代高效交付的要求。本文探讨了如
|
24天前
|
机器学习/深度学习 人工智能 算法
自动化测试中AI驱动的决策框架
【5月更文挑战第28天】 本文探讨了在自动化软件测试过程中,如何利用人工智能(AI)技术来优化测试用例的选择和执行。通过引入一个基于机器学习算法的智能决策框架,我们可以提高测试的效率和有效性,同时减少冗余和不必要的测试活动。与传统的摘要不同,本摘要将直接深入到文章的核心议题,介绍AI在自动化测试中的作用,并指出其在未来的发展趋势。
|
27天前
|
机器学习/深度学习 人工智能 算法
探索自动化测试中AI驱动的决策框架
【5月更文挑战第25天】 在软件测试领域,自动化是提升效率与准确性的关键。随着人工智能(AI)技术的不断进步,其在自动化测试中的应用越来越广泛,特别是在测试决策过程中。本文将探讨一种基于AI的决策框架,它能够实时分析软件质量数据,预测潜在缺陷,并提出优化测试策略的建议。通过引入机器学习算法和数据分析技术,该框架旨在提高测试覆盖率,降低错误检出成本,并最终实现智能、自适应的测试流程。