python单元测试简介

本文探讨了在JavaScript中对既有代码进行单元测试的挑战,包括如何重构混合在HTML中的代码以便测试。通过实例展示了如何从头开始进行单元测试,使用QUnit框架,并通过重构提高代码可测试性。最后,文章强调了测试对于改进代码设计的重要性。
摘要由CSDN通过智能技术生成

您可能知道测试很好,但是在尝试为客户端代码编写单元测试时要克服的第一个障碍是缺少任何实际的单元。JavaScript代码是为网站的每个页面或应用程序的每个模块编写的,并与后端逻辑和相关的HTML紧密混合。在最坏的情况下,代码会与HTML完全混合在一起,作为内联事件处理程序。

当没有使用用于某些DOM抽象的JavaScript库时,可能会出现这种情况;编写内联事件处理程序比使用DOM API绑定那些事件要容易得多。越来越多的开发人员正在使用诸如jQuery之类的库来处理DOM抽象,从而使他们可以将这些内联事件移动到同一页面甚至单独的JavaScript文件中的不同脚本中。但是,将代码放入单独的文件并不意味着它可以作为一个单元进行测试。

单位是什么?在最好的情况下,它是一个纯函数,您可以通过某种方式进行处理-对于给定的输入,该函数始终会为您提供相同的结果。这使单元测试非常容易,但是大多数时候您需要处理副作用,这在这里意味着DOM操作。弄清楚我们可以将代码构建到哪些单元中并相应地构建单元测试,仍然很有用。

建筑单元测试

考虑到这一点,我们显然可以说,从头开始时,从单元测试开始要容易得多。但这不是本文的目的。本文旨在帮助您解决更棘手的问题:提取现有代码并测试重要部分,潜在地发现和修复代码中的错误。

在不修改其当前行为的情况下提取代码并将其放入其他形式的过程称为重构。重构是一种改进程序代码设计的出色方法。并且由于任何更改实际上都可能会修改程序的行为,因此在进行单元测试时最安全的做法是。

这个“鸡与蛋”问题意味着要将测试添加到现有代码中,您必须承担破坏程序的风险。因此,除非您对单元测试有足够的了解,否则需要继续手动测试以最大程度地降低这种风险。

就目前而言,这应该已经足够了。让我们看一个实际的示例,测试一些当前与页面混合并连接到页面的JavaScript代码。该代码查找具有title属性的链接,并使用这些标题显示发布时间(例如“ 5天前”)作为相对时间值:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Mangled date examples</title>
  <script>
  function prettyDate(time){
    var date = new Date(time || ""),
      diff = (((new Date()).getTime() - date.getTime()) / 1000),
      day_diff = Math.floor(diff / 86400);
 
    if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
      return;
 
    return day_diff == 0 && (
        diff < 60 && "just now" ||
        diff < 120 && "1 minute ago" ||
        diff < 3600 && Math.floor( diff / 60 ) +
          " minutes ago" ||
        diff < 7200 && "1 hour ago" ||
        diff < 86400 && Math.floor( diff / 3600 ) +
          " hours ago") ||
      day_diff == 1 && "Yesterday" ||
      day_diff < 7 && day_diff + " days ago" ||
      day_diff < 31 && Math.ceil( day_diff / 7 ) +
        " weeks ago";
  }
  window.onload = function() {
    var links = document.getElementsByTagName("a");
    for ( var i = 0; i < links.length; i++ ) {
      if ( links[i].title ) {
        var date = prettyDate(links[i].title);
        if ( date ) {
          links[i].innerHTML = date;
        }
      }
    }
  };
  </script>
</head>
<body>
 
<ul>
  <li class="entry">
    <p>blah blah blah...</p>
    <small class="extra">
      Posted <span class="time">
        <a href="#2008/01/blah/57/" title="2008-01-28T20:24:17Z">
          <span>January 28th, 2008</span>
        </a>
      </span>
      by <span class="author"><a href="#john/">John Resig</a></span>
    </small>
  </li>
  
</ul>
 
</body>
</html>

如果运行该示例,将会看到一个问题:所有日期都不会被替换。该代码有效。它遍历页面上的所有锚,并title在每个锚上检查属性。如果存在,则将其传递给prettyDate函数。如果prettyDate返回结果,则使用结果更新innerHTML链接的。

使事物可测试

问题在于,对于任何早于31天的日期,它prettyDate只会返回未定义的(隐式地,只有一条return语句),而锚点的文本保持不变。因此,要了解应该发生什么,我们可以对“当前”日期进行硬编码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Mangled date examples</title>
  <script>
  function prettyDate(now, time){
    var date = new Date(time || ""),
      diff = (((new Date(now)).getTime() - date.getTime()) / 1000),
      day_diff = Math.floor(diff / 86400);
 
    if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
      return;
 
    return day_diff == 0 && (
        diff < 60 && "just now" ||
        diff < 120 && "1 minute ago" ||
        diff < 3600 && Math.floor( diff / 60 ) +
          " minutes ago" ||
        diff < 7200 && "1 hour ago" ||
        diff < 86400 && Math.floor( diff / 3600 ) +
          " hours ago") ||
      day_diff == 1 && "Yesterday" ||
      day_diff < 7 && day_diff + " days ago" ||
      day_diff < 31 && Math.ceil( day_diff / 7 ) +
        " weeks ago";
  }
  window.onload = function() {
    var links = document.getElementsByTagName("a");
    for ( var i = 0; i < links.length; i++ ) {
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软件测试test

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值