测试驱动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提供的更多些。本文主要目地在于抛砖引玉,向大家介绍测试框架中相关方法大致的实现方式,以及如何使用测试框架进行单元测试。要想更好的精通单元测试,除了继续加强理论知识的学习、不断的实践之外,还可以看看其他框架的源代码,相信对你定会有比较大的帮助。

目录
相关文章
|
17天前
|
测试技术 开发者 UED
探索软件测试的深度:从单元测试到自动化测试
【10月更文挑战第30天】在软件开发的世界中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的不同层次,从基本的单元测试到复杂的自动化测试,揭示它们如何共同构建一个坚实的质量保证体系。我们将通过实际代码示例,展示如何在开发过程中实施有效的测试策略,以确保软件的稳定性和可靠性。无论你是新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
1月前
|
测试技术 网络安全
什么是软件测试? 软件测试都有什么岗位 ?软件测试和调试的区别? 软件测试和开发的区别? 一位优秀的测试人员应该具备哪些素质? 软件测试等相关概念入门篇
文章全面介绍了软件测试的基本概念、目的、岗位分类、与开发和调试的区别,并阐述了成为优秀测试人员应具备的素质和技能。
184 1
什么是软件测试? 软件测试都有什么岗位 ?软件测试和调试的区别? 软件测试和开发的区别? 一位优秀的测试人员应该具备哪些素质? 软件测试等相关概念入门篇
|
8天前
|
安全 测试技术 持续交付
云计算时代的软件开发与测试:高效、灵活、可扩展
云计算时代的软件开发与测试:高效、灵活、可扩展
|
1月前
|
人工智能 监控 测试技术
云应用开发平台测试
云应用开发平台测试
49 2
|
1月前
|
测试技术 Python
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
本文介绍了使用Python的unittest框架来加载测试用例的四种方法,包括通过测试用例类、模块、路径和逐条加载测试用例。
62 0
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
|
2月前
|
测试技术
测试用例设计方法之基本路径测试法
基本路径测试法是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法,设计出的测试用例要保证在测试中程序的语句覆盖100%,条件覆盖100%
115 7
测试用例设计方法之基本路径测试法
|
1月前
|
敏捷开发 测试技术
开发模型(瀑布、螺旋、scrum) 和 测试模型(V、W)、增量和迭代、敏捷(思想)及敏捷开发 scrum
文章详细介绍了软件开发过程中的不同开发模型(瀑布、螺旋、Scrum)和测试模型(V模型、W模型),以及增量和迭代的概念,最后阐述了敏捷思想及其在敏捷开发(如Scrum)中的应用。
67 0
开发模型(瀑布、螺旋、scrum) 和 测试模型(V、W)、增量和迭代、敏捷(思想)及敏捷开发 scrum
|
2月前
|
测试技术 持续交付 UED
软件测试的艺术与科学:平衡创新与质量的探索在软件开发的波澜壮阔中,软件测试如同灯塔,指引着产品质量的方向。本文旨在深入探讨软件测试的核心价值,通过分析其在现代软件工程中的应用,揭示其背后的艺术性与科学性,并探讨如何在追求技术创新的同时确保产品的高质量标准。
软件测试不仅仅是技术活动,它融合了创造力和方法论,是软件开发过程中不可或缺的一环。本文首先概述了软件测试的重要性及其在项目生命周期中的角色,随后详细讨论了测试用例设计的创新方法、自动化测试的策略与挑战,以及如何通过持续集成/持续部署(CI/CD)流程优化产品质量。最后,文章强调了团队间沟通在确保测试有效性中的关键作用,并通过案例分析展示了这些原则在实践中的应用。
73 1
|
2月前
|
IDE 测试技术 持续交付
Python自动化测试与单元测试框架:提升代码质量与效率
【9月更文挑战第3天】随着软件行业的迅速发展,代码质量和开发效率变得至关重要。本文探讨了Python在自动化及单元测试中的应用,介绍了Selenium、Appium、pytest等自动化测试框架,以及Python标准库中的unittest单元测试框架。通过详细阐述各框架的特点与使用方法,本文旨在帮助开发者掌握编写高效测试用例的技巧,提升代码质量与开发效率。同时,文章还提出了制定测试计划、持续集成与测试等实践建议,助力项目成功。
85 5
|
2月前
|
测试技术 数据库
『软件测试2』 关于黑盒测试和测试用例的基础知识
该文章讲解了黑盒测试的基本概念以及如何编写有效的测试用例,包括选择合适的输入数据、预期结果的设定和测试执行的步骤。

热门文章

最新文章

下一篇
无影云桌面