RSS
 

QUnit, 一款JavaScript单元测试框架

12 Oct

QUnit是jQuery支持的一款JavaScript单页测试框架。简单易用。可以从QUnit的Github页面获取其代码。QUnit的使用与JUnit类似,相信有JUnit经验的开发者和测试人员可以很快上手。

开始写测试用例

  • test( name, expected, test )
    一个常规的测试用例。test里是测试用例的具体内容。
  • asyncTest( name, expected, test )
    一个异步测试用例。默认的test都是同步的。内容中必须显示地调用start(),测试才会开始。
  • expect( amount )
    用于测试代码中,表示在本测试里期待会执行amount个断言,大于或少于这个数量,测试都将失败。
  • module( name, lifecycle )
    定义一个名为name的模块。在可选参数lifecycle中,可以定义模块开始和结束的测试内容。具体见文档。
  • QUnit.init( )
    启动QUnit测试。如果测试在进行中,则会重新启动。基本不用。

QUnit支持的断言

  1. ok( state, message )
    真假断言,state为true则通过。类似于JUnit的assertTrue。
  2. equal( actual, expected, message )
    相等断言,actual和expected相等(==)则通过。类似于JUnit的assertEquals。
  3. notEqual( actual, expected, message )
    不等断言,actual和expected不相等(!=)则通过。类似于JUnit的assertNotEquals。
  4. deepEqual( actual, expected, message )
    递归相等断言,actual和expected全相等(包括其子元素都相等,适用于基本类型,数组和对象)则通过。对于基本类型,相当于strictEqual。
  5. notDeepEqual( actual, expected, message )
    递归不相等断言,actual和expected不全相等(包括其子元素都相等,适用于基本类型,数组和对象)则通过。对于基本类型,相当于notStrictEqual。
  6. strictEqual( actual, expected, message )
    全相等断言,actual和expected全相等(===)则通过。
  7. notStrictEqual( actual, expected, message )
    不全相等断言,actual和expected不全相等(===)则通过。
  8. raises( block, expected, message )
    异常断言,block中抛出异常则通过,expected为可选参数,是所期待抛出异常名的正则表达式。

把QUnit集成到现有工具

QUnit在执行的过程中会调用一系列函数,告知外界运行状况,大家可以覆盖这些函数,达到集成的目的。

  • QUnit.log({ result, actual, expected, message })
    每当断言执行结束后会调用此函数。
  • QUnit.testStart({ name })
    每当一个测试执行开始时会调用此函数。
  • QUnit.testDone({ name, failed, passed, total })
    每当一个测试执行结束后会调用此函数。
  • QUnit.moduleStart({ name })
    每当一个模块执行开始时会调用此函数。
  • QUnit.moduleDone({ name, failed, passed, total })
    每当一个模块执行结束后会调用此函数。
  • QUnit.begin()
    当QUnit开始时会调用此函数。
  • QUnit.done()
    当QUnit结束后会调用此函数。

在后面的实例中,我写了一些覆盖,打印了执行过程。相信有了这些回调函数的帮助,写一个进度条出来也不是难事。

QUnit的过滤器

  • noglobals
    如果勾选,那么如果一个测试中引入了全局变量,则测试会失败。JavaScript中引入全局变量(window的属性)是不推荐的行为。
  • notrycatch
    如果勾选,代码中的try-catch将不会生效,一旦程序中有异常发生,测试即刻终止。

QUnit的一个实例

页面输出如下:

页面全部代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<script src="http://code.jquery.com/jquery-latest.js"></script>
		<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
		<style type="text/css">
			#qunit-logs li {
				font-size: small;
				color: #366097;
			}
		</style>

		<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>

		<script>
			$(document).ready(function() {
				var log = function(message) {
					$('#qunit-logs').append('<li>[' + (new Date()).toLocaleTimeString() + ' ' +  (new Date()).getMilliseconds() + ']' + message + '</li>');
				}

				QUnit.begin = function() {
					log('[begin]');
				}

				QUnit.done = function() {
					log('[done]');
				}

				QUnit.reset = function() {
					log('[reset]');
				}

				QUnit.testStart = function(o) {
					log('[testStart]: ' + o.name);
				}

				QUnit.testDone = function(o) {
					log('[testDone]: ' + o.name + ', total=' + o.total + ', passed=' + o.passed + ', failed=' + o.failed);
				}

				QUnit.moduleStart = function(o) {
					log('[moduleStart]: ' + o.name);
				}

				QUnit.moduleDone = function(o) {
					log('[moduleDone]: ' + o.name + ', total=' + o.total + ', passed=' + o.passed + ', failed=' + o.failed);
				}

				test("a basic test example", function() {
					ok( true, "this test is fine" );
					var value = "hello";
					equal( value, "hello", "We expect value to be hello" );
				});

				module("Module A");

				test("first test within module", function() {
  					ok( true, "all pass" );
				});

				module("Module C");

				test("second test within module", function() {
					ok( true, "all pass" );
				});

				module("Module B");

				test("some other test", function() {
					//expect(1);
					equal( true, false, "failing test" );
					equal( true, true, "passing test" );
				});

				module("Module A");

				test("second test within module", function() {
					ok( true, "all pass" );
				});
			});
		</script>
	</head>
	<body>
		<h1 id="qunit-header">QUnit example</h1>
		<h2 id="qunit-banner"></h2>
		<div id="qunit-testrunner-toolbar"></div>
		<h2 id="qunit-userAgent"></h2>
		<ol id="qunit-tests"></ol>
		<div id="qunit-fixture">test markup, will be hidden</div>
		<ul id="qunit-logs"></ul>
	</body>
</html>
 
 

Fancybox

28 Sep

jQuery插件fancybox

  • Can display images, HTML elements, SWF movies, Iframes and also Ajax requests
  • Customizable through settings and CSS
  • Groups related items and adds navigation.
  • If the mouse wheel plugin is included in the page then FancyBox will respond to mouse wheel events as well
  • Support fancy transitions by using easing plugin
  • Adds a nice drop shadow under the zoomed item

Note.

 

折腾:Macbook Pro装SSD及光驱位改装硬盘盒

29 Aug

今天订的货终于到齐了。折腾一下,很顺利,记录如下:
我的目标:给Macbook装SSD,同时把原来的硬盘装在Macbook光驱位置,原来的光驱装在外置光盘盒里。

1. 拆后盖:

(1) 准备合适的家伙,后盖的螺丝虽然是十字的,但是比较细小,换内存换硬盘你会频繁打开它们,要保护好。
(2) 经常用的Macbook,环境状况不好的话,里面会有超级多的灰,打开前要有心理准备。
(3) 我把螺丝按拆下来位置摆成这样了。

2. 拆光驱:

(1) 到底把SSD盘装在原来的硬盘位,还是Optibay光驱位呢?建议装在Optibay位,因为Macbook硬盘位是有跌落保护的,因此在这里装机械硬盘能起到保护的效果。我这里是因为之前已经把SSD装在硬盘位,加上对这块Optibay硬盘改装盒并不太信任的缘故。
(2) 你可能会发现大量的灰,建议好好清理干净。不建议用卫生纸直接擦,导致大量静电产生。最好用吹的。
(3) 为了顺利拆下光驱,首先你要把盖在光驱上的那个条线连接在主板的一边向上拉起,并把右下黑色的无线模块两颗螺丝松开,向下掀起。不需要完全拆下。
(4) 光驱一共由3个螺丝固定,左,右上,右下。

3. 转移光驱的固定架:

(1) 所谓光驱固定架,就是上面光驱边上突出来的那块金属,由两颗螺丝固定在光驱上。这里要拆下,转移到Optibay硬盘改装盒的相同位置上。
(2) 建议购买Macbook专用的Optibay硬盘改装盒,不然有可能改装盒上没有这两个开孔。

4. 把Optibay硬盘改装盒装到光驱位置

(1) 顺序和拆的顺序相反,很简单了。

5. 盖上后盖完成

(1) 这里我没急着把螺丝拧回去。但还是盖上后盖再开机,这样可以不破坏电磁屏蔽。
(2) 开机按Option有五个分区,我们成功了。

6. 外置光驱

(1) 我买的是一个套装,带一个USB 2.0的外置光驱盒,可以把拆出来的光驱装进去。

全部完成之后,下图是SSD的固态盘速度测试:

下图是装在OptiBay上的HDD硬盘速度测试:

下图是接在外置盒里的光驱:

找了张Mac安装盘,这是张D9双层盘,顺利读取:

 

如何使Mac OS X Lion 10.7.1支持SSD的TRIM技术

26 Aug

在默认情况下,10.6.4以后的Mac OS X只对苹果自家或者预置在Air等产品里的SSD硬盘开启TRIM技术。
TRIM技术的基本原理是,当有文件被删除时,操作系统会发给SSD一个指令,使得SSD在空闲的时候清除被删除文件所占用的存储单元。如果TRIM没有开启,那么SSD会在存储单元再次被使用时,先清除内容,再执行写入。这个区别在于传统硬盘和SSD硬盘的实现方式上。对于传统硬盘来说,写一个数据块的时候,数据块是否有内容是无所谓的,既不会减慢写入速度也不会影响其寿命,而SSD则不然,从底层实现来看,写一个新块,比写一个包含内容的块要慢,而且长期会导致SSD存储单元寿命下降。因此在SSD硬盘上使用TRIM,会提升其写操作速度,及延长SSD硬盘寿命。

具体的开启方法可见这篇博客
我翻译之后把步骤写在这里,如何打开SSD的TRIM支持:

1. 备份原来的IOAHCIBlockStorage:

打开终端(Terminal),输入以下指令(可能需要输入密码):

sudo cp /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage /IOAHCIBlockStorage.original

这一步把系统原来的IOAHCIBlockStorage备份到了磁盘根目录/处。

2. 开启TRIM

sudo perl -pi -e ‘s|(\x52\x6F\x74\x61\x74\x69\x6F\x6E\x61\x6C\x00).{9}(\x00\x51)|$1\x00\x00\x00\x00\x00\x00\x00\x00\x00$2|sg’ /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

这一步更改了IOAHCIBlockStorage内容,打开TRIM。

3. 重启系统

如果一切正常,重启之后TRIM就已经被打开。

以下是恢复步骤:
如果你想关闭TRIM,执行以下命令:

sudo perl -pi -e ‘s|(\x52\x6F\x74\x61\x74\x69\x6F\x6E\x61\x6C\x00).{9}(\x00\x51)|$1\x41\x50\x50\x4C\x45\x20\x53\x53\x44$2|sg’ /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

实在不行,你可以恢复到之前备份的IOAHCIBlockStorage:

sudo cp /IOAHCIBlockStorage.original /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

开启TRIM之后,系统信息显示为:

注意下面的“TRIM Support”已经显示为“YES”,说明TRIM已经成功开启了。

机器的其他信息如下:

开启前后速度对比,虽然不明显…

开启前:

开启后:

 

Modernizr: 一款HTML5浏览器功能支持检测工具

17 Aug

Modernizr is a small JavaScript library that detects the availability of native implementations for next-generation web technologies, i.e. features that stem from the HTML5 and CSS3 specifications. Many of these features are already implemented in at least one major browser (most of them in two or more), and what Modernizr does is, very simply, tell you whether the current browser has this feature natively implemented or not.

Modernizr可以帮你检测当前用户的浏览器是否支持特定的HTML5或CSS3特性。这可以帮助你的HTML5应用节省大量的时间和复杂的编码,提供一处标准的使用方法来检测HTML5特性是否可用。

Modernizr提供一个js脚本文件,你只需要引用这个文件,就可以得到一个全局变量Modernizr,读取Modernizr的属性就可以得知特定的HTML5或CSS3是否支持。

最后,Modernizr是MIT-licensed,所以你可以放心地用在各种类型的项目中。

 

凤凰网扑天盖地的广告啊

24 Jun

 
 

推荐服务:Hello Bar

23 Jun

推荐给大家一个国外服务,Hello Bar。可以维护一个通知条在你的网站顶端。