Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
¹ØÓÚǰ¶Ë¿ª·¢Ì¸Ì¸µ¥Ôª²âÊÔ
 
×÷ÕߣºÑîÏþ²¨, ÁÖ±¦´¨, ÌÆÑ§²¨, À´Ô´£ºIBM ·¢²¼ÓÚ 2015-8-6
  2881  次浏览      32
 

µ¥Ôª²âÊÔUnit Test

ºÜÔç¾ÍÖªµÀµ¥Ôª²âÊÔÕâÑùÒ»¸ö¸ÅÄµ«Ö±µ½¼¸¸öÔÂǰ£¬ÎÒÕæÕý¿ªÊ¼½Ó´¥ºÍʹÓÃËü¡£¾¿¾¹Ê²Ã´Êǵ¥Ôª²âÊÔ£¿ÎÒÏëÒ²ÐíºÜ¶àʹÓÃÁ˺ܾõÄÈËÒ²²»Ò»¶¨ÄÜÃèÊöµÄÊ®·ÖÇå³þ£¬ËùÒÔдÁËÕâÆªÎÄÕÂÀ´³¢ÊÔÃèÊöËüµÄÌØÕ÷ºÍÔ­Ôò£¬ÒÔ°ïÖú¸ü¶àÈË¡£

ʲôÊǵ¥Ôª²âÊÔ£¿

ÏÈÀ´¿´¿´µ¥Ôª²âÊԵ͍Ò壬ÔÚά»ù°Ù¿ÆÓ¢ÎİæÖпÉÒÔÕÒµ½Kolawa AdamÔÚ Automated Defect Prevention: Best Practices in Software Management Ò»ÊéÖжԵ¥Ôª²âÊԵ͍Ò壺

In computer programming, unit testing is a method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures are tested to determine if they are fit for use.

ÖØµãÔÚÓÚ×îºó£¬µ¥Ôª²âÊÔµÄÄ¿µÄÏÔ¶øÒ×¼û£¬ÓÃÀ´È·¶¨ÊÇ·ñÊʺÏʹÓ᣶ø²âÊԵķ½·¨Ôò°üÀ¨¿ØÖÆÊý¾Ý£¬Ê¹ÓúͲÙ×÷¹ý³Ì¡£ÄÇôÒÔÎÒµÄÀí½â£¬Ã¿¸öµ¥Ôª²âÊÔ¾ÍÊÇÒ»¶ÎÓÃÓÚ²âÊÔÒ»¸öÄ£¿é»ò½Ó¿ÚÊÇ·ñÄÜ´ïµ½Ô¤ÆÚ½á¹ûµÄ´úÂë¡£¿ª·¢ÈËÔ±ÐèҪʹÓôúÂëÀ´¶¨ÒåÒ»¸ö¿ÉÓõĺâÁ¿±ê×¼£¬²¢ÇÒ¿ÉÒÔ¿ìËÙ¼ìÑé¡£

ºÜ¿ìÎÒ·¢ÏÖÓÐÒ»¸öÎóÇø£¬Ðí¶àÈËÈÏΪµ¥Ôª²âÊÔ±ØÐëÊÇÒ»¸örunner¼¯ÖÐÔËÐÐËùÓе¥ÔªµÄ²âÊÔ£¬²¢Ò»Ä¿ÁËÈ»¡£²»£¬Õâ½ö½öÊÇÒ»ÖÖ×Ô¶¯»¯µ¥Ôª²âÊÔµÄ×î¼Ñʵ¼ù£¬ÔÚһЩСÐÍÏîÄ¿Öе¥Ôª²âÊÔ¿ÉÄܽö½öÊÇÒ»×éÈ¥³ýÆäËûÌØÐԵĽӿڵ÷Óá£ÉõÖÁÔÚһЩͼÐδ¦Àí»ò²¼¾ÖµÄÏîÄ¿Öе¥Ôª²âÊÔ¿ÉÒÔ½áºÏ×ÔÉíÌØÐÔ±äµÄÊ®·ÖÓÐȤ£¬±ÈÈçMasonry£¬Ò»¸öÍø¸ñ²¼¾Ö¿â£¬ÔÚËüµÄµ¥Ôª²âÊÔÖв»ÊÇÒ»¸öºì»òÂ̵ÄÌõÄ¿£¬¶øÊÇÒ»ÐÐÒ»ÐеÄС¸ñ²¼¾ÖÓÃÒÔ˵Ã÷²¼¾Ö±»Íê³ÉµÄÊÂʵ£¬ÕâÑù±È´úÂë¼ì²é²¼¾ÖÊÇ·ñÕýÈ·ÔÙÒÔÑÕÉ«ÏÔʾ½á¹ûÀ´µÃ¸üÖ±¹Û¸ßЧ£¬Ò²±ÜÃâÁ˲âÊÔ³ÌÐò±¾ÉíµÄbugµ¼ÖµÄʧÎó¡£

´ò¸ö±È·½£¬µ¥Ôª²âÊÔ¾ÍÏñÒ»°Ñ³ß×Ó£¬µ±²âÁ¿µÄ¶ÔÏóÊÇÒ»¸öÇúÃæÊ±£¬Ò²Ðí¿ÉÒÔ»¨·Ñ´óÁ¦ÆøÈ¥½«Ëü³éÏó³ÉÆ½Ãæ£¬µ«ÎÒ¸üÌᳫÁ¿Éí¶¨×öÒ»°ÑÍäÇúµÄ³ß×ÓÈ¥ÊÊÓ¦Õâ¸öÇúÃæ¡£ÎÞÂÛÔõÑù£¬µ¥Ôª²âÊÔÊÇΪÁËÉú²ú´úÂë¶øÐ´£¬ËüÓ¦µ±×ã¹»µÄ×ÔÓɱ¼·Å£¬È¥ÊÊÓ¦¸÷ÖÖ¸÷ÑùµÄÉú²ú´úÂë¡£

ΪʲôҪµ¥Ôª²âÊÔ£¿

Ò²Ðí¶¨ÒåÖÐÒѾ­ºÜÇå³þµÄÖ¸Ã÷ÁËÆäÒâÒ壬ȷÈÏij¶Î´úÂë»òÄ£¿é»ò½Ó¿ÚÊÇ·ñÊʺÏʹÓ㬵«ÎÒÏë»áÓиü¶àµÄÈËÈÏΪ£¬Ö±½ÓÔÚ²âÊÔ»·¾³ÖÐʹÓÃÈí¼þ¿ÉÒÔ¸ü¼ÓÈ·±£Èí¼þÊÇ·ñ¿ÉÓᣲ»£¬ÔÚʵ¼ÊʹÓùý³ÌÖлá°éËæ×ÅÒ»´óÅúµÄ¸½´ø²Ù×÷´óÁ¿Ôö¼Ó²âÊÔʱ¼ä£¬²¢ÇÒÎÞ·¨±£Ö¤Æä²âÊÔ¸²¸ÇÂÊ¡£ËùÒÔÎÒÈÏΪµ¥Ôª²âÊÔµÄÄ¿µÄ²¢²»½ö½öÊÇÈ·ÈÏÊÇ·ñ¿ÉÓ㬶øÊǸü¸ßЧ¸üÎȶ¨µÄÈ·ÈÏÆäÊÇ·ñ¿ÉÓá£

Ëæ×ÅÏîÄ¿¹æÄ£µÄÔö¼Ó£¬º¯Êý¡¢·½·¨¡¢±äÁ¿¶¼ÔÚµÝÔö£¬ÓÈÆäÊǽø¶ÈµÄ²»×㣬À´×Ô²úÆ·¾­ÀíµÄѹÁ¦£¬»¹ÓÐQAËù´øÀ´µÄ¸÷ÖÖBug±¨¸æ»áÈÃÔ­±¾Õû½àµÄ´úÂë±äµÃһƬ»ìÂÒ¡£ÎÒÉõÖÁ¼û¹ýͬһ¸ö½Ó¿ÚÒÔ²»Í¬µÄÃû³Æ³öÏÖÔÚ8¸ö²»Í¬µÄ¿ØÖÆÆ÷ÖС£ÕâʱҲÐíÎÒÃÇÊ×ÏÈÏëµ½µÄÊÇÖØ¹¹£¬¿ÉÊǵȵȣ¬ÔÚÖØ¹¹½áÊøÊ±ÎÒÃÇÈçºÎÈ·¶¨ÏîÄ¿½ö½öÊDZ»Öع¹ÁË£¬¶ø²»ÊDZ»¸ÄдÁË£¿´Ëʱµ¥Ôª²âÊÔ½«ÊÇÒ»¸ù¾ÈÃüµ¾²Ý£¬ËüÊÇÒ»¸öºâÁ¿±ê×¼£¬¸æËß¿ª·¢ÈËÔ±Õâô×öÊÇ·ñ½«¸Ä±ä½á¹û¡£

²»½ö½öÊÇÕâÑù¡£Ðí¶àÈËÈÏΪµ¥Ôª²âÊÔ£¬ÉõÖÁÕû¸ö²âÊÔ¶¼ÊÇÔÚ±àÂë½áÊøºóµÄÒ»µÀ¹¤Ðò£¬¶øÐÞ¸´bugÒ²²»¹ýÊÇÔÚ×öÀ¬»øÑÚÂñÒ»ÀàµÄ¹¤×÷¡£µ«²âÊÔÓ¦¸Ã°éËæÕû¸ö±àÂë»òÈí¼þÖÜÆÚ½øÐУ¬»¹Óн«ÔÚºóÃæÌáµ½µÄTDDÕâÑùÓÐȤµÄ¶«Î÷£¬µ¥Ôª²âÊÔ½«³¬Ç°ÓÚ±àÂë¡£ÎÒµÄÒâ˼ÊÇ£¬µ¥Ôª²âÊÔÓ¦¸ÃÊÇÒ»¸ö¿ò¼Ü¡¢±ê×¼£¬¾­³£±»ÐÎÈݱ»½ÅÊּܣ¬Ïñ½¨ÖþÒ»Ñù£¬½ÅÊּܵĸ߶ÈÖÁÉÙÓ¦¸ÃºÍ´óÂ¥¸ß¶È²»ÏàÉÏÏ£¬ÉõÖÁÒ»¿ªÊ¼¾Í´îºÃ½ÅÊּܡ£

ÈçºÎ×öµ¥Ôª²âÊÔ£¿

ŪÇåÁ˵¥Ôª²âÊÔµÄÄ¿µÄºÍÒâÒ壬µ«ÈçºÎ¿ªÊ¼£¿ºÜ¼òµ¥£¬Ê×ÏÈËüÊÇÒ»¸ö¼ìÑ飬ËùÒÔÓ¦¸ÃÖ»ÓÐpass»òfailÁ½ÖÖÇé¿ö¡£¶ø¼ìÑéµÄ¶ÔÏóÓ¦¸ÃÊÇij¸ö½Ó¿Ú»òÄ£¿é£¬ËùÒÔÓ¦¸Ãµ÷ÓÃËü»ñµÃÒ»¸ö½á¹û¡£¼ìÑéÕâ¸ö½á¹û¾ÍÊǵ¥Ôª²âÊԵĻù±¾¶¯×÷£¬¾ÍÄÃÒ»¸ö³ý·¨º¯ÊýÀ´×öÀý×Ó£º

function division (a, b) {
return a / b;
}
var result = division(4, 2);
if (result === 2) {
alert('pass');
} else {
alert('fail');
}

ÏÔÈ»£¬½«»áÌáʾpassͨ¹ý¡£µ«ÊÇÎÊÌâÀ´ÁË£¬Õâ¸ö²âÊÔµÄÓÃÀýÌ«µ¥Ò»ºÍÆÕͨÁË£¬Èç¹ûʹÓÃ0×ö³ýÊýÄØ£¿ÊÇNaN£¿»¹ÊÇInfinity£¿»òÕßÔÚʵ¼ÊʹÓÃʱ£¬²úÆ·ÐèÒªÒ»¸ö0À´´úÌæÕâÑùÒ»¸ö²»·ûºÏÊýѧ¸ÅÄîµÄ½á¹ûÈ¥ÊÊÓ¦±ØÐëΪÊý×ÖÀàÐ͵ÄijÖÖ¼ÆË㣬ÓÚÊÇdivision³öÏÖÁËÒ»¸öbug¡£ÁíÍâµ±¸²¸ÇÂÊÔö¼Ó£¬Ò²Òâζ×ÅÓÃÀýµÄÔö¼Ó£¬ÎÒÃÇÐèÒª°ÑifÌõ¼þÓï¾äÌá³öÀ´×ö³ÉÒ»¸öº¯Êý¶à´Îµ÷Ó᣻¹ÓÐalert·½·¨£¬Èç¹ûÓÃÀýÌ«¶à£¬ÎÒÏàÐÅÄã»áµãÈ·Èϵ㵽ÊÖÈí£¬Ò²Ðí¿ÉÒÔÖ±½ÓÏÔʾÔÚÒ³ÃæÉÏ¡£

ËùÒÔÎÒÌí¼ÓÁËÒ»¸ö¹ØÓÚ³ýÊýΪ0µÄÓÃÀý£¬²¢Öع¹ÁË´úÂ룺

function division (a, b) {
if (b === 0) {
return 0;
} else {
return a / b;
}
}
function matcher (name, result, expect) {
if (result === expect) {
_print(name + '- pass');
} else {
_print(name + '- fail');
}
function _print (str) {
var _bar = document.createElement('p');
_bar.innerText = str;
document.body.appendChild(_bar);
}
}
matcher('normal', division(4, 2), 2);
matcher('zero', division(5, 0), 0);

ÏÖÔÚ¿ÉÒÔʹÓÃmatcher·½·¨Ìí¼ÓÐí¶à²âÊÔÓÃÀý£¬²¢ÇÒ»¹ÄÜΪ¸ÃÓÃÀýÃüÃû£¬ÔÚÒ³ÃæÖÐÖ±½ÓÏÔʾÿ¸öÓÃÀýÊÇ·ñͨ¹ý¡£ÕâÑùÒ»¸ö»ù±¾µÄµ¥Ôª²âÊÔ¾ÍÍê³ÉÁË£¬µ±È»ËüµÄ¸²¸ÇÂÊ»¹Ô¶Ô¶²»¹»£¬ÕâÀï½ö×÷Ϊһ¸öÀý×Ó¡£ÁíÍâΪÁËÌá¸ßЧÂÊ»¹Ó¦¸ÃʹÓÃÑÕÉ«À´±ê¼ÇÊÇ·ñͨ¹ý£¬¿ÉÒÔһĿÁËÈ»¡£

²âÊÔÇý¶¯¿ª·¢

TDDÊÇTest Driven Development µÄËõд£¬Ò²¾ÍÊDzâÊÔÇý¶¯¿ª·¢¡£

ͨ³£´«Í³Èí¼þ¹¤³Ì½«²âÊÔÃèÊöΪÈí¼þÉúÃüÖÜÆÚµÄÒ»¸ö»·½Ú£¬²¢ÇÒÊÇÔÚ±àÂëÖ®ºó¡£µ«Ãô½Ý¿ª·¢´óʦKent BeckÔÚ2003Äê³ö°æÁË Test Driven Development By Example Ò»Ê飬´Ó¶øÈ·Á¢Á˲âÊÔÇý¶¯¿ª·¢Õâ¸öÁìÓò¡£

TDDÐèÒª×ñÑ­ÈçϹæÔò£º

дһ¸öµ¥Ôª²âÊÔÈ¥ÃèÊö³ÌÐòµÄÒ»¸ö·½Ãæ¡£

ÔËÐÐËüÓ¦¸Ã»áʧ°Ü£¬ÒòΪ³ÌÐò»¹È±ÉÙÕâ¸öÌØÐÔ¡£

ΪÕâ¸ö³ÌÐòÌí¼ÓһЩ¾¡¿ÉÄܼòµ¥µÄ´úÂë±£Ö¤²âÊÔͨ¹ý¡£

ÖØ¹¹Õⲿ·Ö´úÂ룬ֱµ½´úÂëûÓÐÖØ¸´¡¢´úÂëÔðÈÎÇåÎú²¢Çҽṹ¼òµ¥¡£

³ÖÐøÖØ¸´ÕâÑù×ö£¬»ýÀÛ´úÂë¡£

ÁíÍ⣬ºâÁ¿ÊÇ·ñʹÓÃÁËTDDµÄÒ»¸öÖØÒª±ê×¼ÊDzâÊÔ¶Ô´úÂëµÄ¸²¸ÇÂÊ£¬¸²¸ÇÂÊÔÚ80%ÒÔÏÂ˵Ã÷Ò»¸öÍŶÓûÓгä·ÖÕÆÎÕTDD£¬µ±È»¸ß¸²¸ÇÂÊÒ²²»ÄÜ˵һ¶¨Ê¹ÓÃÁËTDD£¬Õâ½ö½öÊÇÒ»¸ö²Î¿¼Ö¸±ê¡£

ÔÚÎÒ¿´À´£¬TDDÊÇÒ»ÖÖ¿ª·¢¼¼Êõ£¬¶ø·Ç²âÊÔ¼¼Êõ£¬ËùÒÔËü¶ÔÓÚ´úÂë¹¹½¨µÄÒâÒåÔ¶´óÓÚ´úÂë²âÊÔ¡£Ò²Ðí×îÖյĴúÂëºÍÏÈ¿ª·¢ÔÙ²âÊÔдµÄ²âÊÔ´úÂë»ù±¾Ò»Ö£¬µ«ËüÃÇÈÔÈ»ÊÇÓкܴó²»Í¬µÄ¡£TDD¾ßÓкÜÇ¿µÄÄ¿µÄÐÔ£¬ÔÚÖ±½Ó½á¹ûµÄÖ¸µ¼Ï¿ª·¢Éú²ú´úÂ룬Ȼºó²»¶ÏÎ§ÈÆÕâ¸öÄ¿±êÈ¥¸Ä½ø´úÂ룬ÆäÓÅÊÆÊǸßЧºÍÈ¥ÈßÓàµÄ¡£ËùÒÔÆäÌØµãÓ¦¸ÃÊÇÓÉÐèÇóµÃ³ö²âÊÔ£¬ÓɲâÊÔ´úÂëµÃ³öÉú²ú´úÂë¡£´ò¸ö±È·½¾ÍÏñÊÇ×ÔÐгµµÄÁ½¸öÂÖ×Ó£¬ËäÈ»¶¼ÊÇÔÚÏòͬһ¸ö·½Ïòת¶¯£¬µ«ÊǺóÂÖÊÇÊ©Á¦µÄ£¬´ø¶¯³µ×ÓÏòǰ£¬¶øÇ°ÂÖÊÇÊÜÁ¦µÄ£¬±»ÏòǰµÄ³µ×Ó´ø¶¯¶ø×ª¡£

ÐÐΪÇý¶¯¿ª·¢

ËùνµÄBDDÐÐΪÇý¶¯¿ª·¢£¬¼´Behaviour Driven Development£¬ÊÇÒ»ÖÖеÄÃô½Ý¿ª·¢·½·¨¡£Ëü¸üÇ÷ÏòÓÚÐèÇó£¬ÐèÒª¹²Í¬ÀûÒæÕߵIJÎÓ룬ǿµ÷Óû§¹ÊÊ£¨User Story£©ºÍÐÐΪ¡£2009Ä꣬ÔÚÂ×¶Ø·¢±íµÄ¡°Ãô½Ý¹æ¸ñ£¬BDDºÍ¼«ÏÞ²âÊÔ½»Á÷¡±[3]ÖУ¬Dan North¶ÔBDD¸ø³öÁËÈç϶¨Ò壺

BDDÊǵڶþ´úµÄ¡¢ÓÉÍâ¼°Äڵġ¢»ùÓÚÀ­(pull)µÄ¡¢¶à·½ÀûÒæÏà¹ØÕßµÄ(stakeholder)¡¢¶àÖÖ¿ÉÀ©Õ¹µÄ¡¢¸ß×Ô¶¯»¯µÄÃô½Ý·½·¨¡£ËüÃèÊöÁËÒ»¸ö½»»¥Ñ­»·£¬¿ÉÒÔ¾ßÓдøÓÐÁ¼ºÃ¶¨ÒåµÄÊä³ö£¨¼´¹¤×÷Öн»¸¶µÄ½á¹û£©£ºÒѲâÊÔ¹ýµÄÈí¼þ¡£
ÁíÍâ×îÖ÷¹ÛµÄÇø±ð¾ÍÊÇÓôʣ¬¡®example¡¯È¡´úÁË¡®test¡¯£¬¡®describe¡¯È¡´úÁË¡®class¡¯£¬¡®behaviour¡¯È¡´úÁË¡®method¡¯µÈµÈ¡£ÕâÕýÊÇÆäÌØÕ÷Ö®Ò»£¬×ÔÈ»ÓïÑԵļÓÈ룬ʹµÃ·Ç³ÌÐòÈËÔ±Ò²ÄܲÎÓëµ½²âÊÔÓÃÀýµÄ±àдÖÐÀ´£¬Ò²´ó´ó½µµÍÁ˿ͻ§¡¢Óû§¡¢ÏîÄ¿¹ÜÀíÕßÓ뿪·¢ÕßÖ®¼äÀ´»Ø·­ÒëµÄ³É±¾¡£

¼òµ¥À´Ëµ£¬ÎÒÈÏΪBDD¸ü¼Ó×¢ÖØÒµÎñÐèÇó¶ø²»ÊǼ¼Êõ£¬ËäÈ»¿´ÆðÀ´BDDȷʵÊDZÈATDD×öµÄ¸üºÃ£¬µ«ÕâÊÇÒ»ÖÖÎóµ¼£¬Õâ½ö½öÊǾÍijÖÖ»·¾³Ï¶øÑԵġ£¶øÇÒÒÔ¹úÄÚµÄÏÖ×´À´¿´TDDÒª±ÈBDD¸üÊʺϣ¬ÒòΪËü²»ÐèÒªËùÓÐÈËÔ±µÄÀí½âºÍ¼ÓÈë¡£

µ¥Ôª²âÊÔ¿ò¼Ü

ÎÞÂÛÈçºÎ£¬µ¥Ôª²âÊÔÓÀÔ¶ÊÇÉÙ²»Á˵ġ£ÆäʵÔÚµ¥Ôª²âÊÔÖвâÊÔ´úÂëºÍÉú²ú´úÂëÓ¦¸ÃÊǵÈÁ¿µÄ£¬ÕýÈçRobert C. MartinÔÚÆä Clean Code: A Handbook of Agile Software Craftsmanship Ò»ÊéÖÐËùд£º

²âÊÔ±ØÐëËæÉú²ú´úÂëµÄÑݽø¶øÐ޸쬲âÊÔÔ½Ôà¾ÍÔ½ÄÑÐÞ¸Ä

ÓÚÊÇеIJâÊÔºÜÄѱ»¼ÓÈëÆäÖУ¬²âÊÔ´úÂëµÄά»¤±äµÃÒì³£À§ÄÑ£¬×îÖÕÔÚ¸÷ÖÖѹÁ¦Ö®ÖÐÖ»ÓÐÈÓµô²âÊÔ´úÂë×é¡£µ«ÊÇûÓÐÁ˲âÊÔ´úÂ룬¾ÍʧȥÁËÈ·±£¶Ô´úÂëµÄ¸Ä¶¯ÄÜÈçÔ¸ÒÔ³¥µÄÄÜÁ¦£¬¸÷ÖÖÎÊÌâËæÖ®¶øÀ´¡£Òò´Ë£¬µ¥Ôª²âÊÔÒ²ÐèÒªÒ»ÖÖÐÐÖ®ÓÐЧµÄʵ¼ùÀ´È·±£ÆäÖÊÁ¿ºÍ¿Éά»¤ÐÔ¡£

ËùÒÔÕýÈçÉú²ú´úÂëÒ»Ñù£¬²âÊÔ´úÂëÒ²Óпò¼Ü£¬ÏÂÃæ½éÉܼ¸ÖÖÖ÷Á÷µÄJavascriptµÄµ¥Ôª²âÊÔ¿ò¼Ü¡£

Jasmine

ÓÐÒ»Àà¿ò¼Ü½Ð×öxUnit£¬À´Ô´ÓÚÖøÃûµÄJAVA²âÊÔ¿ò¼ÜJUnit£¬xUnitÔò´ú±íÁËÒ»ÖÖģʽ£¬²¢ÇÒʹÓÃÕâÑùµÄÃüÃû¡£ÔÚJavascriptÖÐÒ²ÓÐÕâÑùµÄÒ»¸öÀÏÅÆ¿ò¼ÜJsUnit£¬ËûµÄ×÷ÕßÊÇEdward HieattÀ´×ÔPivotal Labs£¬µ«ÔÚ¼¸ÄêǰJsUnit¾ÍÒѾ­Í£Ö¹Î¬»¤ÁË£¬ËûÃÇ´øÀ´ÁËеÄBDD¿ò¼ÜJasmine¡£

Jasmine²»ÒÀÀµÓÚÈκοò¼Ü£¬ËùÒÔÊÊÓÃÓÚËùÓеÄJavascript´úÂ롣ʹÓÃÒ»¸öÈ«¾Öº¯Êý describe À´ÃèÊöÿ¸ö²âÊÔ£¬²¢ÇÒ¿ÉÒÔǶÌס£describeº¯ÊýÓÐ2¸ö²ÎÊý£¬Ò»¸öÊÇ×Ö·û´®ÓÃÓÚÃèÊö£¬Ò»¸öÊǺ¯ÊýÓÃÓÚ²âÊÔ¡£Ôڸú¯ÊýÖпÉÒÔʹÓÃÈ«¾Öº¯Êý it À´¶¨ÒåSpecs£¬Ò²¾ÍÊǵ¥Ôª²âÊÔµÄÖ÷ÒªÄÚÈÝ£¬ ʹÓà expect º¯ÊýÀ´²âÊÔ£º

describe('A suite', function () {
it('is a spec', function () {
var a = true;
expect(a).toBe(true);
});
});

ÁíÍâÈç¹ûÏëÈ¥µôij¸ödescribe£¬ÎÞÐë×¢Ê͵ôÕû¶Î´úÂ룬ֻÐèÒªÔÚdescribeÇ°Ãæ¼ÓÉÏx¼´¿ÉºöÂÔ¸Ãdescribe¡£

Matcher

toBe·½·¨ÊÇÒ»¸ö»ù±¾µÄ matcher ÓÃÀ´¶¨ÒåÅжϹæÔò£¬¿ÉÒÔ¿´µÃ³öÀ´JasmineµÄ·½·¨ÊǷdz£ÓïÒ廯µÄ£¬¡°expect ¡®a¡¯ to be true¡±£¬Èç¹ûÏëÅжϷñ¶¨Ìõ¼þ£¬ÔòÖ»ÐèÒªÔÚtoBeǰµ÷Óà not ·½·¨£º

expect(a).not().toBe(false);

³ýÁËtoBeÕâÑù»ù±¾µÄ»¹ÓÐÐí¶àÆäËûµÄMatcher£¬±ÈÈç toEqual ¡£ºÜ¶à³õѧJasmine»áŪ²»ÇåºÍtoBeµÄÇø±ð£¬Ò»¸ö¼òµ¥µÄÀý×Ó¾ÍÄÜÃ÷°×ËüÃǵÄÇø±ð£º

expect({}).not().toBe({});
expect({}).toEqual({});

Ò»¸öн¨µÄObject²»ÊÇ£¨not to be£©ÁíÒ»¸öн¨µÄObject£¬µ«ÊÇËüÃÇÊÇÏàµÈ£¨to equal£©µÄ¡£»¹ÓÐ toMatch ¿ÉÒÔʹÓÃ×Ö·û´®»òÕßÕýÔò±í´ïʽÀ´ÑéÖ¤£¬ÒÔ¼°ÆäËûÒ»Ð©ÌØÊâÑéÖ¤£¬±ÈÈçundefined»òÕßbooleanµÄÅжϣ¬ toThrow ¿ÉÒÔ¼ì²éº¯ÊýËùÅ׳öµÄÒì³£¡£ÁíÍâJasmine»¹Ö§³Ö×Ô¶¨ÒåMatcher£¬ÒÔNaNµÄ¼ì²éΪÀý£¬ÏñÕâÑùʹÓÃbeforeEach·½·¨ÔÚÿ¸ö²âÊÔÖ´ÐÐǰÌí¼ÓÒ»¸ömatcher£º

beforeEach(function () {
this.addMatchers({
toBeNaN: function (expected) {
return isNaN(expected);
}
});
});

¿ÉÒÔÏëµ½£¬Æä²ÎÊýexpectedÊÇ´«ÈëµÄÒ»¸öÆÚÍûµÄ×ÖÃæÁ¿£¬¶øÔÚexpect·½·¨Öд«ÈëµÄ²ÎÊý£¬¿ÉÒÔͨ¹ý this.acturl »ñÈ¡£¬ÊÇ·ñµ÷ÓÃÁË not ·½·¨Ôò¿ÉÒÔͨ¹ý this.isNot »ñÈ¡£¬ÕâÊÇÒ»¸öbooleanÖµ¡£×îºó²âÊÔÊä³öµÄʧ°ÜÐÅÏ¢Ó¦¸ÃʹÓà this.message À´¶¨Ò壬²»¹ýËüÊÇÒ»¸öfunction£¬È»ºóÔÚÆäÖзµ»ØÒ»¸öÐÅÏ¢¡£ËùÒÔ¼ÌÐøÔö½øtoBeNaN£º

beforeEach(function () {
this.addMatchers({
toBeNaN: function (expected) {
var actual = this.actual;
var not = this.isNot ? ' not' : '';
this.message = function () {
return 'Expected ' + actual + not + ' to be NaN ' + expected;
};
return isNaN(expected);
}
});
});

ÕâÑùÒ»¸öÍêÕûµÄmatcher¾Í´´½¨³ÉÁË¡£

ÁíÍâÐèҪ˵Ã÷µÄÊǶÔÓ¦beforeEachÊÇÔÚÿ¸öspec֮ǰִÐУ¬ afterEach ·½·¨ÔòÊÇÔÚÿ¸öspecÖ®ºóÖ´ÐС£ÕâÊÇÒ»ÖÖAOP£¬¼´ÃæÏò·½ÃæµÄ±à³Ì£¨Aspect Oriented Programming£©¡£±ÈÈçÓÐʱºòΪÁ˲âÊÔÒ»¸ö¶ÔÏ󣬿ÉÄÜÐèÒª¶à´Î´´½¨ºÍÏú»ÙËü£¬ËùÒÔΪÁ˱ÜÃâÈßÓà´úÂ룬ʹÓÃËüÃÇÊÇ×î¼ÑÑ¡Ôñ¡£

»¹¿ÉÒÔʹÓà jasmine.any ·½·¨À´´ú±íÒ»ÀàÊý¾Ý´«ÈëmatcherÖУ¬±ÈÈç

expect(123).toEqual(jasmine.any(Number));
expect(function () {}).toEqual(jasmine.any(Function));

Spy·½·¨

Ò»¸öSpyÄܼà²âÈκÎfunctionµÄµ÷ÓúͻñÈ¡Æä²ÎÊý¡£ÕâÀïÓÐ2¸öÌØÊâµÄMatcher£¬ toHaveBeenCalled ¿ÉÒÔ¼ì²éfunctionÊÇ·ñ±»µ÷Óùý£¬»¹ÓÐ toHaveBeenCalledWith ¿ÉÒÔ´«Èë²ÎÊý¼ì²éÊÇ·ñºÍÕâЩ²ÎÊýÒ»Æð±»µ÷Óùý£¬ÏñÕâÑùʹÓà spyOn À´×¢²áÒ»¸ö¶ÔÏóÖеķ½·¨£º

var foo, a = null;
beforeEach(function () {
var foo = {
set: function (str) {
a = str;
}
}
spyOn(foo, 'set');
foo.set(123);
});
it('tracks calls', function () {
expect(foo.set).toHaveBeenCalled();
expect(foo.set).toHaveBeenCalled(123);
expect(foo.set.calls[0].args[0]).toEqual(123);
expect(foo.set.mostRecentCall.args[0]).toEqual(123);
expect(a).toBeNull();
});

ÔÚ²âÊÔʱ¸Ãfunction½«´øÓÐÒ»¸ö±»µ÷ÓõÄÊý×é calls £¬¶ø args Êý×é¾ÍÊǵ÷ÓÃʱ´«ÈëµÄ²ÎÊý£¬ÁíÍâÌØÊâÊôÐÔ mostRencentCall Ôò´ú±í×îºóÒ»´Îµ÷Ó㬺Ícalls[calls.length]Ò»Ö¡£ÐèÒªÌØ±ð×¢ÒâµÄÊÇ£¬ÕâЩµ÷Óý«²»»á¶Ô±äÁ¿²úÉú×÷Óã¬ËùÒÔ a ÈÔΪnull¡£

Èç¹ûÐèÒªµ÷ÓòúÉúʵ¼ÊµÄ×÷Ó㬿ÉÒÔÔÚspyOn·½·¨ºóµ÷Óà andCallThrough ·½·¨¡£»¹¿ÉÒÔͨ¹ýµ÷Óà andReturn ·½·¨É趨һ¸ö·µ»ØÖµ¸øfunction¡£ andCallFake Ôò¿ÉÒÔ´«ÈëÒ»¸öfunction×÷Ϊ²ÎÊýÈ¥´úÌæÔ­±¾µÄfunction¡£

spyOn(foo, 'set').andCallThrough();

ÉõÖÁÔÚûÓÐfunctionµÄʱºò¿ÉÒÔʹÓÃJasmineµÄ createSpy ºÍ createSpyObj ´´½¨Ò»¸öspy£º

foo = jasmine.createSpy('foo');
obj = jasmine.createSpyObj('obj', [set, do]);

foo(123);
obj.set(123);
obj.do();

ÆäЧ¹ûÏ൱ÓÚspyOnʹÓÃÔÚÁËÒÑ´æÔÚµÄfunctionÉÏ¡£

ʱ¼ä¿ØÖÆ

ÉÏÃæµÄ·½·¨¶¼ÔÚ³ÌÐò˳ÐòÖ´ÐеÄǰÌáÏÂÖ´ÐУ¬µ« setTimeout ÒÔ¼° setInterval Á½¸ö·½·¨»áʹ´úÂë·ÖÀëÔÚʱ¼äÖáÉÏ¡£ËùÒÔJasmineÌṩÁË Clock ·½·¨À´Ä£Äâʱ¼ä£¬ÒÔ»ñÈ¡setTimeoutµÄ²»Í¬×´Ì¬¡£

beforeEach(function () {
jasmine.Clock.useMock();
});
it('set time', function () {
var str = 0;
setTimeout(function () {
str++;
}, 100);
expect(str).toEqual(0);
jasmine.Click.tick(101);
expect(str).toEqual(1);
jasmine.Click.tick(200);
expect(str).toEqual(3);
});

ʹÓÃClockµÄ·½·¨ useMock À´¿ªÊ¼Ê±¼ä¿ØÖÆ£¬È»ºóÔÚitÖÐʹÓà tick ·½·¨À´ÍƽøÊ±¼ä¡£

Òì²½

Javascript×î´óµÄÌØÉ«Ö®Ò»¾ÍÊÇÒì²½£¬Ö®Ç°½éÉܵķ½·¨Èç¹û´æÔÚÒì²½µ÷Ó㬴󲿷ֲâÊÔʱ¿ÉÄܻ᲻ͨ¹ý¡£Òò´Ë£¬ÐèÒªµÈÒì²½»Øµ÷Ö®ºóÔÙ½øÐвâÊÔ¡£

JasmineÌṩÁË runs ºÍ waitsFor Á½¸ö·½·¨À´Íê³ÉÕâ¸öÒì²½µÄµÈ´ý¡£ÐèÒª½«waitsFor·½·¨¼ÐÔÚ¶à¸öruns·½·¨ÖУ¬runs·½·¨ÖеÄÓï¾ä»á°´Ë³ÐòÖ±½ÓÖ´ÐУ¬È»ºó½øÈëwaitsFor·½·¨£¬Èç¹ûwaitsFor·µ»Øfalse£¬Ôò¼ÌÐøÖ´ÐÐwaitsFor£¬Ö±µ½·µ»Øtrue²ÅÖ´ÐкóÃæµÄruns·½·¨¡£

var cb = false;
var ajax = {
success: function () {
cb = true;
}
};
spyOn(ajax, 'success');
it('async callback', function () {
runs(function () {
_toAjax(ajax);
});
waitsFor(function () {
return ajax.success.callCount > 0;
});
runs(function () {
expect(cb).toBeTruthy();
});
});

Èç´Ë£¬Ö»ÒªÔÚwaitsForÖÐÅжϻص÷º¯ÊýÊÇ·ñ±»µ÷ÓÃÁ˼´¿ÉÍê³ÉÒì²½²âÊÔ¡£ÉÏÃæ´úÂëÖÐÎÒʹÓÃÒ»¸ö·½·¨ÃûÖ±½Ó´úÌæÁËajaxÇëÇó·½·¨À´Ëõ¼õ²»±ØÒªµÄ´úÂë¡£ÔÚµÚÒ»¸öruns·½·¨Öз¢³öÁËÒ»¸öajaxÇëÇó£¬È»ºóÔÚwaitsForÖеȴýÆä±»µ÷Ó㬵±µÚ¶þ¸örunsÖ´ÐÐʱ˵Ã÷»Øµ÷º¯ÊýÒѾ­±»µ÷ÓÃÁË£¬½øÐвâÊÔ¡£

Qunit

ËüÊÇÓÉjQueryÍŶӿª·¢µÄÒ»¿î²âÊÔÌ×¼þ£¬×î³õÒÀÀµÓÚjQuery¿â£¬ÔÚ2009ÄêʱÍÑÀëjQueryµÄÒÀÀµ£¬±ä³ÉÁËÒ»¸öÕæÕýµÄ²âÊÔ¿ò¼Ü£¬ÊÊÓÃÓÚËùÓÐJavascript´úÂë¡£

Qunit²ÉÓöÏÑÔ£¨Assert£©À´½øÐвâÊÔ£¬Ïà±ÈÓÚJasmineµÄmatcher¸ü¼Ó¶àµÄÀàÐÍ£¬Qunit¸ü¼¯ÖÐÔÚ²âÊԵĶÈÉÏ¡£ deepEqual ÓÃÓڱȽÏһЩ×ÝÏòÊý¾Ý£¬±ÈÈçObject»òÕßFunctionµÈ¡£¶ø×î³£ÓÃµÄ ok ÔòÖ±½ÓÅжÏÊÇ·ñΪtrue¡£Òì²½·½ÃæQunitÒ²ºÜÓÐȤ£¬Í¨¹ý stop À´Í£Ö¹²âÊԵȴýÒì²½·µ»Ø£¬È»ºóʹÓà start ¼ÌÐø²âÊÔ£¬ÕâÒª±ÈJasmineµÄ¹ý³Ì»¯µÄµÈ´ý¸ü×ÔÓÉһЩ£¬²»¹ýÓÐʱҲÐí»á¸üÄÑдһЩ¡£Qunit»¹ÓµÓÐ3×éAOPµÄ·½·¨( done ºÍ 'begin' )À´¶ÔÓ¦ÓÚÕû¸ö²âÊÔ£¬²âÊÔºÍÄ£¿é¡£

¶ÔÓÚFunctionµÄ¸ú×Ù²âÊÔ£¬QunitËÆºõÍêȫûÓп¼ÂÇ¡£²»¹ý¿ÉÒÔʹÓÃÁíÍâÒ»¸ö²âÊÔ¿ò¼ÜΪQunit´øÀ´µÄ²å¼þ sinon-qunit¡£ÕâÑù¾Í¿ÉÒÔÔÚtestÖÐʹÓà spy ·½·¨ÁË¡£

Sinon

Sinon²¢²»ÊÇÒ»¸öµäÐ͵ĵ¥Ôª²âÊÔ¿ò¼Ü£¬¸üÏñÒ»¸ö¿â£¬×îÖ÷ÒªµÄÊǶÔFunctionµÄ²âÊÔ£¬°üÀ¨ Spy ºÍ Stub Á½¸ö²¿·Ö£¬SpyÓÃÓÚÕì²âFunction£¬¶øStub¸üÏñÊÇÒ»¸öSpyµÄ²å¼þ»òÕßÖúÊÖ£¬ÔÚFunctionµ÷ÓÃǰºó×öÒ»Ð©ÌØÊâµÄ´¦Àí£¬±ÈÈçÐÞ¸ÄÅäÖûòÕ߻ص÷¡£ËüÕýºÃ¼«´óµÄÃÖ²¹ÁËQunitµÄ²»×㣬ËùÒÔͨ³£»áʹÓÃQunit+SinonÀ´½øÐе¥Ôª²âÊÔ¡£

ÖµµÃÒ»ÌáµÄÊÇ£¬SinonµÄ×÷ÕßChristian Johansen¾ÍÊÇ Test-Driven JavaScript Development Ò»ÊéµÄ×÷Õߣ¬Õâ±¾ÊéÕë¶ÔJavascriptºÜÏêϸµÄÃèÊöÁ˵¥Ôª²âÊÔµÄÿ¸ö»·½Ú¡£

Mocha

ËüµÄ×÷Õß¾ÍÊÇÔÚGithubÉÏ·ÛË¿6KµÄ³¬¼¶Jser TJ Holowaychuk£¬¿ÉÒÔÔÚËûµÄÒ³ÃæÉÏ¿´µ½¹ýÈ¥Ò»ÄêµÄÌá½»Á¿ÊÇ5700¶à£¬ÓµÓÐ300¶à¸öÏîÄ¿£¬ÎÞÂÛÊÇË­¶¼ÄÑÒÔÏëÏóËûÊÇÈçºÎ½øÐÐcodingµÄ¡£

ÀíËùµ±È»µÄ£¬Mocha³äÂúÁËGeek¸Ð£¬²»µ«¿ÉÒÔÔÚbashÖнøÐвâÊÔ£¬¶øÇÒ»¹ÓµÓÐÒ»ÕûÌ×ÃüÁî¶Ô²âÊÔ½øÐвÙ×÷¡£ÉõÖÁʹÓà diff ¿ÉÒԲ鿴µ±Ç°²âÊÔÓëÉÏÒ»´Î³É¹¦²âÊԵĴúÂë²»Ò»Ö¡£

²»½ö½öÊÇÕâÑù£¬Mocha·Ç³£µÃ×ÔÓÉ¡£Mocha½«¸ü¶àµÄ·½·¨¼¯ÖÐÔÚÁËdescribeºÍitÖУ¬±ÈÈçÒì²½µÄ²âÊԾͷdz£°ô£¬ÔÚitµÄ»Øµ÷º¯ÊýÖлá»ñȡһ¸ö²ÎÊý done £¬ÀàÐÍÊÇfunction£¬ÓÃÓÚÒì²½»Øµ÷£¬µ±Ö´ÐÐÕâ¸öº¯Êýʱ¾Í»á¼ÌÐø²âÊÔ¡£»¹¿ÉÒÔʹÓà only ºÍ skip ȥѡÔñ²âÊÔʱÐèÒªµÄ²¿·Ö¡£MochaµÄ½Ó¿ÚÒ²Ò»Ñù×ÔÓÉ£¬³ýÁË BDD ·ç¸ñºÍJasmineÀàËÆµÄ½Ó¿Ú£¬»¹ÓÐ TDD ·ç¸ñµÄ £¨suite test setup teardown suiteSetup suiteTeardown£©£¬»¹ÓÐAMD·ç¸ñµÄ exports£¬Qunit·ç¸ñµÈ¡£Í¬Ê±²âÊÔ±¨¸æÒ²¿ÉÒÔÈÎÒâ×éÖ¯£¬ÎÞÂÛÊÇÁÐ±í¡¢½ø¶ÈÌõ¡¢»¹ÊÇ·É»úÅܵÀÕâÑùÆæÌØµÄÑùʽ¶¼¿ÉÒÔÔÚbashÖÐÏÔʾ¡£

ǰ¶Ë²âÊÔ¹¤¾ß

Client/Server ²âÊÔ

Ïà±ÈÓÚ·þÎñ¶Ë¿ª·¢£¬Ç°¶Ë¿ª·¢ÔÚ²âÊÔ·½ÃæÊ¼ÖÕÃæÁÙ×ÅÒ»¸öÑϾþµÄÎÊÌ⣬ÄǾÍÊÇä¯ÀÀÆ÷¼æÈÝÐÔ¡£Paul IrishÔø·¢±íÎÄÕÂBrowser Market Pollution: IE[x] Is the New IE6²ûÊöÁËÒ»¸öÆæ¹ÖµÄÉèÏ룬δÀ´Äã¿ÉÄÜÐèÒªÔÚ76¸öä¯ÀÀÆ÷ÉÏ¿ª·¢£¬ÒòΪÿ´ÎIEµÄа汾¶¼ÊÇÒ»¸öÌØ±ðµÄä¯ÀÀÆ÷£¬¶øÇÒ»¹ÓÐËü¶Ô֮ǰËùÓа汾µÄ¼æÈÝģʽҲÊÇÒ»Ñù¡£ËäȻûÈËÈÏΪ΢Èí»á¼ÌÐøÈç´ËÓÞ´À£¬²»¹ýÕâҲ˵Ã÷ÁËÒ»¸öÎÊÌ⣬ǰ¶Ë¿ª·¢ÖÐä¯ÀÀÆ÷¼æÈÝÐÔÊÇÒ»¸öÓÀÔ¶µÄÎÊÌ⣬¶øÇÒÎÒÈÏΪ¼´Ê¹½â¾öÁËä¯ÀÀÆ÷µÄ¼æÈÝÐÔÎÊÌ⣬δÀ´ÔÚÒÆ¶¯¿ª·¢·½Ã棬É豸¼æÈÝÐÔÒ²ÊÇÒ»¸öÎÊÌâ¡£

ËùÒÔÔÚ×Ô¶¯»¯²âÊÔ·½ÃæÒ²ÊÇÈç´Ë£¬¼´Ê¹ËùÓеĵ¥Ôª²âÊÔ¼¯ÖÐÔÚÁËÒ»¸örunnerÖУ¬Ç°¶Ë²âÊÔÈÔÈ»ÒªÃæ¶ÔÖÁÉÙ4¸öä¯ÀÀÆ÷ÄÚºËÒÔ¼°3¸öµçÄÔ²Ù×÷ϵͳ¼Ó2¸ö»ò¸ü¶àÒÆ¶¯²Ù×÷ϵͳ£¬ºÎ¿ö»¹ÓÐÁîÒÆ¶¯¿ª·¢ÈËԱͷÌÛµÄAndroidµÄË鯬»¯ÎÊÌâ¡£²»¹ý¿ÉÒÔ°²ÐĵÄÊÇ£¬ÔçÒÑ´æÔÚÕâÑùµÄ¹¤¾ß¿ÉÒÔ²¶»ñ²»Í¬É豸ÉϵIJ»Í¬ä¯ÀÀÆ÷£¬²¢Ê¹Ö®ËæÊ±¸üвâÊÔ½á¹û£¬ÉõÖÁ¿ÉÒÔÔÚÒ»¸öÖÕ¶ËÉÏ¿´µ½ËùÓнá¹û¡£

¹¤¾ß½éÉÜ

JSTD£¨Javascript Test Driver£©ÊÇÒ»¸ö×îÔçµÄC/S²âÊÔ¹¤¾ß£¬À´×ÔGoogle£¬»ùÓÚJAVA±àд£¬¿çƽ̨£¬Ê¹ÓÃÃüÁîÐпØÖÆ£¬»¹Óкܺõı༭Æ÷Ö§³Ö£¬×î³£ÓÃÓÚeclipse¡£²»¹ýËüÎÞ·¨ÏÔʾ²âÊÔ¶ÔÏóµÄÉ豸¼°ä¯ÀÀÆ÷°æ±¾£¬Ö»ÓÐä¯ÀÀÆ÷ÃûÊDz»¹»µÄ¡£ÁíÍâJSTDÒѾ­ÂýÂý²»ÔÙ»îÔ¾£¬ËüµÄÔçÕýÈçËüµÄÀÏ¡£

GoogleµÄйóKarma³öÏÖÁË£¬ËüʹÓÃNodejs¹¹½¨£¬Òò´Ë¿çƽ̨£¬»¹Ö§³ÖPhantomJSä¯ÀÀÆ÷£¬»¹Ö§³Ö¶àÖÖ¿ò¼Ü£¬°üÀ¨ÒÔÉϽéÉܵÄJasmine¡¢QunitºÍMocha¡£Ò»´Î¿ÉÒÔÔÚ¶à¸öä¯ÀÀÆ÷¼°É豸ÖнøÐвâÊÔ£¬²¢¿ØÖÆä¯ÀÀÆ÷ÐÐΪºÍ²âÊÔ±¨¸æ¡£ËäÈ»Ëü²»Ö§³ÖNodejsµÄ²âÊÔ£¬²»¹ýûʲôӰÏ죬ÒòΪNodejs²¢²»ÒÀÀµÓÚä¯ÀÀÆ÷¡£

»¹ÓÐTestSwarm£¬³ö×ÔjQueryÖ®¸¸John ResigÖ®ÊÖ£¬¿´À´jQueryµÄÇ¿´ó¹ûÈ»²»ÊÇżȻµÄ£¬ÔÚ²âÊÔ·½Ãæ·Ç³£µ½Î»£¬¸÷ÖÖ¹¤¾ßÆëÈ«¡£Ëü×îÌØ±ðµÄµØ·½ÔÚÓÚËùÓвâÊÔ»·¾³ÓÉ·þÎñÆ÷Ìṩ£¬°üÀ¨¸÷ÖÖ°æ±¾µÄÖ÷Á÷ä¯ÀÀÆ÷ÒÔ¼°iOS5µÄiphoneÉ豸£¬²»¹ýĿǰ¼ÓÈëÒѾ­ÊÜÏÞ¡£

×îÊÜÖõÄ¿µÄµ±ÊôBuster£¬Æä×÷ÕßÖ®Ò»¾ÍÊÇChristian Johansen¡£ºÍKarmaºÜÏñ£¬Ò²Ê¹ÓÃNodejs±àд¿çƽ̨²¢ÇÒÖ§³ÖPhantomJS£¬Ò»´Î²âÊÔËùÓпͻ§¶Ë¡£¸üÖØÒªµÄÊÇÖ§³ÖNodejsµÄ²âÊÔ£¬Í¬ÑùÖ§³Ö¸÷ÖÖÖ÷Á÷²âÊÔ¿ò¼Ü¡£²»¹ýĿǰ»¹ÔÚBeta²âÊÔÖУ¬ºÜ¶àbug¶øÇÒ²»ÄܺܺõļæÈÝWindowsϵͳ¡£ËüµÄÄ¿±ê»¹°üÀ¨ÕûºÏBrowser Stack¡£

»ùÓÚÍøÒ³µÄ²âÊÔ

µ½Ä¿Ç°ÎªÖ¹ÎÒÃǵIJâÊÔ¿´ÆðÀ´Ê®·ÖµÄÍêÃÀÁË£¬µ«ÊDZðÍüÁË£¬ÔÚǰ¶Ë¿ª·¢ÖдæÔÚ½»»¥ÎÊÌ⣬²»ÄÜÆÚ´ýQAÍæÁËÃüµÄµã»÷ij¸ö°´Å¥»òÕßË¢ÐÂÒ»¸öÒ³Ãæ²¢ÊäÈëÒ»¾äÂÒÂëÖ®ÀàµÄ¶«Î÷À´²âÊÔ´úÂë¡£¼´Ê¹ÊÇ¿ª·¢Õß±¾ÉíÒ²»áÊܲ»ÁË£¬Èç¹û²úÆ·±¾ÉíÓµÓÐÒ»¶Ñ¸´ÔÓµÄ±íµ¥ºÍÂß¼­µÄ»°¡£

SeleniumÊÇÒ»¸ö²âÊÔ¹¤¾ß¼¯£¬ÓÉThoughtworks¿ª·¢£¬·ÖΪÁ½²¿·Ö¡£Selenium IDEÊÇÒ»¸öFirefoxä¯ÀÀÆ÷µÄ²å¼þ£¬¿ÉÒÔÂ¼ÖÆÓû§ÐÐΪ£¬²¢¿ìËÙ²âÊÔ¡£

¶øSelenium WebDriverÊÇÒ»¸ö¶àÓïÑÔµÄÇý¶¯ä¯ÀÀÆ÷µÄ¹¤¾ß£¬Ö§³ÖPython¡¢Java¡¢Ruby¡¢Perl¡¢PHP»ò.Net¡£²¢ÇÒ¿ÉÒÔ²Ù×÷IE¡¢Firefox¡¢SafariºÍChromeµÈÖ÷Á÷ä¯ÀÀÆ÷¡£Í¨¹ý open , type , click , waitForxxx µÈÖ¸ÁîÀ´Ä£ÄâÓû§ÐÐΪ£¬±ÈÈçÓÃJava²âÊÔ£º

public void testNew() throws Exception {
selenium.open("/");
selenium.type("q", "selenium rc");
selenium.click("btnG");
selenium.waitForPageToLoad("30000");
assertTrue(selenium.isTextPresent("Results * for selenium rc"));
}

Ê×ÏÈÌø×ªµ½¸úĿ¼£¬È»ºóÑ¡ÔñÀàÐÍ£¬µã»÷°´Å¥G£¬²¢µÈ´ýÒ³ÃæÔØÈë30Ã룬ȻºóʹÓöÏÑÔ²âÊÔ¡£ÕâÑù¾ÍÍê³ÉÁËÒ»´ÎÓû§»ù±¾ÐÐΪµÄÄ£Ä⣬²»¹ý¸´ÔÓµÄÄ£ÄâÒÔ¼°ÔÚһЩ·ÇÁ´½ÓµÄ²Ù×÷»¹ÐèÒª¸ñÍâ×¢Ò⣬±ÈÈçAjaxÇëÇó»òÕßPjaxµÄÎÞˢеȵȡ£

ÁíÍ⻹ÓÐÒ»¿î¿ÉÒÔÄ£ÄâÓû§ÐÐΪµÄÍøÒ³²âÊÔ¹¤¾ßWATIR£¬ÊÇWeb Application Testing in RubyµÄËõд£¬ÏÔÈ»ËüÖ»Ö§³ÖRubyÓïÑÔÀ´²Ù×÷ä¯ÀÀÆ÷Ä£ÄâÓû§ÐÐΪ¡£¹Ù·½Éù³ÆËüÊÇÒ»¸ö¼òµ¥¶øÁé»îµÄ¹¤¾ß£¬ÎÞÂÛÔõÑùÖÁÉپ͹ٷ½ÍøÕ¾µÄÉè¼ÆÀ´¿´Òª±ÈSelenium¼òÔ¼¶àÁË¡£Í¬ÑùÖ§³ÖÄ£ÄâÁ´½Óµã»÷£¬°´Å¥µã»÷£¬»¹ÓÐ±íµ¥µÄÌîдµÈÐÐΪ¡£²»¹ýWATIR²»Ö§³ÖAjaxµÄ²âÊÔ¡£ºÍÆäËûRuby¿âÒ»ÑùÐèÒªgemÀ´°²×°Ëü£º

gem install watir --no-rdoc --no-ri

È»ºóʹÓÃËü

require 'rubygems'
require 'watir'
require 'watir-webdriver'
browser = Watir::Browser.new
browser.goto 'http://www.example.com/form'
browser.test_field(:name => 'entry.0.single').set 'Watir'
browser.radio(:value => 'Watir').set
browser.radio(:value => 'Watir').clear
browser.checkbox(:value => 'Ruby').set
browser.checkbox(:value => 'Javascript').clear
browser.button(:name => 'submit').click

ÕâÑù¾ÍʹÓÃwatirÍê³ÉÁËÒ»´Î±íµ¥Ìîд¡£

³ÖÐø¼¯³É²âÊÔ

³ÖÐø¼¯³É¾ÍÊÇͨ³£ËùνµÄCI(Continuous integration)£¬³ÖÐø²»¶ÏµÄ×Ô¶¯»¯²âÊÔмÓÈë´úÂëºóµÄÏîÄ¿¡£Ëü²¢²»ÊôÓÚµ¥Ôª²âÊÔ£¬¶øÊÇÁíÍâµÄ·¶³ë£¬²»¹ýͨ¹ýʹÓÃCI·þÎñ¿ÉÒÔºÜÈÝÒ×µÄÔÚGithubÉϲâÊÔÏîÄ¿£¬¶øÕâÒ²¾ÍÊdzÖÐø¼¯³ÉµÄÒâÒå¡£

ÏÂÃæÒÔÎÒµÄjQС²å¼þDialogΪÀý½éÉÜÒ»ÏÂTravis-CIµÄʹÓ÷½·¨£¬×¢²áTravis£¬È»ºóÁ´½Ó×Ô¼ºµÄGithub£¬Ñ¡ÔñÒª½øÐгÖÐø¼¯³ÉµÄÏîÄ¿¡£´Ëʱ»áÏÔʾbuild failing£¬ÄÇÊÇÒòΪ»¹Ã»ÓÐÔÚÏîÄ¿ÖнøÐÐÏà¹ØÅäÖá£

Ê×ÏÈÐèҪʹÓÃGruntµÈ¹¤¾ßÅäÖúòâÊÔ¿ò¼ÜµÄ×Ô¶¯»¯²âÊÔ£¬Ï¸½Ú¿ÉÒԲο¼ÎÒ֮ǰµÄÎÄÕ¸ĽøÎÒµÄWorkflow¡£È»ºóÔÚ package.json ÖÐÌí¼ÓһϴúÂëÀ´Ö¸¶¨Ö´ÐеĽű¾£º

"scripts": {
"test": "grunt jasmine:test"
}

½Ó×ÅÌí¼ÓÒ»¸öÎļþ .travis.yml À´ÅäÖÃtravis£º

language: node_js
node_js:
- "0.8"
before_script:
- npm install -g grunt-cli

language ÊǼ¯³É²âÊÔËùʹÓõÄÓïÑÔ£¬ÕâÀïǰ¶Ë¿ª·¢µ±È»ÊÇʹÓÃNodejs£¬ÔÚ node_js ÖÐÖ¸¶¨°æ±¾¼´¿É¡£µ±È»Travis»¹Ö§³ÖÆäËû¶àÖÖÓïÑÔ£¬ÒÔ¼°ºó¶ËÊý¾Ý¿âµÈ¡£

before_script ÔòÊÇÔÚ²âÊÔǰִÐеĽű¾³ÌÐò£¬ÕâÀïÔÚÈ«¾Ö°²×°Grunt-cli¼´¿É£¬ÒòΪĬÈϵÄTravis»áÖ´ÐÐ npm install ½«package.jsonÖÐÖ¸¶¨µÄNode°ü°²×°µ½ÏîÄ¿¡£

×îºóÔÚGithubÖл¹ÐèÒªÔÚÏîÄ¿µÄSettingÖеÄService HooksÖÐÅäÖÃTravis£¬ÊäÈëToken²¢±£´æ¡£»òÕßÖ±½ÓÔÚTravisÖеã»÷¸ÃÏîÄ¿ÌõÄ¿ÖеİâÊÖͼ±ê½øÈëGithub£¬»á×Ô¶¯ÅäÖúá£

ÁíÍ⣬Èç¹ûÔÚGithubÉÏΪREADMEÎļþÌí¼ÓÒ»ÐÐ

[![Build Status](https://travis-ci.org/tychio/dialog.png?branch=master)](https://travis-ci.org/tychio/dialog)

¾Í¿ÉÒÔ³ÖÐøÖ±¹ÛµÄÏÔʾÆä²âÊÔ½á¹û¡£

   
2881 ´Îä¯ÀÀ       32
Ïà¹ØÎÄÕÂ

΢·þÎñ²âÊÔÖ®µ¥Ôª²âÊÔ
һƪͼÎÄ´øÄãÁ˽â°×ºÐ²âÊÔÓÃÀýÉè¼Æ·½·¨
È«ÃæµÄÖÊÁ¿±£ÕÏÌåϵ֮»Ø¹é²âÊÔ²ßÂÔ
È˹¤ÖÇÄÜ×Ô¶¯»¯²âÊÔ̽Ë÷
Ïà¹ØÎĵµ

×Ô¶¯»¯½Ó¿Ú²âÊÔʵ¼ù֮·
jenkins³ÖÐø¼¯³É²âÊÔ
ÐÔÄܲâÊÔÕï¶Ï·ÖÎöÓëÓÅ»¯
ÐÔÄܲâÊÔʵÀý
Ïà¹Ø¿Î³Ì

³ÖÐø¼¯³É²âÊÔ×î¼Ñʵ¼ù
×Ô¶¯»¯²âÊÔÌåϵ½¨ÉèÓë×î¼Ñʵ¼ù
²âÊԼܹ¹µÄ¹¹½¨ÓëÓ¦ÓÃʵ¼ù
DevOpsʱ´úµÄ²âÊÔ¼¼ÊõÓë×î¼Ñʵ¼ù
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

LoadRunnerÐÔÄܲâÊÔ»ù´¡
Èí¼þ²âÊÔ½á¹û·ÖÎöºÍÖÊÁ¿±¨¸æ
ÃæÏò¶ÔÏóÈí¼þ²âÊÔ¼¼ÊõÑо¿
Éè¼Æ²âÊÔÓÃÀýµÄËÄÌõÔ­Ôò
¹¦ÄܲâÊÔÖйÊÕÏÄ£Ð͵Ľ¨Á¢
ÐÔÄܲâÊÔ×ÛÊö

ÐÔÄܲâÊÔ·½·¨Óë¼¼Êõ
²âÊÔ¹ý³ÌÓëÍŶӹÜÀí
LoadRunner½øÐÐÐÔÄܲâÊÔ
WEBÓ¦ÓõÄÈí¼þ²âÊÔ
ÊÖ»úÈí¼þ²âÊÔ
°×ºÐ²âÊÔ·½·¨Óë¼¼Êõ

ij²©²ÊÐÐÒµ Êý¾Ý¿â×Ô¶¯»¯²âÊÔ
IT·þÎñÉÌ Web°²È«²âÊÔ
IT·þÎñÉÌ ×Ô¶¯»¯²âÊÔ¿ò¼Ü
º£º½¹É·Ý µ¥Ôª²âÊÔ¡¢Öع¹
²âÊÔÐèÇó·ÖÎöÓë²âÊÔÓÃÀý·ÖÎö
»¥ÁªÍøweb²âÊÔ·½·¨Óëʵ¼ù
»ùÓÚSeleniumµÄWeb×Ô¶¯»¯²âÊÔ