ÕªÒª£ºÔÚiOSÏîÄ¿¿ª·¢ÖУ¬µ±ÊµÏÖй¦ÄÜʱÈç¹ûºöÂÔ¿Éά»¤ÐÔ¶øÒýÈë¼¼ÊõÕ®Îñ£¬½«»áÐèÒªÑÓ³Ù½â¾öËü»òµ¼ÖÂÔö¼Óά»¤³É±¾¡£¿ª·¢ÕßÐèÒªÉèÖÃʲô²ÅÄÜ×Ô¶¯¼à¿Ø´úÂëÖÊÁ¿£¿Í¨¹ýÊʵ±ÔËÓÃGcovrµÈһϵÁй¤¾ß£¬¾ÍÄÜÓÐЧÌá¸ß´úÂëÖÊÁ¿¡£
µ±ÊµÏÖй¦ÄÜʱ£¬Èç¹ûºöÂÔ¿Éά»¤ÐÔ¶øÒýÈë¼¼ÊõÕ®Îñ£¬Äǽ«»áÐèÒªÑÓ³Ù½â¾öËü»òµ¼ÖÂÔö¼Óά»¤³É±¾¡£
×î½üÎÒÃÇÒѾ˼¿¼Í¨¹ýÄÄЩ·½Ê½À´Ìá¸ß´úÂëµÄÖÊÁ¿£º
µ±´úÂëµÄÖÊÁ¿Ï½µÊ±£¬Í¨¹ýÉèÖÃһЩ¹¤¾ßÀ´ÂíÉÏÌáÐÑ¿ª·¢Õߣ»
Îĵµ»¯Ò»Ð©±àÂë¹æ·¶ºÍ˼¿¼ÔÚ¹ýÈ¥µÄ¼¸¸öÏîÄ¿ÖÐÈçºÎ±ÜÃâά»¤ÐÔ²îµÄÎÊÌâ¡£
ÎÒ½«»á¼òµ¥µØ¸ÅÀ¨ÎÒÃÇÐèÒªÉèÖÃʲô²ÅÄÜ×Ô¶¯¼à¿Ø´úÂëÖÊÁ¿¡£
»ù´¡
ÎÒÃÇÑ¡ÔñÒ»¸ö³ÖÐø¼¯³É¹¤¾ßJenkins£¬ÈÃËüÔËÐÐÔÚһ̨·ÅÔÚÎÒÃǹ¤×÷ÊÒµÄMac Mini¡£ÆäʵÎÒ²»Ôõôϲ»¶Jenkins£¬µ«µ½Ä¿Ç°ÎªÖ¹£¬ËüÊÇ×îÎȶ¨ºÍ×îÊʺϵŤ¾ßÀ´Íê³ÉÕâЩ¹¤×÷¡£
ÎÒÃÇÒѾͨ¹ýHomebrewºÍrbenvÀ´·Ö±ð°²×°JenkinsºÍRuby£¬¶ørbenvÄܹ»ÎªÎÒÃÇÌṩһ¸ö×îкÍÎȶ¨µÄRuby Gems»·¾³¡£ÓиöHomebrewºÍRuby GemsÁ½¸ö°ü¹ÜÀí¹¤¾ßÖ®ºó£¬ÎÒÃǾͼ¸ºõÄܹ»°²×°ËùÓÐÎÒÃÇÐèÒªµÄ¹¤¾ß£¬µ«ºÜÉÙ»áÆÆ»µÓëÔÓÐOS Xϵͳ¸üÐÂÌṩµÄRuby¡£
µ¥Ôª²âÊÔ
ÎÒÃÇʹÓÃSpectaºÍExpectaÀ´²âÊÔÎÒÃǵÄiOSÏîÄ¿¡£
SpectaÈÃÎÒÃDzÉÓÃÐÐΪÇý¶¯¿ª·¢(BDD)·ç¸ñµÄÓï·¨À´±àд²âÊÔ£¬Ïà±ÈÓÚXCTestµÄÓï·¨£¬Ëü¸ü¼ÓÒ×¶Á¡£Ëü»¹ÓÐÒ»¸öÇ¿´óµÄ·Ö×é²âÊÔ¹¦ÄÜ£¬ÔÚ²âÊÔ֮ǰ»òÖ®ºóÔËÐÐһЩ´úÂë¿é£¬ÕâÑùµÄ»°£¬Äܹ»¼«´óµØ¼õÉÙÖØ¸´´úÂë¡£
ExpectaÊÇÒ»¸öÆ¥ÅäÆ÷¿ò¼Ü£¬ÎÒÃÇ¿ÉÒÔÔÚ²âÊÔÖÐʹÓÃËüÀ´´´½¨¶ÏÑÔ¡£ËüµÄÓï·¨·Ç³£Ç¿´ó£¬Óë´Ëͬʱ£¬Ëü±ÈÄÚ½¨µÄXCAssertÌ×¼þ¸ü¼ÓÒ×¶Á¡£ÀýÈ磺
expect(@"foo").to.equal(@"foo"); expect(foo).notTo.equal(1); expect([bar isBar]).to.equal(YES); expect(baz).to.equal(3.14159); |
ÎÒÃÇÔÚ¿ª·¢Ê±£¬Í¨¹ýXCodeÀ´ÔËÐвâÊÔ£»¶øÊ¹ÓÃͨ¹ýHomebrewÀ´°²×°µÄJenkinsʱ£¬»á½èÖúXCTool¡£XCToolÊÇÒ»¸ö¿É´úÌæµÄÑ¡ÔñÀ´xcodebuild£¬ËüÄÜÈÃÄãͨ¹ýÃüÁîÐеķ½Ê½À´·Ç³£ÇáËɵØÔËÐвâÊÔÌ×¼þºÍÉú³ÉJUnit·ç¸ñµÄ²âÊÔ±¨¸æ¡£
$ xctool -workspace Project.xcworkspace -scheme Project -reporter junit:junit-report.xml test |
ÕâЩ²âÊÔ±¨¸æ»á·¢²¼ÔÚJenkinsÉÏ£¬¶øJenkins»áʹÓÃJUnit PluginÀ´¸ù¾Ýʱ¼äµÄÍÆÒÆÌṩµ¥Ôª²âÊÔ½á¹ûµÄͼ±í£¬Í¬Ê±»áÏòÎÒÃÇÏÔʾÎÒÃǵIJâÊÔÊÇ·ñÎȶ¨¡£

Unit Test
Pull Request²âÊÔ
ÎÒÃÇÏëÎÒÃǵIJâÊÔ¾¡¿ÉÄÜÔËÐÐÒÔÖÁÓÚÈç¹ûÎÒÃÇÆÆ»µÊ²Ã´¶«Î÷£¬ÎÒÃǾͻáÂíÉÏÖªµÀ¡£ÎÒÃÇÔÚfeature branches×öЩÐ޸ģ¬È»ºóÌá½»Ò»¸öpull requestµ½Github£¬ÄÇô´úÂë¾Í»á±»ÁíÒ»¸ö¿ª·¢ÕßÉó²é¡£Ö»Òª±»´ò¿ª£¬ÎÒÃǾÍÄÜÔËÐÐËùÓеIJâÊÔÀ´È·±£Ã»ÓÐÈκζ«Î÷±»ÆÆ»µ¡£
µ±ÐµÄpull requstÊÇ¿ª·Å״̬ʱ£¬ÎªÁ˹ÜÀíÕâЩ£¬ÎÒÃǰ²×°Github Pull Request pluginÀ´½«ÐÅÏ¢´ÓGithub·¢Ë͵½Jenkins¡£Èç¹ûÓÐÈκβâÊÔʧ°Ü£¬Ëü½«»áÏÔʾÔÚGithub£¬È»ºóÎÒÃǾͲ»½«´úÂëºÏ²¢£¬Ö±µ½´úÂë±»ÐÞ¸´ÎªÖ¹¡£
´úÂ븲¸ÇÂÊ
ÎÒÃÇÒ²»áÓÃGcovr¹¤¾ßÀ´Éú³É´úÂ븲¸ÇÂʱ¨¸æ£¬GcovrµÄ°²×°·½Ê½Ò²ÊÇHomebrew¡£ÄãÐèÒªÕë¶Ômain targetµÄdebug congfiguration¸Ä±äÁ½¸ö¹¹½¨ÉèÖÃÀ´ÅäÖÃÏîÄ¿¡£½«Generate Test Coverage FilesºÍInstrument Program Flow¶¼ÉèÖÃΪYES¡£
 Code Coverage
µ±ÎÒÃÇÔËÐе¥Ôª²âÊÔÀ´Éú³É´úÂ븲¸ÇÂʱ¨¸æÊ±£¬ÎÒÃÇÐèÒª½«OBJROOT=./buildÌí¼Óµ½XCToolÃüÁîÐеÄβ²¿¡£
$ gcovr -r . ¡ª object-directory build/Project.build/Debug- iphonesimulator/Project.build/Objects-normal/x86_64 ¡ª exclude ¡®.*Tests.*¡¯ ¡ª xml > coverage.xml |
GcovrÊä³öµÄ´úÂ븲¸ÇÂʱ¨¸æÒ²»á±»²å¼þCobertura Jenkins plugin·¢²¼£¬Õâ¸ö²å¼þ»áÌṩһÖÖ¿ÉÊÓ»¯µÄ·½Ê½À´¸ù¾Ýʱ¼äµÄÍÆÒÆÀ´ÏÔʾ´úÂ븲¸ÇÂÊ¡£
ÏÖÔÚÎÒÃDz»½ö¿ÉÒÔ¿´µ½²âÊÔÊÇ·ñͨ¹ý£¬»¹¿ÉÒÔ¿´µ½´úÂëµÄ²âÊÔ¸²¸Ç·¶Î§¡£
¾²Ì¬·ÖÎö
ÔÚ¹¤¾ß¼¯ÖУ¬ÆäÖÐÒ»¸öÇ¿´ó²¢Äܹ»±£³Ö¸ßÖÊÁ¿µÄ´úÂëµÄ¹¤¾ß¾ÍÊǾ²Ì¬·ÖÎö¹¤¾ß¡£ÕâЩ¹¤¾ß»áɨÃèÄãµÄ´úÂ룬ȻºóÉú³ÉÒ»¸ö±¨¸æ£¬Õâ¸ö±¨¸æ»á¸æËßÄãÆÆ»µ´úÂë·ç¸ñ¹æÔòµÄ´úÂëλÖ᣾ټ¸¸ö¹æÔòµÄÀý×Ó£º
δʹÓõıäÁ¿»ò²ÎÊý
³¤±äÁ¿Ãû£¬·½·¨Ãû»ò´úÂëÐÐ
¸²¸ÇÒ»¸ö·½·¨£¬µ«Ã»ÓÐÔÚÕâ¸ö·½·¨µ÷ÓÃsuper
·½·¨Ì«³¤»ò·½·¨¹ýÓÚ¸´ÔÓ
»¹¸ü¶àµÄ¹æ¸ñ...
ÎÒÃÇʹÓÃOCLint¾²Ì¬·ÖÎö¹¤¾ß£¬Õâ¸ö¹¤¾ßÄܹ»Ö§³ÖC£¬C++ºÍObjective-CÓïÑÔ¡£OCLintͨ¹ý½áºÏXCToolʹÓÃÀ´Éú³Éjson-compilation-database reporter£¬´Ó¶øÌṩgreat integrationÌØÐÔ¡£ÎÒÃÇÊ×ÏÈÌí¼ÓÁíÒ»¸öreporterµ½ÎÒÃǵÄXCToolÃüÁîÐУ¬È»ºó½«ÄǸöreport´«µÝµ½OCLintÀ´Ö´Ðо²Ì¬·ÖÎö¡£
$ xctool -workspace Project.xcworkspace -scheme Project -reporter junit:junit-report.xml -reporter json-compilation-database: compile_commands.json test $ oclint-json-compilation-database -e Pods -report-type pmd -o oclint-pmd.xml |
Õâ¸öreportÒÔPMDµÄ·½Ê½À´Éú³É£¬È»ºóʹÓÃPMD Plugin±»·¢²¼µ½Jenkins¡£ÓÐÁËÕâЩ²å¼þÖ®ºó£¬ÄãÒ²¿ÉÒÔÔÚ²âÊÔʧ°Ü֮ǰ£¬ÉèÖÃÿ¸ö¾¯¸æµÄÓÅÏȼ¶(µ×£¬ÖУ¬¸ß)ÖÐһЩÏÞÖÆ¡£×î³õ£¬ÎÒÃÇÉèÖÃÕâЩÏÞÖÆÎªµÍ£¬ÄÇôֻҪÎÒÃÇÒýÈë´úÂ룬¾Í»á±»ÌáÐÑ£¬´Ó¶øÌá¸ß´úÂëÖÊÁ¿¡£
 Static Analysis
×Ô¶¯²¿Êð
×îºóÒ»¸öÎÊÌâ²»ÊÇÈçºÎÌá¸ß´úÂëÖÊÁ¿£¬¶øÊÇÈçºÎ½Úʡʱ¼ä¡£¿ª·¢Õßͨ³£¶¼»á½«±àÒëºÃµÄ´úÂëͨ¹ýCrashlytics·¢Ë͵½Éè¼ÆÊ¦À´Éè¼ÆÉó²é£¬»òÔÚsprint½áÊøÑÝʾʱ·¢¸øÓû§¡£·¢ËÍÒ»¸öÒѾ±àÒëºÃµÄAppͨ³£»¨Ò»¸ö¿ª·¢ÕßµÄ10·ÖÖÓ×óÓÒʱ¼ä£¬µ«ËüÐèÒªËûÃÇÀ´Çл»ÈÎÎñºÍ¸ÉÈÅËûÃǵÄÐÄÁ÷¡£
×î½üÎÒÃÇÒѾÅäÖÃÒ»¸öÔÚÒ¹Íí¹¹½¨ÏµÍ³£¬Ëü»áÔÚÔçÉÏ×Ô¶¯·¢ËÍÒ»¸öа汾µÄApp¸øÃ¿¸öÈË¡£
ΪÁË×öµ½ÕâÑù£¬ÎÒÃÇʹÓÃfastlane¡£fastlaneÊÇÒ»¸ö¶¨ÒålanesµÄһЩ²Ù×÷À´Ö´ÐеÄÇ¿´ó¹¤¾ß¼¯¡£ÏÖÔÚÎÒÃÇÓÐÈý¸öÒѾ¶¨ÒåºÃµÄlanes£¬Ò»¸öÊÇÓÃÀ´·¢²¼¸øribot¿ª·¢Õߣ¬Ò»¸öÊÇÓÃÀ´·¢²¼¸øÔÚribotµÄÿ¸öÈË£¬×îºóÒ»¸öÊÇ·¢²¼¸øÓû§¡£
before_all do |lane| cert sigh end desc ¡°Deploy a new build to ribot iOS developers over crashlytics¡± lane :dev do ipa crashlytics({ groups: ¡®ribot-developers¡¯ }) end desc ¡°Deploy a new build to people at ribot over crashlytics¡± lane :internal do ensure_git_status_clean append_build_time ipa crashlytics({ groups: ¡®ribot¡¯ }) reset_git_repo end desc ¡°Deploy a new build to everyone over crashlytics¡± lane :external do ensure_git_status_clean increment_build_number ipa crashlytics({ groups: [¡®ribot¡¯, ¡®client¡¯] }) commit_version_bump add_git_tag push_to_git_remote end after_all do |lane| clean_build_artifacts end |
ͨ¹ýʹÓÃfastlane¹¤¾ß(ͨ¹ýRuby GemsÀ´°²×°)À´ÔËÐÐÒ»¸ölane¡£
ÔÚ¿ªÊ¼Ê¹ÓÃËùÓеÄlanes֮ǰ£¬ÎÒÃÇÓ¦¸Ã×Ô¶¯È·±£ÎÒÃÇÓÐÒ»¸öÓÐЧµÄsigning certificateºÍ×îеÄprovisioning profile¡£ËùÓÐÎÒÃǵÄÅäÖö¼·ÅÔÚÒ»¸ö.envÎļþ£¬ËüÈÃÎÒÃÇÓÐЩĬÈÏÅäÖ㬵«µ±ÎÒÃÇÔËÐÐfastlane¸ù¾ÝÐèÒªÀ´¸²¸ÇËüÃÇ¡£
ÔÚ½«À´£¬ÎÒÃÇ»áͨ¹ýʹÓÃdeliver²Ù×÷À´×Ô¶¯»¯App StoreÌá½»¹ý³Ì¡£
×îºó×ܽá
µ½Ä¿Ç°ÎªÖ¹£¬ÎÒÃÇÒѾ³¢ÊÔÕâЩ¹ý³Ì£¬²¢ÔÚ¹¤³ÌÖгÊÏÖ³öºÃµÄ½á¹û¡£ÎÒÃÇÆÚÍû¿´µ½Ö»ÒªÊʵ±µØÊ¹ÓÃÕâЩ¹¤¾ß£¬¾ÍÄÜÌá¸ß´úÂëµÄÖÊÁ¿£¬ÕâЩ±¨¸æ½«»áÈÃÎÒÃÇËæ×Åʱ¼äÍÆÒÆÀ´Á¿»¯´úÂëÖÊÁ¿¡£ÎÒÃÇÆÚ´ýÔÚÏÂÒ»¸ö¹¤³ÌÖÐÊʵ±µØÊ¹ÓÃÕâЩ¹¤¾ß»á·¢Éúʲô¡£ |