CINXE.COM

Google Testing Blog: July 2008

<!DOCTYPE html> <html class='v2 list-page' dir='ltr' itemscope='' itemtype='http://schema.org/Blog' lang='en' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <title> Google Testing Blog: July 2008 </title> <meta content='width=device-width, height=device-height, minimum-scale=1.0, initial-scale=1.0, user-scalable=0' name='viewport'/> <meta content='IE=Edge' http-equiv='X-UA-Compatible'/> <meta content='Google Testing Blog' property='og:title'/> <meta content='en_US' property='og:locale'/> <meta content='https://testing.googleblog.com/2008/07/' property='og:url'/> <meta content='Google Testing Blog' property='og:site_name'/> <!-- Twitter Card properties --> <meta content='Google Testing Blog' property='og:title'/> <meta content='summary' name='twitter:card'/> <meta content='@googletesting' name='twitter:creator'/> <link href='https://fonts.googleapis.com/css?family=Roboto:400italic,400,500,500italic,700,700italic' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/icon?family=Material+Icons' rel='stylesheet'/> <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js' type='text/javascript'></script> <!-- End --> <style id='page-skin-1' type='text/css'><!-- /* <Group description="Header Color" selector="header"> <Variable name="header.background.color" description="Header Background" type="color" default="#ffffff"/> </Group> */ .header-outer { border-bottom: 1px solid #e0e0e0; background: #ffffff; } html, .Label h2, #sidebar .rss a, .BlogArchive h2, .FollowByEmail h2.title, .widget .post h2 { font-family: Roboto, sans-serif; } .plusfollowers h2.title, .post h2.title, .widget h2.title { font-family: Roboto, sans-serif; } .widget-item-control { height: 100%; } .widget.Header, #header { position: relative; height: 100%; width: 100%; } } .widget.Header .header-logo1 { float: left; margin-right: 15px; padding-right: 15px; border-right: 1px solid #ddd; } .header-title h2 { color: rgba(0,0,0,.54); display: inline-block; font-size: 40px; font-family: Roboto, sans-serif; font-weight: normal; line-height: 48px; vertical-align: top; } .header-inner { background-repeat: no-repeat; background-position: right 0px; } .post-author, .byline-author { font-size: 14px; font-weight: normal; color: #757575; color: rgba(0,0,0,.54); } .post-content .img-border { border: 1px solid rgb(235, 235, 235); padding: 4px; } .header-title a { text-decoration: none !important; } pre { border: 1px solid #bbbbbb; margin-top: 1em 0 0 0; padding: 0.99em; overflow-x: auto; overflow-y: auto; } pre, code { font-size: 9pt; background-color: #fafafa; line-height: 125%; font-family: monospace; } pre, code { color: #060; font: 13px/1.54 "courier new",courier,monospace; } .header-left .header-logo1 { width: 128px !important; } .header-desc { line-height: 20px; margin-top: 8px; } .fb-custom img, .twitter-custom img, .gplus-share img { cursor: pointer; opacity: 0.54; } .fb-custom img:hover, .twitter-custom img:hover, .gplus-share img:hover { opacity: 0.87; } .fb-like { width: 80px; } .post .share { float: right; } #twitter-share{ border: #CCC solid 1px; border-radius: 3px; background-image: -webkit-linear-gradient(top,#ffffff,#dedede); } .twitter-follow { background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSPSElBOH0lQ-yG1UMSLWe_pq9gZ9DT-0xhhjwadPeQt1WAHCnDYvERUcHBadwN6NcdtZCJu-F0fLqO6_PnV2iWDxnun1R_ii8saOztKUI6GA6zc2FNkjkcfTDlPzaINdbYhPw7Q/s1600/twitter-bird.png) no-repeat left center; padding-left: 18px; font: normal normal normal 11px/18px 'Helvetica Neue',Arial,sans-serif; font-weight: bold; text-shadow: 0 1px 0 rgba(255,255,255,.5); cursor: pointer; margin-bottom: 10px; } .twitter-fb { padding-top: 2px; } .fb-follow-button { background: -webkit-linear-gradient(#4c69ba, #3b55a0); background: -moz-linear-gradient(#4c69ba, #3b55a0); background: linear-gradient(#4c69ba, #3b55a0); border-radius: 2px; height: 18px; padding: 4px 0 0 3px; width: 57px; border: #4c69ba solid 1px; } .fb-follow-button a { text-decoration: none !important; text-shadow: 0 -1px 0 #354c8c; text-align: center; white-space: nowrap; font-size: 11px; color: white; vertical-align: top; } .fb-follow-button a:visited { color: white; } .fb-follow { padding: 0px 5px 3px 0px; width: 14px; vertical-align: bottom; } .gplus-wrapper { margin-top: 3px; display: inline-block; vertical-align: top; } .twitter-custom, .gplus-share { margin-right: 12px; } .fb-follow-button{ margin: 10px auto; } /** CUSTOM CODE **/ /* Make the page title smaller */ .header-inner { height: 120px !important; } /* Make the post titles look like the links that they are */ .post .title a { color: #4184F3 !important; } /* Set a normal line height in post text */ .post .post-content { line-height: 1.4 !important; } .post .post-content li { line-height: 1.4 !important; } /* Custom table class used in some posts */ .my-bordered-table { border-collapse: collapse; border: 1px solid black; } .my-bordered-table th, .my-bordered-table td { border: 1px solid black; padding: 5px; } --></style> <style id='template-skin-1' type='text/css'><!-- .header-outer { clear: both; } .header-inner { margin: auto; padding: 0px; } .footer-outer { background: #f5f5f5; clear: both; margin: 0; } .footer-inner { margin: auto; padding: 0px; } .footer-inner-2 { /* Account for right hand column elasticity. */ max-width: calc(100% - 248px); } .google-footer-outer { clear: both; } .cols-wrapper, .google-footer-outer, .footer-inner, .header-inner { max-width: 978px; margin-left: auto; margin-right: auto; } .cols-wrapper { margin: auto; clear: both; margin-top: 60px; margin-bottom: 60px; overflow: hidden; } .col-main-wrapper { float: left; width: 100%; } .col-main { margin-right: 278px; max-width: 660px; } .col-right { float: right; width: 248px; margin-left: -278px; } /* Tweaks for layout mode. */ body#layout .google-footer-outer { display: none; } body#layout .header-outer, body#layout .footer-outer { background: none; } body#layout .header-inner { height: initial; } body#layout .cols-wrapper { margin-top: initial; margin-bottom: initial; } --></style> <!-- start all head --> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='https://testing.googleblog.com/favicon.ico' rel='icon' type='image/x-icon'/> <link href='https://testing.googleblog.com/2008/07/' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Google Testing Blog - Atom" href="https://testing.googleblog.com/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Google Testing Blog - RSS" href="https://testing.googleblog.com/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Google Testing Blog - Atom" href="https://www.blogger.com/feeds/15045980/posts/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <meta content='https://testing.googleblog.com/2008/07/' property='og:url'/> <meta content='Google Testing Blog' property='og:title'/> <meta content='' property='og:description'/> <!-- end all head --> <base target='_self'/> <style> html { font-family: Roboto, sans-serif; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; } body { padding: 0; /* This ensures that the scroll bar is always present, which is needed */ /* because content render happens after page load; otherwise the header */ /* would "bounce" in-between states. */ min-height: 150%; } h2 { font-size: 20px; } h1, h2, h3, h4, h5 { line-height: 2em; } html, h4, h5, h6 { font-size: 17px; } h3 { font-size: 18px !important; } a, a:visited { color: #4184F3; text-decoration: none; } a:focus, a:hover, a:active { text-decoration: none; } .Header { margin-top: 15px; } .Header h1 { font-size: 32px; font-weight: 300; line-height: 32px; height: 42px; } .header-inner .Header .titlewrapper { padding: 0; margin-top: 30px; } .header-inner .Header .descriptionwrapper { padding: 0; margin: 0; } .cols-wrapper { margin-top: 56px; } .header-outer, .cols-wrapper, .footer-outer, .google-footer-outer { padding: 0 60px; } .header-inner { height: 256px; position: relative; } html, .header-inner a { color: #212121; color: rgba(0,0,0,.87); } .header-inner .google-logo { display: inline-block; background-size: contain; z-index: 1; height: 46px; overflow: hidden; margin-top: 4px; margin-right: 8px; } .header-left { position: absolute; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); margin-top: 12px; width: 100%; } .google-logo { margin-left: -4px; } #google-footer { position: relative; font-size: 13px; list-style: none; text-align: right; } #google-footer a { color: #444; } #google-footer ul { margin: 0; padding: 0; height: 144px; line-height: 144px; } #google-footer ul li { display: inline; } #google-footer ul li:before { color: #999; content: "\00b7"; font-weight: bold; margin: 5px; } #google-footer ul li:first-child:before { content: ''; } #google-footer .google-logo-dark { left: 0; margin-top: -16px; position: absolute; top: 50%; } /** Sitemap links. **/ .footer-inner-2 { font-size: 14px; padding-top: 42px; padding-bottom: 74px; } .footer-inner-2 .HTML h2 { color: #212121; color: rgba(0,0,0,.87); font-size: 14px; font-weight: 500; padding-left: 0; margin: 10px 0; } .footer-inner-2 .HTML ul { font-weight: normal; list-style: none; padding-left: 0; } .footer-inner-2 .HTML li { line-height: 24px; padding: 0; } .footer-inner-2 li a { color: rgba(65,132,243,.87); } /** Archive widget. **/ .BlogArchive { font-size: 13px; font-weight: normal; } .BlogArchive .widget-content { display: none; } .BlogArchive h2, .Label h2 { color: #4184F3; text-decoration: none; } .BlogArchive .hierarchy li { display: inline-block; } /* Specificity needed here to override widget CSS defaults. */ .BlogArchive #ArchiveList ul li, .BlogArchive #ArchiveList ul ul li { padding-left: 0; text-indent: 0; } .BlogArchive .intervalToggle { cursor: pointer; } .BlogArchive .expanded .intervalToggle .new-toggle { -ms-transform: rotate(180deg); transform: rotate(180deg); } .BlogArchive .new-toggle { float: right; padding-top: 3px; opacity: 0.87; } #ArchiveList { text-transform: uppercase; } #ArchiveList .expanded > ul:last-child { margin-bottom: 16px; } #ArchiveList .archivedate { width: 100%; } /* Months */ .BlogArchive .items { max-width: 150px; margin-left: -4px; } .BlogArchive .expanded .items { margin-bottom: 10px; overflow: hidden; } .BlogArchive .items > ul { float: left; height: 32px; } .BlogArchive .items a { padding: 0 4px; } .Label { font-size: 13px; font-weight: normal; } .sidebar-icon { display: inline-block; width: 24px; height: 24px; vertical-align: middle; margin-right: 12px; margin-top: -1px } .Label a { margin-right: 4px; } .Label .widget-content { display: none; } .FollowByEmail { font-size: 13px; font-weight: normal; } .FollowByEmail h2 { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAALCAYAAACZIGYHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUBJREFUeNrMkSGLAlEUhb+ZB4JFi8mx2cz+ApvhRUGTcUCrNqNJDYIi+DO0GUwmQXDK2DSIoGgZcSaIjDrzwrK4ssvChj1w0733O+fdp+m6PozH4yQSCfb7Pa7r8pOi0SjJZBLP8zgej4gAIMvlMuPxmADIYrHger1+C6lUKmo+NJ/NZojb7SZDWiwWo1qtks1msW2bw+HwZdkwDHq9HvV6nel0SqvVYrvdIh6Ph3Qch+VyqRYLhQJSSjRNw7IsfN9XgGKxSLfbJZfL0e/3aTabrFYr7vc7IujLcOh8PqunrNdr0uk0pVKJVCpFJBJRgEajweVyod1uMxgM2O12BAGUgRbU8DV2JpOhVquRz+cRQii3+XxOp9NRN3jVR5LPOp1OjEYjlSL8hclkgmmabDabt4d+m+S30vkD/R/IU4ABAPTZgnZdmG/PAAAAAElFTkSuQmCC"); background-repeat: no-repeat; background-position: 0 50%; text-indent: 30px; } .FollowByEmail .widget-content { display: none; } .searchBox input { border: 1px solid #eee; color: #212121; color: rgba(0,0,0,.87); font-size: 14px; padding: 8px 8px 8px 40px; width: 164px; font-family: Roboto, sans-serif; background: url("https://www.gstatic.com/images/icons/material/system/1x/search_grey600_24dp.png") 8px center no-repeat; } .searchBox ::-webkit-input-placeholder { /* WebKit, Blink, Edge */ color: rgba(0,0,0,.54); } .searchBox :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color: #000; opacity: 0.54; } .searchBox ::-moz-placeholder { /* Mozilla Firefox 19+ */ color: #000; opacity: 0.54; } .searchBox :-ms-input-placeholder { /* Internet Explorer 10-11 */ color: #757575; } .widget-item-control { margin-top: 0px; } .section { margin: 0; padding: 0; } #sidebar-top { border: 1px solid #eee; } #sidebar-top > div { margin: 16px 0; } .widget ul { line-height: 1.6; } /*main post*/ .post { margin-bottom:30px; } #main .post .title { margin: 0; } #main .post .title a { color: #212121; color: rgba(0,0,0,.87); font-weight: normal; font-size: 24px; } #main .post .title a:hover { text-decoration:none; color:#4184F3; } .message, #main .post .post-header { margin: 0; padding: 0; } #main .post .post-header .caption, #main .post .post-header .labels-caption, #main .post .post-footer .caption, #main .post .post-footer .labels-caption { color: #444; font-weight: 500; } #main .tr-caption-container td { text-align: left; } #main .post .tr-caption { color: #757575; color: rgba(0,0,0,.54); display: block; max-width: 560px; padding-bottom: 20px; } #main .post .tr-caption-container { line-height: 24px; margin: -1px 0 0 0 !important; padding: 4px 0; text-align: left; } #main .post .post-header .published{ font-size:11px; font-weight:bold; } .post-header .publishdate { font-size: 17px; font-weight:normal; color: #757575; color: rgba(0,0,0,.54); } #main .post .post-footer{ font-size:12px; padding-bottom: 21px; } .label-footer { margin-bottom: 12px; margin-top: 12px; } .comment-img { margin-right: 16px; opacity: 0.54; vertical-align: middle; } #main .post .post-header .published { margin-bottom: 40px; margin-top: -2px; } .post .post-content { color: #212121; color: rgba(0,0,0,.87); font-size: 17px; margin: 25px 0 36px 0; line-height: 32px; word-wrap: break-word; } .post-body .post-content ul, .post-body .post-content ol { margin: 16px 0; padding: 0 48px; } .post-summary { display: none; } /* Capture section headers. */ .post-content br + br + b, .post-content .space + .space + b, .post-content .separator + b { display: inline-block; margin-bottom: 8px; margin-top: 24px; } .post-content li { line-height: 32px; } /* Override all post images/videos to left align. */ .post-content .separator, .post-content > div { text-align: left; } .post-content .separator > a, .post-content .separator > span { margin-left: 0 !important; } .post-content img { max-width: 100%; } .post-content .tr-caption-container img { margin-bottom: 12px; } .post-content iframe, .post-content embed { max-width: 100%; } .post-content .carousel-container { margin-bottom: 48px; } #main .post-content b { font-weight: 500; } /* These are the main paragraph spacing tweaks. */ #main .post-content br { content: ' '; display: block; padding: 4px; } .post-content .space { display: block; height: 8px; } .post-content iframe + .space, .post-content iframe + br { padding: 0 !important; } #main .post .jump-link { margin-bottom:10px; } .post-content img, .post-content iframe { margin: 30px 0 20px 0; } .post-content > img:first-child, .post-content > iframe:first-child { margin-top: 0; } .col-right .section { padding: 0 16px; } #aside { background:#fff; border:1px solid #eee; border-top: 0; } #aside .widget { margin:0; } #aside .widget h2, #ArchiveList .toggle + a.post-count-link { color: #212121; color: rgba(0,0,0,.87); font-weight: 400 !important; margin: 0; } #ArchiveList .toggle { float: right; } #ArchiveList .toggle .material-icons { padding-top: 4px; } #sidebar .tab { cursor: pointer; } #sidebar .tab .arrow { display: inline-block; float: right; } #sidebar .tab .icon { display: inline-block; vertical-align: top; height: 24px; width: 24px; margin-right: 13px; margin-left: -1px; margin-top: 1px; color: #757575; color: rgba(0,0,0,.54); } #sidebar .widget-content > :first-child { padding-top: 8px; } #sidebar .active .tab .arrow { -ms-transform: rotate(180deg); transform: rotate(180deg); } #sidebar .arrow { color: #757575; color: rgba(0,0,0,.54); } #sidebar .widget h2 { font-size: 14px; line-height: 24px; display: inline-block; } #sidebar .widget .BlogArchive { padding-bottom: 8px; } #sidebar .widget { border-bottom: 1px solid #eee; box-shadow: 0px 1px 0 white; margin-bottom: 0; padding: 14px 0; min-height: 20px; } #sidebar .widget:last-child { border-bottom: none; box-shadow: none; margin-bottom: 0; } #sidebar ul { margin: 0; padding: 0; } #sidebar ul li { list-style:none; padding:0; } #sidebar ul li a { line-height: 32px; } #sidebar .archive { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAYCAYAAADzoH0MAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE1JREFUeNpiNDY23s9AAWBioBCwYBM8c+YMVsUmJibEGYBNMS5DaeMFfDYSZQA2v9I3FrB5AZeriI4FmnrBccCT8mhmGs1MwyAzAQQYAKEWG9zm9QFEAAAAAElFTkSuQmCC"); height: 24px; line-height: 24px; padding-left: 30px; } #sidebar .labels { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUxJREFUeNpiNDY23s9AAMycOfM7UF05kHkZmzwTMkdSUhKrIcXFxZy3bt3qBjIN8RrS09PDsHnzZjCNDr58+cKQlpbGDjSoHcg1w2oIyAUODg5gARCNzUVIBrUCuVYYhjx//pzhwIEDYAEQDeJjA1CDWIAGNQK59jBxRuSABbkAlwHIgIeHh2HWrFn/1NTU2oDcvSgBS4wBSC5iArqoCsj1YGIgEyAZVMoEchqlBjEB/cZAiUHg2AEGznpKDAImxOeM////B4VLKtBvEUCngZ1ILKivr3/u6+ubBzJAGZQ9gC5aQoqLgAY8BhkAZL4BuQQkxgXE34A4BuiiZEIuAhrwEGhAEZD5DpzYoIaA2UAM4kQADUrHZRDUgAIg8wO2XAwzbQXQa5OweQ1owB10AyA6gS7BgX1u3ry5397eHow3bdo0EyjGi00tQIABANPgyAH1q1eaAAAAAElFTkSuQmCC"); height: 20px; line-height: 20px; padding-left: 30px; } #sidebar .rss a { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAX5JREFUeNqsVDGSgkAQHL2rIiIikohIc/EBRkbwAIwuwgfwAXiAD9AHSI7kEkECRCb6AIyINDLx7K0aa6kT7uq0q7YYtnZ7umdnt7darXbr9Zpegeu61DNNc0dvwCcH4/GYJpMJnc9nOhwOVJbl/4hAAokMECZJQtvt9k+kH7qufyEYDAakqqqYxFdRFBqNRmTbNg2HQ0rTlK7XayvR0xqBdDqdkuM4dE/0ULhYLOh4PHYrknG5XGi/31MYhuL/nkwonM1mlGUZ1XXdrsiyLGEDhY7juJEZ1u5tIixDGdYhmYw+B7CAzPP5nDabjdgIAgCksMX1832/3drtdqPT6SQWapomiGEFNkDEdpDMMAzK81ys/7XYy+XyoQgq2WoURSIJ2iIIgp/WZCCTvFm2wgeAU31aI3Q2GhIDMeB53qPYPIcm5VrxXIOIOxsDMStjVawAc1VViRgN22lNBiuQN3GR+SY07hpOoStmFQAKXRRFY93bnpG+fONfedi+BRgAbkS8Fxp7QQIAAAAASUVORK5CYII="); } #sidebar .subscription a { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAALCAYAAACZIGYHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUBJREFUeNrMkSGLAlEUhb+ZB4JFi8mx2cz+ApvhRUGTcUCrNqNJDYIi+DO0GUwmQXDK2DSIoGgZcSaIjDrzwrK4ssvChj1w0733O+fdp+m6PozH4yQSCfb7Pa7r8pOi0SjJZBLP8zgej4gAIMvlMuPxmADIYrHger1+C6lUKmo+NJ/NZojb7SZDWiwWo1qtks1msW2bw+HwZdkwDHq9HvV6nel0SqvVYrvdIh6Ph3Qch+VyqRYLhQJSSjRNw7IsfN9XgGKxSLfbJZfL0e/3aTabrFYr7vc7IujLcOh8PqunrNdr0uk0pVKJVCpFJBJRgEajweVyod1uMxgM2O12BAGUgRbU8DV2JpOhVquRz+cRQii3+XxOp9NRN3jVR5LPOp1OjEYjlSL8hclkgmmabDabt4d+m+S30vkD/R/IU4ABAPTZgnZdmG/PAAAAAElFTkSuQmCC"); } #sidebar-bottom { background: #f5f5f5; border-top:1px solid #eee; } #sidebar-bottom .widget { border-bottom: 1px solid #e0e0e0; padding: 15px 0; text-align: center; } #sidebar-bottom > div:last-child { border-bottom: 0; } #sidebar-bottom .text { line-height: 20px; } /* Home, forward, and backward pagination. */ .blog-pager { border-top : 1px #e0e0e0 solid; padding-top: 10px; margin-top: 15px; text-align: right !important; } #blog-pager { margin-botom: 0; margin-top: -14px; padding: 16px 0 0 0; } #blog-pager a { display: inline-block; } .blog-pager i.disabled { opacity: 0.2 !important; } .blog-pager i { color: black; margin-left: 16px; opacity: 0.54; } .blog-pager i:hover, .blog-pager i:active { opacity: 0.87; } #blog-pager-older-link, #blog-pager-newer-link { float: none; } .gplus-profile { background-color: #fafafa; border: 1px solid #eee; overflow: hidden; width: 212px; } .gplus-profile-inner { margin-left: -1px; margin-top: -1px; } /* Sidebar follow buttons. */ .followgooglewrapper { padding: 12px 0 0 0; } .loading { visibility: hidden; } .detail-page .post-footer .cmt_iframe_holder { padding-top: 40px !important; } /** Desktop **/ @media (max-width: 900px) { .col-right { display: none; } .col-main { margin-right: 0; min-width: initial; } .footer-outer { display: none; } .cols-wrapper { min-width: initial; } .google-footer-outer { background-color: #f5f5f5; } } /** Tablet **/ @media (max-width: 712px) { .header-outer, .cols-wrapper, .footer-outer, .google-footer-outer { padding: 0 40px; } } /* An extra breakpoint accommodating for long blog titles. */ @media (max-width: 600px) { .header-left { height: 100%; position: initial; top: inherit; margin-top: 0; -webkit-transform: initial; transform: initial; } .header-title { margin-top: 18px; } .header-inner { height: auto; margin-bottom: 32px; margin-top: 32px; } .header-desc { margin-top: 12px; } .header-inner .google-logo { height: 40px; margin-top: 3px; } .header-inner .google-logo img { height: 42px; } .header-title h2 { font-size: 32px; line-height: 40px; } } /** Mobile/small desktop window; also landscape. **/ @media (max-width: 480px), (max-height: 480px) { .header-outer, .cols-wrapper, .footer-outer, .google-footer-outer { padding: 0 16px; } .cols-wrapper { margin-top: 0; } .post-header .publishdate, .post .post-content { font-size: 16px; } .post .post-content { line-height: 28px; margin-bottom: 30px; } .post { margin-top: 30px; } .byline-author { display: block; font-size: 12px; line-height: 24px; margin-top: 6px; } #main .post .title a { font-weight: 500; color: #4c4c4c; color: rgba(0,0,0,.70); } #main .post .post-header { padding-bottom: 12px; } #main .post .post-header .published { margin-bottom: -8px; margin-top: 3px; } .post .read-more { display: block; margin-top: 14px; } .post .tr-caption { font-size: 12px; } #main .post .title a { font-size: 20px; line-height: 30px; } .post-content iframe { /* iframe won't keep aspect ratio when scaled down. */ max-height: 240px; } .post-content .separator img, .post-content .tr-caption-container img, .post-content iframe { margin-left: -16px; max-width: inherit; width: calc(100% + 32px); } .post-content table, .post-content td { width: 100%; } #blog-pager { margin: 0; padding: 16px 0; } /** List page tweaks. **/ .list-page .post-original { display: none; } .list-page .post-summary { display: block; } .list-page .comment-container { display: none; } .list-page #blog-pager { padding-top: 0; border: 0; margin-top: -8px; } .list-page .label-footer { display: none; } .list-page #main .post .post-footer { border-bottom: 1px solid #eee; margin: -16px 0 0 0; padding: 0 0 20px 0; } .list-page .post .share { display: none; } /** Detail page tweaks. **/ .detail-page .post-footer .cmt_iframe_holder { padding-top: 32px !important; } .detail-page .label-footer { margin-bottom: 0; } .detail-page #main .post .post-footer { padding-bottom: 0; } .detail-page #comments { display: none; } } [data-about-pullquote], [data-is-preview], [data-about-syndication] { display: none; } </style> <noscript> <style> .loading { visibility: visible }</style> </noscript> <!-- Google tag (gtag.js) --> <script async='true' src='https://www.googletagmanager.com/gtag/js?id=G-838ZCPQWM6'></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-838ZCPQWM6'); </script> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=15045980&amp;zx=1da02fdc-f393-4bba-bcc4-96fe879b4516' media='none' onload='if(media!=&#39;all&#39;)media=&#39;all&#39;' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=15045980&amp;zx=1da02fdc-f393-4bba-bcc4-96fe879b4516' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> </head> <body> <script type='text/javascript'> //<![CDATA[ var axel = Math.random() + ""; var a = axel * 10000000000000; document.write('<iframe src="https://2542116.fls.doubleclick.net/activityi;src=2542116;type=gblog;cat=googl0;ord=ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>'); //]]> </script> <noscript> <img alt='' height='1' src='https://ad.doubleclick.net/ddm/activity/src=2542116;type=gblog;cat=googl0;ord=1?' width='1'/> </noscript> <!-- Header --> <div class='header-outer'> <div class='header-inner'> <div class='section' id='header'><div class='widget Header' data-version='1' id='Header1'> <div class='header-left'> <div class='header-title'> <a class='google-logo' href='https://testing.googleblog.com/'> <img height='50' src='https://www.gstatic.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png'/> </a> <a href='/.'> <h2> Testing Blog </h2> </a> </div> <div class='header-desc'> </div> </div> </div></div> </div> </div> <!-- all content wrapper start --> <div class='cols-wrapper loading'> <div class='col-main-wrapper'> <div class='col-main'> <div class='section' id='main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='post' data-id='7050115864048216306' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/circular-dependency-in-constructors-and.html' itemprop='url' title='Circular Dependency in constructors and Dependency Injection'> Circular Dependency in constructors and Dependency Injection </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Thursday, July 31, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> by <a href="http://misko.hevery.com/about/"><span class="blsp-spelling-error" id="SPELLING_ERROR_0">Miško</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_1">Hevery</span></a><br /><br />So you discovered dependency injection and <a href="http://code.google.com/p/google-guice/"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">GUICE</span></a> and you are happily <span class="blsp-spelling-error" id="SPELLING_ERROR_3">refactoring</span> and writing new tests for you code until you come across this circular reference.<br /><pre>class A {<br />final B b;<br />A(B b){<br /> this.b = b;<br />}<br />}<br /><br />class B {<br />final A a;<br />B(){<br /> this.a = new A(this);<br />}<br />}<br /><br />+---------+ +---------+<br />| A |<-----| B | | | | | | |----->| |<br />+---------+ +---------+</pre><br />Hm, dependency injection says that you need to ask for your dependencies and so the resulting code will be:<br /><pre>class A {<br />final B b;<br />A(B b){<br /> this.b = b;<br />}<br />}<br /><br />class B {<br />final A a;<br />B(A a){<br /> this.a = a;<br />}<br />}</pre><br />But now we have a problem, we can't instantiate this (I know <span class="blsp-spelling-error" id="SPELLING_ERROR_5">GUICE</span> can through proxy, but it is not clean and it does not help us in tests). So the real problem in situation like this is mixing of concerns. One of the two objects is hiding another object C. Either A contains C or B contains C. To find out which one it is, <em><strong>list all of the methods in your class A and class B and. The shorter of the two lists is your hidden Class C.</strong></em><br /><pre>+---------+ +---------+<br />| A |<-----| B | | | | | +-+ | | | | +->|C| |<br />| |------+---->| | |<br />| | | +-+ |<br />+---------+ +---------+</pre><br />Suppose B has the shorter list. We now extract all of the methods in B which are accessing the state of hidden C methods into a new object C like this:<br /><pre> +---------+<br />+---------+ | B |<br />| A |<-------------| | | | | | | | +---+ | | | |--->| C |<----| | | | +---+ +---------+ +---------+ class C { C(){ } } class A { final C c; A(C c){ this.c = c; } } class B { final A a; final C c; B(A a, C c){ this.a = a; this.c = c; } }</pre>When you go through this exercise you will realize that the C was always an object in its own right but you have never thought about it that way, so the new code is actually better <span class="blsp-spelling-error" id="SPELLING_ERROR_9">OO</span>. From testing point of view you can now test each class in isolation. <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> by <a href="http://misko.hevery.com/about/"><span class="blsp-spelling-error" id="SPELLING_ERROR_0">Miško</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_1">Hevery</span></a><br /><br />So you discovered dependency injection and <a href="http://code.google.com/p/google-guice/"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">GUICE</span></a> and you are happily <span class="blsp-spelling-error" id="SPELLING_ERROR_3">refactoring</span> and writing new tests for you code until you come across this circular reference.<br /><pre>class A {<br />final B b;<br />A(B b){<br /> this.b = b;<br />}<br />}<br /><br />class B {<br />final A a;<br />B(){<br /> this.a = new A(this);<br />}<br />}<br /><br />+---------+ +---------+<br />| A |<-----| B | | | | | | |----->| |<br />+---------+ +---------+</pre><br />Hm, dependency injection says that you need to ask for your dependencies and so the resulting code will be:<br /><pre>class A {<br />final B b;<br />A(B b){<br /> this.b = b;<br />}<br />}<br /><br />class B {<br />final A a;<br />B(A a){<br /> this.a = a;<br />}<br />}</pre><br />But now we have a problem, we can't instantiate this (I know <span class="blsp-spelling-error" id="SPELLING_ERROR_5">GUICE</span> can through proxy, but it is not clean and it does not help us in tests). So the real problem in situation like this is mixing of concerns. One of the two objects is hiding another object C. Either A contains C or B contains C. To find out which one it is, <em><strong>list all of the methods in your class A and class B and. The shorter of the two lists is your hidden Class C.</strong></em><br /><pre>+---------+ +---------+<br />| A |<-----| B | | | | | +-+ | | | | +->|C| |<br />| |------+---->| | |<br />| | | +-+ |<br />+---------+ +---------+</pre><br />Suppose B has the shorter list. We now extract all of the methods in B which are accessing the state of hidden C methods into a new object C like this:<br /><pre> +---------+<br />+---------+ | B |<br />| A |<-------------| | | | | | | | +---+ | | | |--->| C |<----| | | | +---+ +---------+ +---------+ class C { C(){ } } class A { final C c; A(C c){ this.c = c; } } class B { final A a; final C c; B(A a, C c){ this.a = a; this.c = c; } }</pre>When you go through this exercise you will realize that the C was always an object in its own right but you have never thought about it that way, so the new code is actually better <span class="blsp-spelling-error" id="SPELLING_ERROR_9">OO</span>. From testing point of view you can now test each class in isolation. <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:Circular Dependency in constructors and Dependency Injection&url=https://testing.googleblog.com/2008/07/circular-dependency-in-constructors-and.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/circular-dependency-in-constructors-and.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/circular-dependency-in-constructors-and.html#comments' style='font-weight: 500; text-decoration: underline;'>9 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/circular-dependency-in-constructors-and.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/Misko%20Hevery' rel='tag'> Misko Hevery </a> </span> </div> </div> </div> <div class='post' data-id='1425671639485176679' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/tott-testing-against-interfaces.html' itemprop='url' title='TotT: Testing Against Interfaces'> TotT: Testing Against Interfaces </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Friday, July 25, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> To quell a lingering feeling of inadequacy, you took the time to build your own planetary death ray, a veritable rite of passage in the engineering profession. Congratulations. And you were feeling pretty proud until the following weekend, when you purchased the limited-edition Star Wars trilogy with Ewok commentary, and upon watching the Death Star destroy Alderaan, you realized that you had made a bad decision: Your planetary death ray has a blue laser, but green lasers look so much cooler. But it's not a simple matter of going down to Radio Shack to purchase a green laser that you can swap into your existing death ray. You're going to have to build another planetary death ray from the ground-up to have a green laser, which is fine by you because owning two death rays instead of one will only make the neighbors more jealous.<br /><br />Both your planetary death rays should interoperate with a variety of other bed-wettingly awesome technology, so it's natural that they export the same Java API:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public interface PlanetaryDeathRay {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void aim(double xPosition, double yPosition);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public boolean fire(); /* call this if she says the rebel</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;base is on Dantooine */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">public class BlueLaserPlanetaryDeathRay</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;implements PlanetaryDeathRay { /* implementation here */ }</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">public class GreenLaserPlanetaryDeathRay</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;implements PlanetaryDeathRay { /* implementation here */ }</span><br /></p><br /><br />Testing both death rays is important so there are no major malfunctions, like destroying Omicron Persei VIII instead of Omicron Persei VII. You want to run the same tests against both implementations to ensure that they exhibit the same behavior &#8211; something you could easily do if you only once defined tests that run against any <span style="font-family:Courier New, monospace;">PlanetaryDeathRay</span> implementation. Start by writing the following abstract class that extends <span style="font-family:Courier New, monospace;">junit.framework.TestCase</span>:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public abstract class PlanetaryDeathRayTestCase</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;extends TestCase {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected PlanetaryDeathRay deathRay;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;@Override protected void setUp() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;deathRay = createDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;@Override protected void tearDown() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;deathRay = null;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected abstract PlanetaryDeathRay createDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* create the PlanetaryDeathRay to test */</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void testAim() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;/* write implementation-independent tests here against</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deathRay.aim() */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void testFire() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;/* write implementation-independent tests here against</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deathRay.fire() */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />Note that the setUp method gets the particular <span style="font-family:Courier New, monospace;">PlanetaryDeathRay</span> implementation to test from the abstract <span style="font-family:Courier New, monospace;">createDeathRay</span> method. A subclass needs to implement only this method to create a complete test: the <span style="font-family:Courier New, monospace;">testAim</span> and <span style="font-family:Courier New, monospace;">testFire</span> methods it inherits will be part of the test when it runs:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public class BlueLaserPlanetaryDeathRayTest</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;extends PlanetaryDeathRayTestCase {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected PlanetaryDeathRay createDeathRay() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;return new BlueLaserPlanetaryDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />You can easily add new tests to this class to test functionality specific to <span style="font-family:Courier New, monospace;">BlueLaserPlanetaryDeathRay</span>.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-07-24.pdf">this episode</a> of Testing on the Toilet and post it in your office. <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> To quell a lingering feeling of inadequacy, you took the time to build your own planetary death ray, a veritable rite of passage in the engineering profession. Congratulations. And you were feeling pretty proud until the following weekend, when you purchased the limited-edition Star Wars trilogy with Ewok commentary, and upon watching the Death Star destroy Alderaan, you realized that you had made a bad decision: Your planetary death ray has a blue laser, but green lasers look so much cooler. But it's not a simple matter of going down to Radio Shack to purchase a green laser that you can swap into your existing death ray. You're going to have to build another planetary death ray from the ground-up to have a green laser, which is fine by you because owning two death rays instead of one will only make the neighbors more jealous.<br /><br />Both your planetary death rays should interoperate with a variety of other bed-wettingly awesome technology, so it's natural that they export the same Java API:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public interface PlanetaryDeathRay {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void aim(double xPosition, double yPosition);</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public boolean fire(); /* call this if she says the rebel</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;base is on Dantooine */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">public class BlueLaserPlanetaryDeathRay</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;implements PlanetaryDeathRay { /* implementation here */ }</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">public class GreenLaserPlanetaryDeathRay</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;implements PlanetaryDeathRay { /* implementation here */ }</span><br /></p><br /><br />Testing both death rays is important so there are no major malfunctions, like destroying Omicron Persei VIII instead of Omicron Persei VII. You want to run the same tests against both implementations to ensure that they exhibit the same behavior &#8211; something you could easily do if you only once defined tests that run against any <span style="font-family:Courier New, monospace;">PlanetaryDeathRay</span> implementation. Start by writing the following abstract class that extends <span style="font-family:Courier New, monospace;">junit.framework.TestCase</span>:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public abstract class PlanetaryDeathRayTestCase</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;extends TestCase {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected PlanetaryDeathRay deathRay;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;@Override protected void setUp() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;deathRay = createDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;@Override protected void tearDown() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;deathRay = null;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected abstract PlanetaryDeathRay createDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* create the PlanetaryDeathRay to test */</span><br /><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void testAim() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;/* write implementation-independent tests here against</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deathRay.aim() */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;public void testFire() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;/* write implementation-independent tests here against</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deathRay.fire() */</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />Note that the setUp method gets the particular <span style="font-family:Courier New, monospace;">PlanetaryDeathRay</span> implementation to test from the abstract <span style="font-family:Courier New, monospace;">createDeathRay</span> method. A subclass needs to implement only this method to create a complete test: the <span style="font-family:Courier New, monospace;">testAim</span> and <span style="font-family:Courier New, monospace;">testFire</span> methods it inherits will be part of the test when it runs:<br /><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">public class BlueLaserPlanetaryDeathRayTest</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;extends PlanetaryDeathRayTestCase {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;protected PlanetaryDeathRay createDeathRay() {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;return new BlueLaserPlanetaryDeathRay();</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;}</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><br />You can easily add new tests to this class to test functionality specific to <span style="font-family:Courier New, monospace;">BlueLaserPlanetaryDeathRay</span>.<br /><br />Remember to download <a href="http://code.google.com/testing/TotT-2008-07-24.pdf">this episode</a> of Testing on the Toilet and post it in your office. <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:TotT: Testing Against Interfaces&url=https://testing.googleblog.com/2008/07/tott-testing-against-interfaces.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/tott-testing-against-interfaces.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/tott-testing-against-interfaces.html#comments' style='font-weight: 500; text-decoration: underline;'>7 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/tott-testing-against-interfaces.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/Java' rel='tag'> Java </a> , <a class='label' href='https://testing.googleblog.com/search/label/TotT' rel='tag'> TotT </a> </span> </div> </div> </div> <div class='post' data-id='1997301458069663637' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/how-to-write-3v1l-untestable-code.html' itemprop='url' title='How to Write 3v1L, Untestable Code'> How to Write 3v1L, Untestable Code </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Thursday, July 24, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> by <a href="http://misko.hevery.com/about/">Miško Hevery</a>, <a href="http://jawspeak.com/">Jonathan Wolter</a>, Russ Ruffer, Brad Cross, and lots of other test infected Googlers<br /><br />This guide lists principles that will help you write impossible to tests code. Or, avoiding these techniques will help you write code that can be tested.<br /><ul><br /><li> <strong>Make Your Own Dependencies</strong> - Instantiate objects using new in the middle of methods, don't pass the object in. This is evil because whenever you new up an object inside a block of code and then use it, anyone that wants to test that code is also forced to use that concrete object you new'ed up. They can't "inject" a dummy, fake, or other mock in to simplify the behavior or make assertions about what you do to it.</li><br /><li> <strong>Heavy Duty Constructors</strong> - Make constructors that do lots of work in them. The more work you do in the constructor, the hard it is to create your object in a test fixture. And if your constructor can construct other things that are hard themselves to construct, that's even better! You want the transitive dependencies of every constructor to be enormous. Enormous is hard to get under test.</li><br /><li> <strong>Depend on Concrete Classes</strong> - Tie things down to concrete classes - avoid interfaces wherever possible. (They let people substitute the concrete classes you're using for their own classes which would implement the same contract in the interface or abstract class. Testing do-gooders might want to do this to get your code under a test harness - don't let them!)</li><br /><li> <strong>Conditional Slalom</strong> - Always, always, feel good when writing lengthy <code>if</code> branches and <code>switch</code> statements. These increase the number of possible execution paths that tests will need to cover when exercising the code under test. The higher the Cyclomatic complexity, the harder it is to test! When someone suggests to use polymorphism instead of conditionals, laugh at their thoughtfulness towards testing. Make the branching both deep and wide: if you're not consistently at least 5 conditionals deep, you're spoon feeding testable code to the TDD zealots.</li><br /><li> <strong>Depend on Large Context Objects</strong> - Pass around ginormous context objects (or small ones with hard to construct contents). These will reduce the clarity of methods [myMethod(Context ctx) is less clear than myMethod(User user, Label label)]. For testing, the context objects will need to be created, populated, and passed around.</li><br /><li> <strong>Use Statics</strong> - Statics, statics everywhere! They put a great big crunch in testability. They can't be mocked, and are a smell that you've got a method without a home. OO zealots will say that a static method is a sign that one of the parameters should own the method. But you're being 3v1L!</li><br /><li> <strong>Use More Statics</strong> - Statics are a really powerful tool to bring TDD Infected engineers to their knees. Static methods can't be overridden in a subclass (sometimes subclassing a class and overriding methods is a technique for testing). When you use static methods, they can't be mocked using mocking libraries (nixing another trick up the pro-testing engineer's sleeve).</li><br /><li> <strong>Use Global Flags</strong> - Why call a method explicitly? Just like L Ron Hubbard, use "mind over matter" to set a flag in one part of your code, in order to cause an effect in a totally different part of your application (it's even more fun when you do it concurrently in different threads!). The testers will go crazy trying to figure out why all of a sudden a conditional that was evaluating true one minute is all of a sudden evaluating to false.</li><br /><li> <strong>Use Singletons Everywhere</strong> - Why pass in a dependency and make it obvious when you can use a singleton? It's hard to set up a test that requires singletons, and the TDDers will be in for a world of hurt when all their tests depend on each other's state.</li><br /><li> <strong>Be Defensive - They're out to Get Your Code!</strong> - Defensively assert about the state of parameters passed in methods, constructors, and mid-method. If someone can pass in a null, you've left your guard down. You see, there are testing freaks out there that like to instantiate your object, or call a method under test and pass in nulls! Be aggressive in preventing this: rule your code with an iron fist! (And remember: it's not paranoia if <em>they really are out to get you</em>.)</li><br /><li> <strong>Use Primitives Wherever Possible</strong> - Instead of using a "cookie object," pass in primitives and do all the parsing you need, every time you need a value. Primitives make people work harder by having to parse and massage them to get the data out -- where objects are mockable (gasp) and nullable, and encapsulate state (who'd want to do that?)</li><br /><li> <strong>Look for Everything You Need</strong> - By Looking for things you are asserting your objects dominance as the object which knows where everything is. This will make the life of tester hard, since he will have to mimic the environment so that your code can get a hold of what it needs. And don't be afraid of how many objects you need to reach out to to, the more the harder it will be for test to mock them all out in unisin. If you are an InvoiceTaxCalculator, feel free to do things like: invoiceTaxCalculator.getUser().getDbManager().getCaRateTables().getSalesTaxRate(). Cover your ears when some testing weenie tells you about <a href="http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/" target="_self">Dependency Injection</a>, <a href="http://misko.hevery.com/2008/07/18/breaking-the-law-of-demeter-is-like-looking-for-a-needle-in-the-haystack/" target="_self">Law of Demeter</a>, or not looking for things.</li><br /><li> <strong>Use static initializes</strong> - Do as much work as possible when your class is loaded. Testing nuts will be so frustrated when they find out just loading your class causes nasty stuff like network or file access.</li><br /><li> <strong>Couple functional code directly to the external systems it depends on</strong> If your product uses external systems such as a databases, file systems or a network, make sure your business logic is coded to reference as many low level implementation details of these systems as possible. This will prevent others from using your code in ways you don't intend, (like small tests that run in 2 ms instead of 5 minutes).</li><br /><li> <strong>Mix Object Lifecycles</strong> - Have long lived objects reference short lived objects. This confuses people as the long lived object references the short lived object still after it's no longer valid or alive. This is especially insidious, both bad design, and evil, hard to test.<a name="Side_Effects_are_the_Way_to_Go"></a></li><br /><li><strong>Side Effects are the Way to Go</strong> Your best bet is to perform a large number of side effect producing operations in your methods. This is especially true for setters. The more non-obvious the side effects better. Peculiar and seemingly irrational side effects are particularly helpful for unit testing. To add another layer of sweet creamy goodness on top, you want to make it possible to initialize your objects in an invalid state, with uninitialized member fields. Once you have achieved this, be sure to make calls on the methods of the uninitialized fields as side effects from your setters in order to cause SEGV's or NPE's, depending on your language's vernacular. Why go to all this trouble? Clean, readable, and testable code that works, that's why! Side effect free functions are for intellectual weaklings that think a function name should give some kind of an indication of what the function does.</li><br /><li> <strong>Create Utility Classes and Functions/Methods</strong> - For instance, you have a String which is a URL you're passing around (obeying "Use Primitives Wherever Possible"). Create another class with static methods such as isValidUrl(String url). Don't let the OO police tell you to make that a method on a URL object. And if your static utility methods can call to external services as well, that's even better!</li><br /><li> <strong>Create Managers and Controllers</strong> - all over the place have these Managers and Controllers meddling in the responsibilities of other objects. Don't bother trying to pull that responsibility into other individual objects. Look at a SomeObjectManager class and you have no idea what it's going to do.</li><br /><li> <strong>Do Complicated Creation Work in Objects</strong> - Whenever someone suggests you to use a Factory to instantiate things, know that you are smarter than them. You're more intelligent than they must be, because your objects can have multiple responsibilities and be thousands of lines long.</li><br /><li> <strong>Greenlight if-branches and switch statements</strong> - Go ahead, don't feel dirty about nesting if-branches. It's "more readable" that way. OO cowboys will want to have a whole polymorphic soup of collaborating objects. Say no to the OO-ist. When you nest and branch conditionals, all you need to do is read the code from top to bottom. Like a great novel, one simple linear prose of code. With the OO-overboard paradigm, it's like a terrible choose-your-own-adventure kid's book. You're constantly flipping between classes and juggling patterns and so many more complex concepts. Just if-things out and you'll be fine.</li><br /><li> <strong>Utils, Utils, Utils!</strong> - Code smell? No way - code perfume! Litter about as many util and helper classes as you wish. These folks are helpful, and when you stick them off somewhere, someone else can use them too. That's code reuse, and good for everyone, right? Be forewarned, the OO-police will say that functionality belongs in some object, as that object's responsibility. Forget it, you're way to pragmatic to break things down like they want. You've got a product to ship after all!</li><br /><li> <strong>Use "Refactoring" whenever you need to get away with something</strong> - This is a word that Test-Driven and OO-goons like. So if you want to do something far reaching, involving new functionality, without tests, just tell them you're "Refactoring." It'll trick them every time. No matter that they think you need to have tests around everything before you can refactor, and that it should never add new functionality. Ignore their hubbub, and do things your own way!</li></ul><h3>Java Specific<br /></h3><ul><li> <strong>Final Methods</strong> - Use final classes and methods all the time. They can't be overridden for testing (-; But don't bother making fields final, or using value objects (without setters) - just let your objects' state be changed by anything and anyone. No sense in guaranteeing state, it'd make things too easy.</li><br /><li> <strong>Handcuff your users to Specific Types</strong> - Use <code>instanceof</code> as much as possible. This will make Mocking a pain, and show people that you're in control of the objects allowed.</li></ul><h3>C++ Specific</h3><ul><li> <strong>Use non-virtual methods</strong> - Unless you need to override the method in a deep and scary inheritance hierarchy, just make the method non-virtual. If you make it virtual, a TDD zealot may mock your class! An even nicer trick is to keep your destructor non-virtual - then when the testing freaks try to subclass, whooooaoaaaaaa....</li><br /><li> <strong>Never use pure abstract classes</strong> - Depending on pure abstract classes is a sure-fire way to let the TDD crazies inject stubs and mocks into your code, making it testable.</li><br /><li> <strong>Macros are your friends</strong> - Always use <code>#ifdef PROD</code> and other compile-time switches to make sure the testies can't get at your really important blocks of code and test them. In fact, this code won't even run: until it gets to production!</li><br /></ul> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> by <a href="http://misko.hevery.com/about/">Miško Hevery</a>, <a href="http://jawspeak.com/">Jonathan Wolter</a>, Russ Ruffer, Brad Cross, and lots of other test infected Googlers<br /><br />This guide lists principles that will help you write impossible to tests code. Or, avoiding these techniques will help you write code that can be tested.<br /><ul><br /><li> <strong>Make Your Own Dependencies</strong> - Instantiate objects using new in the middle of methods, don't pass the object in. This is evil because whenever you new up an object inside a block of code and then use it, anyone that wants to test that code is also forced to use that concrete object you new'ed up. They can't "inject" a dummy, fake, or other mock in to simplify the behavior or make assertions about what you do to it.</li><br /><li> <strong>Heavy Duty Constructors</strong> - Make constructors that do lots of work in them. The more work you do in the constructor, the hard it is to create your object in a test fixture. And if your constructor can construct other things that are hard themselves to construct, that's even better! You want the transitive dependencies of every constructor to be enormous. Enormous is hard to get under test.</li><br /><li> <strong>Depend on Concrete Classes</strong> - Tie things down to concrete classes - avoid interfaces wherever possible. (They let people substitute the concrete classes you're using for their own classes which would implement the same contract in the interface or abstract class. Testing do-gooders might want to do this to get your code under a test harness - don't let them!)</li><br /><li> <strong>Conditional Slalom</strong> - Always, always, feel good when writing lengthy <code>if</code> branches and <code>switch</code> statements. These increase the number of possible execution paths that tests will need to cover when exercising the code under test. The higher the Cyclomatic complexity, the harder it is to test! When someone suggests to use polymorphism instead of conditionals, laugh at their thoughtfulness towards testing. Make the branching both deep and wide: if you're not consistently at least 5 conditionals deep, you're spoon feeding testable code to the TDD zealots.</li><br /><li> <strong>Depend on Large Context Objects</strong> - Pass around ginormous context objects (or small ones with hard to construct contents). These will reduce the clarity of methods [myMethod(Context ctx) is less clear than myMethod(User user, Label label)]. For testing, the context objects will need to be created, populated, and passed around.</li><br /><li> <strong>Use Statics</strong> - Statics, statics everywhere! They put a great big crunch in testability. They can't be mocked, and are a smell that you've got a method without a home. OO zealots will say that a static method is a sign that one of the parameters should own the method. But you're being 3v1L!</li><br /><li> <strong>Use More Statics</strong> - Statics are a really powerful tool to bring TDD Infected engineers to their knees. Static methods can't be overridden in a subclass (sometimes subclassing a class and overriding methods is a technique for testing). When you use static methods, they can't be mocked using mocking libraries (nixing another trick up the pro-testing engineer's sleeve).</li><br /><li> <strong>Use Global Flags</strong> - Why call a method explicitly? Just like L Ron Hubbard, use "mind over matter" to set a flag in one part of your code, in order to cause an effect in a totally different part of your application (it's even more fun when you do it concurrently in different threads!). The testers will go crazy trying to figure out why all of a sudden a conditional that was evaluating true one minute is all of a sudden evaluating to false.</li><br /><li> <strong>Use Singletons Everywhere</strong> - Why pass in a dependency and make it obvious when you can use a singleton? It's hard to set up a test that requires singletons, and the TDDers will be in for a world of hurt when all their tests depend on each other's state.</li><br /><li> <strong>Be Defensive - They're out to Get Your Code!</strong> - Defensively assert about the state of parameters passed in methods, constructors, and mid-method. If someone can pass in a null, you've left your guard down. You see, there are testing freaks out there that like to instantiate your object, or call a method under test and pass in nulls! Be aggressive in preventing this: rule your code with an iron fist! (And remember: it's not paranoia if <em>they really are out to get you</em>.)</li><br /><li> <strong>Use Primitives Wherever Possible</strong> - Instead of using a "cookie object," pass in primitives and do all the parsing you need, every time you need a value. Primitives make people work harder by having to parse and massage them to get the data out -- where objects are mockable (gasp) and nullable, and encapsulate state (who'd want to do that?)</li><br /><li> <strong>Look for Everything You Need</strong> - By Looking for things you are asserting your objects dominance as the object which knows where everything is. This will make the life of tester hard, since he will have to mimic the environment so that your code can get a hold of what it needs. And don't be afraid of how many objects you need to reach out to to, the more the harder it will be for test to mock them all out in unisin. If you are an InvoiceTaxCalculator, feel free to do things like: invoiceTaxCalculator.getUser().getDbManager().getCaRateTables().getSalesTaxRate(). Cover your ears when some testing weenie tells you about <a href="http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/" target="_self">Dependency Injection</a>, <a href="http://misko.hevery.com/2008/07/18/breaking-the-law-of-demeter-is-like-looking-for-a-needle-in-the-haystack/" target="_self">Law of Demeter</a>, or not looking for things.</li><br /><li> <strong>Use static initializes</strong> - Do as much work as possible when your class is loaded. Testing nuts will be so frustrated when they find out just loading your class causes nasty stuff like network or file access.</li><br /><li> <strong>Couple functional code directly to the external systems it depends on</strong> If your product uses external systems such as a databases, file systems or a network, make sure your business logic is coded to reference as many low level implementation details of these systems as possible. This will prevent others from using your code in ways you don't intend, (like small tests that run in 2 ms instead of 5 minutes).</li><br /><li> <strong>Mix Object Lifecycles</strong> - Have long lived objects reference short lived objects. This confuses people as the long lived object references the short lived object still after it's no longer valid or alive. This is especially insidious, both bad design, and evil, hard to test.<a name="Side_Effects_are_the_Way_to_Go"></a></li><br /><li><strong>Side Effects are the Way to Go</strong> Your best bet is to perform a large number of side effect producing operations in your methods. This is especially true for setters. The more non-obvious the side effects better. Peculiar and seemingly irrational side effects are particularly helpful for unit testing. To add another layer of sweet creamy goodness on top, you want to make it possible to initialize your objects in an invalid state, with uninitialized member fields. Once you have achieved this, be sure to make calls on the methods of the uninitialized fields as side effects from your setters in order to cause SEGV's or NPE's, depending on your language's vernacular. Why go to all this trouble? Clean, readable, and testable code that works, that's why! Side effect free functions are for intellectual weaklings that think a function name should give some kind of an indication of what the function does.</li><br /><li> <strong>Create Utility Classes and Functions/Methods</strong> - For instance, you have a String which is a URL you're passing around (obeying "Use Primitives Wherever Possible"). Create another class with static methods such as isValidUrl(String url). Don't let the OO police tell you to make that a method on a URL object. And if your static utility methods can call to external services as well, that's even better!</li><br /><li> <strong>Create Managers and Controllers</strong> - all over the place have these Managers and Controllers meddling in the responsibilities of other objects. Don't bother trying to pull that responsibility into other individual objects. Look at a SomeObjectManager class and you have no idea what it's going to do.</li><br /><li> <strong>Do Complicated Creation Work in Objects</strong> - Whenever someone suggests you to use a Factory to instantiate things, know that you are smarter than them. You're more intelligent than they must be, because your objects can have multiple responsibilities and be thousands of lines long.</li><br /><li> <strong>Greenlight if-branches and switch statements</strong> - Go ahead, don't feel dirty about nesting if-branches. It's "more readable" that way. OO cowboys will want to have a whole polymorphic soup of collaborating objects. Say no to the OO-ist. When you nest and branch conditionals, all you need to do is read the code from top to bottom. Like a great novel, one simple linear prose of code. With the OO-overboard paradigm, it's like a terrible choose-your-own-adventure kid's book. You're constantly flipping between classes and juggling patterns and so many more complex concepts. Just if-things out and you'll be fine.</li><br /><li> <strong>Utils, Utils, Utils!</strong> - Code smell? No way - code perfume! Litter about as many util and helper classes as you wish. These folks are helpful, and when you stick them off somewhere, someone else can use them too. That's code reuse, and good for everyone, right? Be forewarned, the OO-police will say that functionality belongs in some object, as that object's responsibility. Forget it, you're way to pragmatic to break things down like they want. You've got a product to ship after all!</li><br /><li> <strong>Use "Refactoring" whenever you need to get away with something</strong> - This is a word that Test-Driven and OO-goons like. So if you want to do something far reaching, involving new functionality, without tests, just tell them you're "Refactoring." It'll trick them every time. No matter that they think you need to have tests around everything before you can refactor, and that it should never add new functionality. Ignore their hubbub, and do things your own way!</li></ul><h3>Java Specific<br /></h3><ul><li> <strong>Final Methods</strong> - Use final classes and methods all the time. They can't be overridden for testing (-; But don't bother making fields final, or using value objects (without setters) - just let your objects' state be changed by anything and anyone. No sense in guaranteeing state, it'd make things too easy.</li><br /><li> <strong>Handcuff your users to Specific Types</strong> - Use <code>instanceof</code> as much as possible. This will make Mocking a pain, and show people that you're in control of the objects allowed.</li></ul><h3>C++ Specific</h3><ul><li> <strong>Use non-virtual methods</strong> - Unless you need to override the method in a deep and scary inheritance hierarchy, just make the method non-virtual. If you make it virtual, a TDD zealot may mock your class! An even nicer trick is to keep your destructor non-virtual - then when the testing freaks try to subclass, whooooaoaaaaaa....</li><br /><li> <strong>Never use pure abstract classes</strong> - Depending on pure abstract classes is a sure-fire way to let the TDD crazies inject stubs and mocks into your code, making it testable.</li><br /><li> <strong>Macros are your friends</strong> - Always use <code>#ifdef PROD</code> and other compile-time switches to make sure the testies can't get at your really important blocks of code and test them. In fact, this code won't even run: until it gets to production!</li><br /></ul> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:How to Write 3v1L, Untestable Code&url=https://testing.googleblog.com/2008/07/how-to-write-3v1l-untestable-code.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/how-to-write-3v1l-untestable-code.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/how-to-write-3v1l-untestable-code.html#comments' style='font-weight: 500; text-decoration: underline;'>31 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/how-to-write-3v1l-untestable-code.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/Misko%20Hevery' rel='tag'> Misko Hevery </a> </span> </div> </div> </div> <div class='post' data-id='276719960416223477' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/breaking-law-of-demeter-is-like-looking.html' itemprop='url' title='Breaking the Law of Demeter is Like Looking for a Needle in the Haystack'> Breaking the Law of Demeter is Like Looking for a Needle in the Haystack </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Monday, July 21, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> by <a href="http://misko.hevery.com/about/">Miško Hevery</a> Every time I see <a href="http://en.wikipedia.org/wiki/Law_of_Demeter" target="_blank">Law of Demeter</a> violation I imagine a haystack where the code is desperately trying to locate the needle. <pre class="code">class Mechanic { Engine engine; Mechanic(Context context) { this.engine = context.getEngine(); } }</pre> The <tt>Mechanic</tt> does not care for the <tt>Context</tt>. You can tell because <tt>Mechanic</tt> does not store the reference to <tt>Context</tt>. Instead the <tt>Mechanic</tt> traverses the <tt>Context</tt> and looks for what it really needs, the <tt>Engine</tt>. So what is wrong with code like this you say? The problems with such code are very subtle: <ul> <li>Most applications tend to have some sort of <tt>Context</tt> object which is the kitchen sink and which can get you just about any other object in the system aka the service locator.</li> <li>If you want to reuse this code in a different project, the compiler will not only need <tt>Mechanic</tt> and <tt>Engine</tt> but also the <tt>Context</tt>. But <tt>Context</tt> is the kitchen sink of your application. It tends to reference to just about every other class in your system, hence the compiler will need those classes too. This kind of code is not very reusable.</li> <li>Even if you don't plan to reuse the code, the <tt>Context</tt> has high coupling with the rest of the system. Coupling is transitive, this means <tt>Mechanic</tt> inherits all of the badness through association.</li> <li>Your JavaDoc is not very useful! Yes, by examining the API I can see that the Mechanic needs <tt>Context</tt>, but <tt>Context</tt> is the kitchen sink. What does the mechanic really need? (If you don't have source code nearby, it may be hard to figure out).</li> </ul> <div style="display: inline; float: right; margin: 5px 5pt 5px 5px;"><img alt="" class="alignright size-medium wp-image-100" height="144" src="https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_t0x8InZf2TEON-Jt5bQ1DeOld5ouIsJYyz0a36f2SrhhaU0U5iUqDxG9TqXC8QjmfD0QXHW3Z-Efu3mrwE7qhQcAURh_1QP_Hg5DrTLYeKw8yAQVMduoR3eiOhS98UbM2qFz6aDBL8=s0-d" style="border: 1px solid black; margin-left: 5px; margin-right: 5px;" title="needle" width="96"></div> But here is the real killer! Writing tests for such code base sucks! <ul> <li>Every time I have to write a test I have to create a graph of objects (the haystack) which no one really needs or cares for, and into this haystack I have to carefully place the needles (the real object of interests) so that the code under test can go and look for them. I have to create the <tt>Context</tt> just so when I construct the <tt>Mechanic</tt> it can reach in the <tt>Context</tt> and get what it realy needs, the <tt>Engine</tt>. But context is never something which is easy to create. Since context is a kitchen sink which knows just about everything else, its constructor is usually scary. So most of the time I can't even instantiate Mechanic, not to mention run any tests on it. The testing game is over before it even started.</li> <li>Ok, but today we have fancy tools such as <a href="http://jmock.org/" target="_blank">JMock</a> and <a href="http://www.easymock.org/" target="_blank">EasyMock</a>, surely i can mock out <tt>Context</tt>. Yes, you can! BUT: (1) typical setup of a mock is about 5 lines of code. So your test will contain a lot of junk which will mask the real purpose of the test. (2) These tests will be fragile. Every time you refactor something in context, or how context interacts, you are running the risk of breaking your tests. (False negatives) (3) What if you want to test the class <tt>Shop</tt> which needs a reference to <tt>Mechanic</tt>? Well then you have to mock out <tt>Context</tt> again. This mocking tax will be spread all over your tests. In the end the mocking setup will drown out your tests and make for one unreadable test base.</li> </ul> Please stop looking for the needle in the haystack and just ask for the things you directly need in your code. You will thank me later... <pre>class Mechanic { Engine engine; Mechanic(Engine engine) { this.engine = engine; } }</pre> PS: Now imagine how hard will it be to write a test for this class: <pre class="code">class Monitor { SparkPlug sparkPlug; Monitor(Context context) { this.sparkPlug = context. getCar().getEngine(). getPiston().getSparkPlug(); } }</pre> GOOD LUCK! <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> by <a href="http://misko.hevery.com/about/">Miško Hevery</a> Every time I see <a href="http://en.wikipedia.org/wiki/Law_of_Demeter" target="_blank">Law of Demeter</a> violation I imagine a haystack where the code is desperately trying to locate the needle. <pre class="code">class Mechanic { Engine engine; Mechanic(Context context) { this.engine = context.getEngine(); } }</pre> The <tt>Mechanic</tt> does not care for the <tt>Context</tt>. You can tell because <tt>Mechanic</tt> does not store the reference to <tt>Context</tt>. Instead the <tt>Mechanic</tt> traverses the <tt>Context</tt> and looks for what it really needs, the <tt>Engine</tt>. So what is wrong with code like this you say? The problems with such code are very subtle: <ul> <li>Most applications tend to have some sort of <tt>Context</tt> object which is the kitchen sink and which can get you just about any other object in the system aka the service locator.</li> <li>If you want to reuse this code in a different project, the compiler will not only need <tt>Mechanic</tt> and <tt>Engine</tt> but also the <tt>Context</tt>. But <tt>Context</tt> is the kitchen sink of your application. It tends to reference to just about every other class in your system, hence the compiler will need those classes too. This kind of code is not very reusable.</li> <li>Even if you don't plan to reuse the code, the <tt>Context</tt> has high coupling with the rest of the system. Coupling is transitive, this means <tt>Mechanic</tt> inherits all of the badness through association.</li> <li>Your JavaDoc is not very useful! Yes, by examining the API I can see that the Mechanic needs <tt>Context</tt>, but <tt>Context</tt> is the kitchen sink. What does the mechanic really need? (If you don't have source code nearby, it may be hard to figure out).</li> </ul> <div style="display: inline; float: right; margin: 5px 5pt 5px 5px;"><img alt="" class="alignright size-medium wp-image-100" height="144" src="https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_t0x8InZf2TEON-Jt5bQ1DeOld5ouIsJYyz0a36f2SrhhaU0U5iUqDxG9TqXC8QjmfD0QXHW3Z-Efu3mrwE7qhQcAURh_1QP_Hg5DrTLYeKw8yAQVMduoR3eiOhS98UbM2qFz6aDBL8=s0-d" style="border: 1px solid black; margin-left: 5px; margin-right: 5px;" title="needle" width="96"></div> But here is the real killer! Writing tests for such code base sucks! <ul> <li>Every time I have to write a test I have to create a graph of objects (the haystack) which no one really needs or cares for, and into this haystack I have to carefully place the needles (the real object of interests) so that the code under test can go and look for them. I have to create the <tt>Context</tt> just so when I construct the <tt>Mechanic</tt> it can reach in the <tt>Context</tt> and get what it realy needs, the <tt>Engine</tt>. But context is never something which is easy to create. Since context is a kitchen sink which knows just about everything else, its constructor is usually scary. So most of the time I can't even instantiate Mechanic, not to mention run any tests on it. The testing game is over before it even started.</li> <li>Ok, but today we have fancy tools such as <a href="http://jmock.org/" target="_blank">JMock</a> and <a href="http://www.easymock.org/" target="_blank">EasyMock</a>, surely i can mock out <tt>Context</tt>. Yes, you can! BUT: (1) typical setup of a mock is about 5 lines of code. So your test will contain a lot of junk which will mask the real purpose of the test. (2) These tests will be fragile. Every time you refactor something in context, or how context interacts, you are running the risk of breaking your tests. (False negatives) (3) What if you want to test the class <tt>Shop</tt> which needs a reference to <tt>Mechanic</tt>? Well then you have to mock out <tt>Context</tt> again. This mocking tax will be spread all over your tests. In the end the mocking setup will drown out your tests and make for one unreadable test base.</li> </ul> Please stop looking for the needle in the haystack and just ask for the things you directly need in your code. You will thank me later... <pre>class Mechanic { Engine engine; Mechanic(Engine engine) { this.engine = engine; } }</pre> PS: Now imagine how hard will it be to write a test for this class: <pre class="code">class Monitor { SparkPlug sparkPlug; Monitor(Context context) { this.sparkPlug = context. getCar().getEngine(). getPiston().getSparkPlug(); } }</pre> GOOD LUCK! <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:Breaking the Law of Demeter is Like Looking for a Needle in the Haystack&url=https://testing.googleblog.com/2008/07/breaking-law-of-demeter-is-like-looking.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/breaking-law-of-demeter-is-like-looking.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/breaking-law-of-demeter-is-like-looking.html#comments' style='font-weight: 500; text-decoration: underline;'>10 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/breaking-law-of-demeter-is-like-looking.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/Misko%20Hevery' rel='tag'> Misko Hevery </a> </span> </div> </div> </div> <div class='post' data-id='9107537524752361033' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/yui-and-gwt-how-do-you-test.html' itemprop='url' title='YUI and GWT... How do you test?'> YUI and GWT... How do you test? </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Monday, July 21, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <span class="byline-author">Posted by Patrick Copeland, Engineering Productivity Director<br /><br />A smart person once said that, "all computer science problems can be solved by introducing another abstraction layer." From a testing perspective, every new abstraction layer also introduces every problem in computer science.<br /><br />Frank Cohen, of PushToTest, wrote a blog post recently that focuses on the Google Web Tool Kit and puts the challange of dealing new abstration layers into a brief historical perspective.<br /><br /><a href="http://tinyurl.com/6r34jf">http://tinyurl.com/6r34jf</a><br /></span> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <span class="byline-author">Posted by Patrick Copeland, Engineering Productivity Director<br /><br />A smart person once said that, "all computer science problems can be solved by introducing another abstraction layer." From a testing perspective, every new abstraction layer also introduces every problem in computer science.<br /><br />Frank Cohen, of PushToTest, wrote a blog post recently that focuses on the Google Web Tool Kit and puts the challange of dealing new abstration layers into a brief historical perspective.<br /><br /><a href="http://tinyurl.com/6r34jf">http://tinyurl.com/6r34jf</a><br /></span> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:YUI and GWT... How do you test?&url=https://testing.googleblog.com/2008/07/yui-and-gwt-how-do-you-test.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/yui-and-gwt-how-do-you-test.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/yui-and-gwt-how-do-you-test.html#comments' style='font-weight: 500; text-decoration: underline;'>5 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/yui-and-gwt-how-do-you-test.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/Patrick%20Copeland' rel='tag'> Patrick Copeland </a> </span> </div> </div> </div> <div class='post' data-id='602767139745848618' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/call-for-attendance-gtac-2008.html' itemprop='url' title='Call for Attendance: GTAC 2008'> Call for Attendance: GTAC 2008 </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Tuesday, July 15, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <span class="byline-author">Posted by Lydia Ash, Test Engineering Manager </span><br /><br /><span style="font-weight: bold;">Call for Attendance</span><span style="font-weight: bold;"><br />Google Test Automation Conference 2008</span><span style="font-weight: bold;"><br />Seattle, WA</span><span style="font-weight: bold;"><br />October 23 - 24</span><br /><br />Google's Test Automation Conference is built on our participants each bringing their experience, ideas, and insight to the discussions we host. Our participants are all experienced industry professionals working as software development engineers or software testing engineers. For the limited number of spaces available in each year's conference, we ask each applicant to share what they would bring to the discussions as an active participant in the conference.<br /><br />To apply for a participant space at the GTAC 2008 conference, you can apply:<br /><div style="text-align: center;"><a href="http://services.google.com/events/gtac2008">http://services.google.com/events/gtac2008</a><br /><br /></div><span style="font-weight: bold;">Timeline</span><br /><ul><li>Deadline for applying as a participant: August 15</li><li>Notification of acceptance: August 29</li><li>Wait list callbacks: October 3</li><li>GTAC 2008 Conference: October 23 and 24</li></ul><br /><span style="font-weight: bold;">Scheduled Presentations</span><br /><ul><li>Atom Publishing Protocol, Testing a Server Implementation by David Calavera</li><li>JInjector: a Coverage and End-To-End Testing Framework for J2ME and RIM by Julian Harty, Olivier Gaillard, and Michael Sama</li><li>Advances in Automated Software Testing Technologies by Elfriede Dustin</li><li>Taming the Beast: How to test an AJAX Application by Markus Clermont and John Thomas</li><li>Automated Model-Based Testing of Web Applications by Oluwaseun Akinmade and Prof. Atif M Memon</li><li>Boosting Your Testing Productivity with Groovy by Andres Almiray</li><li>Practicing Testability in the Real World by Vishal Chowdhary</li><li>The New Genomics: Software Development at Petabyte Scale by Matt Wood</li><li>The Value of Small Tests by Christopher Semturs</li><li>Deployment and Test Automation: Extending the Notion of 'Done' to 'System Tested on a Production Deployment' by Marc-Elian Begin</li></ul><span style="font-weight: bold;">No Registration Fees</span><br />The GTAC conference has no registration fees. Once invitations have been sent to participate, full registration instructions will be sent to each invitee. Breakfast and lunch will be provided each day of the conference, as well as a reception the evening of October 23.<br /><br /><span style="font-weight: bold;">Cancellation</span><br />If you register as a participant and will not be able to attend, please send email immediately to <a href="mailto:gtac@google.com">gtac@google.com</a> to allow a wait list person the opportunity to participate in that slot.<br /><br /><span style="font-weight: bold;">Hotel Accommodations</span><br /><a href="http://www.starwoodhotels.com/whotels/property/overview/index.html?propertyID=1154">W Seattle</a> (Conference Venue)<br />1112 Fourth Avenue<br />Seattle, WA 98101<br />(206) 264-6000<br /><br />Other Hotels in the Area<br />Hotel Vintage Park<br />1100 5th Ave<br />Seattle, WA<br />(206) 624-8000<br /><br />Madison Renaissance Hotel<br />515 Madison St<br />Seattle, WA<br />(206) 583-0300<br /><br />Hotel Monaco<br />1101 4th Avenue<br />Seattle, WA<br />(206) 621-1770 <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <span class="byline-author">Posted by Lydia Ash, Test Engineering Manager </span><br /><br /><span style="font-weight: bold;">Call for Attendance</span><span style="font-weight: bold;"><br />Google Test Automation Conference 2008</span><span style="font-weight: bold;"><br />Seattle, WA</span><span style="font-weight: bold;"><br />October 23 - 24</span><br /><br />Google's Test Automation Conference is built on our participants each bringing their experience, ideas, and insight to the discussions we host. Our participants are all experienced industry professionals working as software development engineers or software testing engineers. For the limited number of spaces available in each year's conference, we ask each applicant to share what they would bring to the discussions as an active participant in the conference.<br /><br />To apply for a participant space at the GTAC 2008 conference, you can apply:<br /><div style="text-align: center;"><a href="http://services.google.com/events/gtac2008">http://services.google.com/events/gtac2008</a><br /><br /></div><span style="font-weight: bold;">Timeline</span><br /><ul><li>Deadline for applying as a participant: August 15</li><li>Notification of acceptance: August 29</li><li>Wait list callbacks: October 3</li><li>GTAC 2008 Conference: October 23 and 24</li></ul><br /><span style="font-weight: bold;">Scheduled Presentations</span><br /><ul><li>Atom Publishing Protocol, Testing a Server Implementation by David Calavera</li><li>JInjector: a Coverage and End-To-End Testing Framework for J2ME and RIM by Julian Harty, Olivier Gaillard, and Michael Sama</li><li>Advances in Automated Software Testing Technologies by Elfriede Dustin</li><li>Taming the Beast: How to test an AJAX Application by Markus Clermont and John Thomas</li><li>Automated Model-Based Testing of Web Applications by Oluwaseun Akinmade and Prof. Atif M Memon</li><li>Boosting Your Testing Productivity with Groovy by Andres Almiray</li><li>Practicing Testability in the Real World by Vishal Chowdhary</li><li>The New Genomics: Software Development at Petabyte Scale by Matt Wood</li><li>The Value of Small Tests by Christopher Semturs</li><li>Deployment and Test Automation: Extending the Notion of 'Done' to 'System Tested on a Production Deployment' by Marc-Elian Begin</li></ul><span style="font-weight: bold;">No Registration Fees</span><br />The GTAC conference has no registration fees. Once invitations have been sent to participate, full registration instructions will be sent to each invitee. Breakfast and lunch will be provided each day of the conference, as well as a reception the evening of October 23.<br /><br /><span style="font-weight: bold;">Cancellation</span><br />If you register as a participant and will not be able to attend, please send email immediately to <a href="mailto:gtac@google.com">gtac@google.com</a> to allow a wait list person the opportunity to participate in that slot.<br /><br /><span style="font-weight: bold;">Hotel Accommodations</span><br /><a href="http://www.starwoodhotels.com/whotels/property/overview/index.html?propertyID=1154">W Seattle</a> (Conference Venue)<br />1112 Fourth Avenue<br />Seattle, WA 98101<br />(206) 264-6000<br /><br />Other Hotels in the Area<br />Hotel Vintage Park<br />1100 5th Ave<br />Seattle, WA<br />(206) 624-8000<br /><br />Madison Renaissance Hotel<br />515 Madison St<br />Seattle, WA<br />(206) 583-0300<br /><br />Hotel Monaco<br />1101 4th Avenue<br />Seattle, WA<br />(206) 621-1770 <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:Call for Attendance: GTAC 2008&url=https://testing.googleblog.com/2008/07/call-for-attendance-gtac-2008.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/call-for-attendance-gtac-2008.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/call-for-attendance-gtac-2008.html#comments' style='font-weight: 500; text-decoration: underline;'>4 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/call-for-attendance-gtac-2008.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/GTAC' rel='tag'> GTAC </a> </span> </div> </div> </div> <div class='post' data-id='9081839922903151980' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/how-to-think-about-new-operator-with.html' itemprop='url' title='How to Think About the "new" Operator with Respect to Unit Testing'> How to Think About the "new" Operator with Respect to Unit Testing </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Thursday, July 10, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> By <a href="http://www.testabilityexplorer.org/about">Miško Hevery</a><br /> <br /> <ul><br /> <li>Unit Testing as the name implies asks you to test a Class (Unit) in isolation.</li> <br /> <li>If your code mixes Object Construction with Logic you will never be able to achieve isolation.</li> <br /> <li>In order to unit-test you need to separate object graph construction from the application logic into two different classes</li> <br /> <li>The end goal is to have either: classes with logic OR classes with "<span style="font-family: &quot;courier new&quot; , monospace;">new</span>" operators.</li> </ul> <br /> <br /> <br /> Unit-Testing as the name implies is testing of a Unit (most likely a Class) in isolation. Suppose you have a class <span style="font-family: &quot;courier new&quot; , monospace;">House</span>. In your <span style="font-family: &quot;courier new&quot; , monospace;">JUnit</span> test-case you simply instantiate the class <span style="font-family: &quot;courier new&quot; , monospace;">House</span>, set it to a particular state, call the method you want to test&nbsp; and then assert that the class' final state is what you would expect. Simple stuff really...<br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class House {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked;</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked() {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return isLocked;</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean lock() {</span><span style="font-family: &quot;courier new&quot; , monospace;"><br /><br />&nbsp;&nbsp;&nbsp; isLocked = true;<br /><br />&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> If you look at House closely you will realize that this class is a leaf of your application. By leaf I mean that it is the end of the dependency graph, it does not reference any other classes. As such all leafs of any code base are easy to test, because the dependency graph ends with the leaf. But testing classes which are not leafs can be a problem because we may not be able to instantiate the class in isolation.<br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class House {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private final Kitchen kitchen = new Kitchen();</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked;</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked() {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return isLocked;</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean lock() {</span><span style="font-family: &quot;courier new&quot; , monospace;"><br /><br />&nbsp;&nbsp;&nbsp; kitchen.lock();<br /><br />&nbsp;&nbsp;&nbsp; isLocked = true;<br /><br />&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> In this updated version of <span style="font-family: &quot;courier new&quot; , monospace;">House </span>it is not possible to instantiate <span style="font-family: &quot;courier new&quot; , monospace;">House</span> without the <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span>. The reason for this is that the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operator of <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span> is embedded within the <span style="font-family: &quot;courier new&quot; , monospace;">House</span> logic and there is nothing we can do in a test to prevent the <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span> from getting instantiated. We say that we are mixing the <i>concern of application instantiation</i> with <i>concern of application logic</i>. In order to achieve true unit testing we need to instantiate <i>real</i> <span style="font-family: &quot;courier new&quot; , monospace;">House</span> with a <i>fake</i> <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span> so that we can unit-test the <span style="font-family: &quot;courier new&quot; , monospace;">House</span> in isolation. <br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class House {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private final Kitchen kitchen;<br /></span><span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked;</span><br /> <br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp; public House(Kitchen kitchen) {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; this.kitchen = kitchen;</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked() {</span><br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return isLocked;</span><br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean lock() {</span><span style="font-family: &quot;courier new&quot; , monospace;"><br /><br />&nbsp;&nbsp;&nbsp; kitchen.lock();<br /><br />&nbsp;&nbsp;&nbsp; isLocked = true;<br /><br />&nbsp; }</span><br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> Notice how we have removed the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operator from the application logic. This makes testing easy. To test we simply <span style="font-family: &quot;courier new&quot; , monospace;">new</span>-up a real <span style="font-family: &quot;courier new&quot; , monospace;">House</span> and use a mocking framework to create a fake <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span>. This way we can still test <span style="font-family: &quot;courier new&quot; , monospace;">House</span> in isolation even if it is not a leaf of an application graph. <br /> <br /> <br /> <br /> But where have the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operators gone? Well, we need a factory object which is responsible for instantiating the whole object graph of the application. An example of what such an object may look like is below. Notice how all of the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operators from your applications migrate here.<br /> <br /> <br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class ApplicationBuilder {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; House build() {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return new House(</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Kitchen(new Sink(), new Dishwasher(), new Refrigerator())</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> As a result your main method simply asks the <span style="font-family: &quot;courier new&quot; , monospace;">ApplicationBuilder</span> to construct the object graph for you application and then fires of the application by calling a method which does work.<br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class Main {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; public static void(String...args) {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; House house = new ApplicationBuilder().build();</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; house.lock();</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> Asking for your dependencies instead of constructing them withing the application logic is called "Dependency Injection" and is nothing new in the unit-testing world. But the reason why Dependency Injection is so important is that within unit-tests you want to test a small subset of your application. The requirement is that you can construct that small subset of the application independently of the whole system. If you mix application logic with graph construction (the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operator) unit-testing becomes impossible for anything but the leaf nodes in your application. Without Dependency Injection the only kind of testing you can do is scenario-testing, where you instantiate the whole application and than pretend to be the user in some automated way.<br /> <br /> <br /> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> By <a href="http://www.testabilityexplorer.org/about">Miško Hevery</a><br /> <br /> <ul><br /> <li>Unit Testing as the name implies asks you to test a Class (Unit) in isolation.</li> <br /> <li>If your code mixes Object Construction with Logic you will never be able to achieve isolation.</li> <br /> <li>In order to unit-test you need to separate object graph construction from the application logic into two different classes</li> <br /> <li>The end goal is to have either: classes with logic OR classes with "<span style="font-family: &quot;courier new&quot; , monospace;">new</span>" operators.</li> </ul> <br /> <br /> <br /> Unit-Testing as the name implies is testing of a Unit (most likely a Class) in isolation. Suppose you have a class <span style="font-family: &quot;courier new&quot; , monospace;">House</span>. In your <span style="font-family: &quot;courier new&quot; , monospace;">JUnit</span> test-case you simply instantiate the class <span style="font-family: &quot;courier new&quot; , monospace;">House</span>, set it to a particular state, call the method you want to test&nbsp; and then assert that the class' final state is what you would expect. Simple stuff really...<br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class House {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked;</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked() {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return isLocked;</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean lock() {</span><span style="font-family: &quot;courier new&quot; , monospace;"><br /><br />&nbsp;&nbsp;&nbsp; isLocked = true;<br /><br />&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> If you look at House closely you will realize that this class is a leaf of your application. By leaf I mean that it is the end of the dependency graph, it does not reference any other classes. As such all leafs of any code base are easy to test, because the dependency graph ends with the leaf. But testing classes which are not leafs can be a problem because we may not be able to instantiate the class in isolation.<br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class House {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private final Kitchen kitchen = new Kitchen();</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked;</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked() {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return isLocked;</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean lock() {</span><span style="font-family: &quot;courier new&quot; , monospace;"><br /><br />&nbsp;&nbsp;&nbsp; kitchen.lock();<br /><br />&nbsp;&nbsp;&nbsp; isLocked = true;<br /><br />&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> In this updated version of <span style="font-family: &quot;courier new&quot; , monospace;">House </span>it is not possible to instantiate <span style="font-family: &quot;courier new&quot; , monospace;">House</span> without the <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span>. The reason for this is that the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operator of <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span> is embedded within the <span style="font-family: &quot;courier new&quot; , monospace;">House</span> logic and there is nothing we can do in a test to prevent the <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span> from getting instantiated. We say that we are mixing the <i>concern of application instantiation</i> with <i>concern of application logic</i>. In order to achieve true unit testing we need to instantiate <i>real</i> <span style="font-family: &quot;courier new&quot; , monospace;">House</span> with a <i>fake</i> <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span> so that we can unit-test the <span style="font-family: &quot;courier new&quot; , monospace;">House</span> in isolation. <br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class House {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private final Kitchen kitchen;<br /></span><span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked;</span><br /> <br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp; public House(Kitchen kitchen) {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; this.kitchen = kitchen;</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean isLocked() {</span><br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return isLocked;</span><br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; private boolean lock() {</span><span style="font-family: &quot;courier new&quot; , monospace;"><br /><br />&nbsp;&nbsp;&nbsp; kitchen.lock();<br /><br />&nbsp;&nbsp;&nbsp; isLocked = true;<br /><br />&nbsp; }</span><br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> Notice how we have removed the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operator from the application logic. This makes testing easy. To test we simply <span style="font-family: &quot;courier new&quot; , monospace;">new</span>-up a real <span style="font-family: &quot;courier new&quot; , monospace;">House</span> and use a mocking framework to create a fake <span style="font-family: &quot;courier new&quot; , monospace;">Kitchen</span>. This way we can still test <span style="font-family: &quot;courier new&quot; , monospace;">House</span> in isolation even if it is not a leaf of an application graph. <br /> <br /> <br /> <br /> But where have the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operators gone? Well, we need a factory object which is responsible for instantiating the whole object graph of the application. An example of what such an object may look like is below. Notice how all of the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operators from your applications migrate here.<br /> <br /> <br /> <br /> <br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class ApplicationBuilder {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; House build() {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; return new House(</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Kitchen(new Sink(), new Dishwasher(), new Refrigerator())</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> As a result your main method simply asks the <span style="font-family: &quot;courier new&quot; , monospace;">ApplicationBuilder</span> to construct the object graph for you application and then fires of the application by calling a method which does work.<br /> <br /> <br style="font-family: courier new,monospace;" /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">class Main {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; public static void(String...args) {</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; House house = new ApplicationBuilder().build();</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp;&nbsp;&nbsp; house.lock();</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">&nbsp; }</span><br /> <br /> <span style="font-family: &quot;courier new&quot; , monospace;">}</span><br /> <br /> <br /> <br /> Asking for your dependencies instead of constructing them withing the application logic is called "Dependency Injection" and is nothing new in the unit-testing world. But the reason why Dependency Injection is so important is that within unit-tests you want to test a small subset of your application. The requirement is that you can construct that small subset of the application independently of the whole system. If you mix application logic with graph construction (the <span style="font-family: &quot;courier new&quot; , monospace;">new</span> operator) unit-testing becomes impossible for anything but the leaf nodes in your application. Without Dependency Injection the only kind of testing you can do is scenario-testing, where you instantiate the whole application and than pretend to be the user in some automated way.<br /> <br /> <br /> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:How to Think About the "new" Operator with Respect to Unit Testing&url=https://testing.googleblog.com/2008/07/how-to-think-about-new-operator-with.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/how-to-think-about-new-operator-with.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/how-to-think-about-new-operator-with.html#comments' style='font-weight: 500; text-decoration: underline;'>17 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/how-to-think-about-new-operator-with.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/Misko%20Hevery' rel='tag'> Misko Hevery </a> </span> </div> </div> </div> <div class='post' data-id='8870154328391757476' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/tott-expect-vs-assert.html' itemprop='url' title='TotT: EXPECT vs. ASSERT'> TotT: EXPECT vs. ASSERT </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Thursday, July 10, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <p><i>Because the <a href="http://code.google.com/p/googletest/">Google C++ Testing Framework</a> was opensourced last week, there will be episodes focusing on it published here in the future. Watch for them. I've reshuffled the schedule to get one out this week.</i></p><br /><br /><center><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494923662601362" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrMrPiRT4Cc3Tw3su4JVrVLLJPjfQNKkporPU9UD-a4cRkyhNkRWKxU4_FFnRPLrVzunEs0VaQIdjHIZFs9ruui4Vsb1bEeisYBskuxee7idQeNqnhF-rKoOVP-2t_wr6ZlJHO/s320/frame-1.png" style="margin:0 10px 10px 0;" /><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494920044814578" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl7jFeBXXVtL3qpbsDmZ2cRGoeSe3I8aYn8YdP1dxPdcK8jkPBEY-Kit6-EKul9oB1LdpKOJbnhmAxtlaIIrLwb8X0AKHvEjWM-hcyqlp53I7FuLnJ3ssaWh0y3AOm1rlALvHA/s320/frame-2.png" style="margin:0 10px 10px 0;" /><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494926321107730" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_UbbZFPiXe4coLHwT9dB0Uj6eg7gLmFF4rAwkiRVBxRwQhO5kzl3_3KX_1SETr9kszFyPFmj1Jk62m22fzdPn96vliaspQ3ytjDUdOHhZXw7D6ZcfeAEtDlQE3fdhARvp5Xy7/s320/frame-3.png" style="margin:0 10px 10px 0;" /><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494925947448786" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIEwBbrbB4MGPiu7v_XYNZzYbvwxxLXiTRaMcoZm44_Z75xxhsL6Ml8Mkml4OrZWJerOtQpSmc__3GQdjLogyJNuClWSIqirRY4qX5KBFRAvMKW3fQ-9upIxV6TFda6dfhLPjj/s320/frame-4.png" style="margin:0 10px 10px 0;" /><br /></center><br /><p><a href="http://code.google.com/p/googletest/">Google C++ Testing Framework</a> supports two families of assertions with the same interface:</p><ul><li><b>ASSERT</b>: Fails fast, aborting the current function.</li><li><b>EXPECT</b>: Continues after the failure.</li></ul><br /><p>As Moka the code monkey has shown Uni the testing robot, EXPECT is often more appropriate because it: reveals more failures in a single run, and allows more to be fixed in a single edit/compile/run-tests cycle. Example:<p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(WordStemmerTest, StemsPluralSuffixes) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("jump", stemmer->Stem("jumps"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("pixi", stemmer->Stem("pixies"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("prioriti", stemmer->Stem("priorities"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;// etc ...</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><p>Use ASSERT when it doesn't make sense to continue. Example:</p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(FileGeneratorTest, CreatesFileContainingSequenceOfChars) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_TRUE(fp = fopen(path, "r"))</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "Failed to open " << path;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_EQ(10, fread(buffer, 1, 10, fp))</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "File " << path << " is too small";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;buffer[10] = '\0';</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("123456789", buffer)</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "File " << path << " is corrupted";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><p>Remember to download <a href="http://code.google.com/testing/TotT-2008-07-10.pdf">this episode</a> of Testing on the Toilet and post it in your office.</p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <p><i>Because the <a href="http://code.google.com/p/googletest/">Google C++ Testing Framework</a> was opensourced last week, there will be episodes focusing on it published here in the future. Watch for them. I've reshuffled the schedule to get one out this week.</i></p><br /><br /><center><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494923662601362" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrMrPiRT4Cc3Tw3su4JVrVLLJPjfQNKkporPU9UD-a4cRkyhNkRWKxU4_FFnRPLrVzunEs0VaQIdjHIZFs9ruui4Vsb1bEeisYBskuxee7idQeNqnhF-rKoOVP-2t_wr6ZlJHO/s320/frame-1.png" style="margin:0 10px 10px 0;" /><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494920044814578" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl7jFeBXXVtL3qpbsDmZ2cRGoeSe3I8aYn8YdP1dxPdcK8jkPBEY-Kit6-EKul9oB1LdpKOJbnhmAxtlaIIrLwb8X0AKHvEjWM-hcyqlp53I7FuLnJ3ssaWh0y3AOm1rlALvHA/s320/frame-2.png" style="margin:0 10px 10px 0;" /><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494926321107730" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_UbbZFPiXe4coLHwT9dB0Uj6eg7gLmFF4rAwkiRVBxRwQhO5kzl3_3KX_1SETr9kszFyPFmj1Jk62m22fzdPn96vliaspQ3ytjDUdOHhZXw7D6ZcfeAEtDlQE3fdhARvp5Xy7/s320/frame-3.png" style="margin:0 10px 10px 0;" /><br /><img alt="" border="0" id="BLOGGER_PHOTO_ID_5221494925947448786" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIEwBbrbB4MGPiu7v_XYNZzYbvwxxLXiTRaMcoZm44_Z75xxhsL6Ml8Mkml4OrZWJerOtQpSmc__3GQdjLogyJNuClWSIqirRY4qX5KBFRAvMKW3fQ-9upIxV6TFda6dfhLPjj/s320/frame-4.png" style="margin:0 10px 10px 0;" /><br /></center><br /><p><a href="http://code.google.com/p/googletest/">Google C++ Testing Framework</a> supports two families of assertions with the same interface:</p><ul><li><b>ASSERT</b>: Fails fast, aborting the current function.</li><li><b>EXPECT</b>: Continues after the failure.</li></ul><br /><p>As Moka the code monkey has shown Uni the testing robot, EXPECT is often more appropriate because it: reveals more failures in a single run, and allows more to be fixed in a single edit/compile/run-tests cycle. Example:<p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(WordStemmerTest, StemsPluralSuffixes) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("jump", stemmer->Stem("jumps"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("pixi", stemmer->Stem("pixies"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("prioriti", stemmer->Stem("priorities"));</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;// etc ...</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><p>Use ASSERT when it doesn't make sense to continue. Example:</p><br /><p style="BORDER:1px solid #808080; PADDING:0.1in; BACKGROUND:#e6f5ff none repeat scroll 0% 50%; MARGIN-LEFT:0.39in; MARGIN-RIGHT:0.39in; MARGIN-BOTTOM:0pt"><span style=" ;font-family:courier new, monospace;font-size:100%;">TEST(FileGeneratorTest, CreatesFileContainingSequenceOfChars) {</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_TRUE(fp = fopen(path, "r"))</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "Failed to open " << path;</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;ASSERT_EQ(10, fread(buffer, 1, 10, fp))</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "File " << path << " is too small";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;buffer[10] = '\0';</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;EXPECT_STREQ("123456789", buffer)</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<< "File " << path << " is corrupted";</span><br /><span style=" ;font-family:courier new, monospace;font-size:100%;">}</span><br /></p><br /><p>Remember to download <a href="http://code.google.com/testing/TotT-2008-07-10.pdf">this episode</a> of Testing on the Toilet and post it in your office.</p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:TotT: EXPECT vs. ASSERT&url=https://testing.googleblog.com/2008/07/tott-expect-vs-assert.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/tott-expect-vs-assert.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/tott-expect-vs-assert.html#comments' style='font-weight: 500; text-decoration: underline;'>4 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/tott-expect-vs-assert.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/C%2B%2B' rel='tag'> C++ </a> , <a class='label' href='https://testing.googleblog.com/search/label/TotT' rel='tag'> TotT </a> </span> </div> </div> </div> <div class='post' data-id='4596842432845665451' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://testing.googleblog.com/2008/07/announcing-new-google-c-testing.html' itemprop='url' title='Announcing: New Google C++ Testing Framework'> Announcing: New Google C++ Testing Framework </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Thursday, July 03, 2008 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <span class="byline-author">Posted by Zhanyong Wan, Software Engineer</span><br /><br />We all know the importance of writing automated tests to cover our code. To make it easier for everyone to write good C++ tests, today we have open-sourced <a href="http://code.google.com/p/googletest/" id="fl82" target="_blank">Google C++ Testing Framework</a> (Google Test for short), a library that thousands of Googlers have been using in our C++ programs. Highlights of the project include:<br /> <ul id="fl821"><li id="fl822"> Google Test is <i id="fl823">portable</i>: it works on a variety of platforms (Linux, Windows, Mac OS X, and more), with several versions of GCC and MSVC compilers, and with or without exceptions. You can even use it in embedded systems like Windows CE and Symbian. Build tools and test runners for many of these are under active development, with Linux <a title="Autotools" href="http://www.gnu.org/software/autoconf/" id="aq27">Autotools</a> support already in place.<br /> </li><li id="fl824"> It supports both <a href="http://code.google.com/p/googletest/wiki/GoogleTestPrimer#Basic_Concepts" id="fl825" target="_blank">fatal and nonfatal</a> assertions. The test will continue after a nonfatal failure. This allows more problems to be uncovered and fixed in a single edit-compile-test cycle. </li><li id="fl826"> It provides many <a href="http://code.google.com/p/googletest/wiki/GoogleTestPrimer#Assertions" id="fl827" target="_blank">assertions</a> for common testing needs, and lets you easily <a href="http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide#Predicate_Assertions" id="fl828" target="_blank">define new assertions</a> for less common cases. </li><li id="fl829"> On Linux, you can write <a href="http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide#Death_Tests" id="fl8210" target="_blank">death tests</a> to ensure that your code crashes with expected errors. </li><li id="fl8211">Because it's based on the popular <a href="http://en.wikipedia.org/wiki/XUnit" id="fl8212" target="_blank">xUnit</a> architecture, Google Test is easy to learn if you've used any testing framework in this family before. </li></ul><br />It will take you about 10 minutes to learn <a href="http://code.google.com/p/googletest/wiki/GoogleTestPrimer" id="fl8213" target="_blank">the basics</a> and get started. Stay tuned to this blog for helpful Google Test information in upcoming Testing on the Toilet episodes.<br /><br />Please send questions and feedback to <a title="googletestframework@googlegroups.com" href="mailto:googletestframework@googlegroups.com" id="bx9o">googletestframework@googlegroups.com</a> (the <a href="http://groups.google.com/group/googletestframework" id="fl8215" target="_blank">Google Test Discussion Group</a>). See you there! <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <span class="byline-author">Posted by Zhanyong Wan, Software Engineer</span><br /><br />We all know the importance of writing automated tests to cover our code. To make it easier for everyone to write good C++ tests, today we have open-sourced <a href="http://code.google.com/p/googletest/" id="fl82" target="_blank">Google C++ Testing Framework</a> (Google Test for short), a library that thousands of Googlers have been using in our C++ programs. Highlights of the project include:<br /> <ul id="fl821"><li id="fl822"> Google Test is <i id="fl823">portable</i>: it works on a variety of platforms (Linux, Windows, Mac OS X, and more), with several versions of GCC and MSVC compilers, and with or without exceptions. You can even use it in embedded systems like Windows CE and Symbian. Build tools and test runners for many of these are under active development, with Linux <a title="Autotools" href="http://www.gnu.org/software/autoconf/" id="aq27">Autotools</a> support already in place.<br /> </li><li id="fl824"> It supports both <a href="http://code.google.com/p/googletest/wiki/GoogleTestPrimer#Basic_Concepts" id="fl825" target="_blank">fatal and nonfatal</a> assertions. The test will continue after a nonfatal failure. This allows more problems to be uncovered and fixed in a single edit-compile-test cycle. </li><li id="fl826"> It provides many <a href="http://code.google.com/p/googletest/wiki/GoogleTestPrimer#Assertions" id="fl827" target="_blank">assertions</a> for common testing needs, and lets you easily <a href="http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide#Predicate_Assertions" id="fl828" target="_blank">define new assertions</a> for less common cases. </li><li id="fl829"> On Linux, you can write <a href="http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide#Death_Tests" id="fl8210" target="_blank">death tests</a> to ensure that your code crashes with expected errors. </li><li id="fl8211">Because it's based on the popular <a href="http://en.wikipedia.org/wiki/XUnit" id="fl8212" target="_blank">xUnit</a> architecture, Google Test is easy to learn if you've used any testing framework in this family before. </li></ul><br />It will take you about 10 minutes to learn <a href="http://code.google.com/p/googletest/wiki/GoogleTestPrimer" id="fl8213" target="_blank">the basics</a> and get started. Stay tuned to this blog for helpful Google Test information in upcoming Testing on the Toilet episodes.<br /><br />Please send questions and feedback to <a title="googletestframework@googlegroups.com" href="mailto:googletestframework@googlegroups.com" id="bx9o">googletestframework@googlegroups.com</a> (the <a href="http://groups.google.com/group/googletestframework" id="fl8215" target="_blank">Google Test Discussion Group</a>). See you there! <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Google Testing Blog:Announcing: New Google C++ Testing Framework&url=https://testing.googleblog.com/2008/07/announcing-new-google-c-testing.html&via=googletesting'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://testing.googleblog.com/2008/07/announcing-new-google-c-testing.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='comment-container'> <i class='comment-img material-icons'> &#57529; </i> <a href='https://testing.googleblog.com/2008/07/announcing-new-google-c-testing.html#comments' style='font-weight: 500; text-decoration: underline;'>11 comments</a> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://testing.googleblog.com/2008/07/announcing-new-google-c-testing.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://testing.googleblog.com/search/label/C%2B%2B' rel='tag'> C++ </a> , <a class='label' href='https://testing.googleblog.com/search/label/Zhanyong%20Wan' rel='tag'> Zhanyong Wan </a> </span> </div> </div> </div> <div class='blog-pager' id='blog-pager'> <a class='home-link' href='https://testing.googleblog.com/'> <i class='material-icons'> &#59530; </i> </a> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='https://testing.googleblog.com/search?updated-max=2008-08-21T11:51:00-07:00&max-results=5&reverse-paginate=true' id='Blog1_blog-pager-newer-link' title='Newer Posts'> <i class='material-icons'> &#58820; </i> </a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='https://testing.googleblog.com/search?updated-max=2008-07-03T17:02:00-07:00&max-results=5' id='Blog1_blog-pager-older-link' title='Older Posts'> <i class='material-icons'> &#58824; </i> </a> </span> </div> <div class='clear'></div> </div></div> </div> </div> <div class='col-right'> <div class='section' id='sidebar-top'><div class='widget HTML' data-version='1' id='HTML8'> <div class='widget-content'> <div class='searchBox'> <input type='text' title='Search This Blog' placeholder='Search blog ...' /> </div> </div> <div class='clear'></div> </div> </div> <div id='aside'> <div class='section' id='sidebar'><div class='widget Label' data-version='1' id='Label1'> <div class='tab'> <img class='sidebar-icon' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAYpJREFUeNrs2aFuwzAQBmAvKRkMKRjZA4QMDJaWFgyMjuzFRg37DIUlA3uFkoGQSaWzJU+tpri5O9+l/zSfdFJlpe59yTmyVedq1PjfcZMZ70NuQnaF8w8htyE/rABtpviXkLcK88c5HhLkMBfgVan43zfFBNGMjHVGT/s55KP2pAvidbGHd+nzKt1RKSLG3rKF1iPFv6UWiPke8i7kEqGdGsI1O+LYVdqJAjgirwkKYD0ytkJBUNbAMvX8V3q9PhUsYvU1sWD8SO/sQvx2ahxOiNoJCSBCoAHYCEQAC4EKICOQASQEOmAS8RcAFxFN5hiIiugpgC3wk9hQAHH/70EBHXUN7IER5EWMiBgo2+nzOKQv9SCAeEM/OQAkhE/ncccFICB87qzQMia5FsJfOui0zMnmRvipU1ormHQuxGTxUsAcCFLxJQBLBLn4UoAFglW8BkATwS5eC6CBEBWvCShBiIvXBkgQRcVbADiI4uKtABSESvGWgB9EzHt3+tNwyO0qa9SoIYtvAQYAqDJhaWWeMecAAAAASUVORK5CYII='/> <h2> Labels </h2> <i class='material-icons arrow'> &#58821; </i> </div> <div class='widget-content list-label-widget-content'> <ul> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/TotT'> TotT </a> <span dir='ltr'> 104 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/GTAC'> GTAC </a> <span dir='ltr'> 61 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/James%20Whittaker'> James Whittaker </a> <span dir='ltr'> 42 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Misko%20Hevery'> Misko Hevery </a> <span dir='ltr'> 32 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Code%20Health'> Code Health </a> <span dir='ltr'> 31 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Anthony%20Vallone'> Anthony Vallone </a> <span dir='ltr'> 27 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Patrick%20Copeland'> Patrick Copeland </a> <span dir='ltr'> 23 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jobs'> Jobs </a> <span dir='ltr'> 18 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Andrew%20Trenk'> Andrew Trenk </a> <span dir='ltr'> 13 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/C%2B%2B'> C++ </a> <span dir='ltr'> 11 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Patrik%20H%C3%B6glund'> Patrik Höglund </a> <span dir='ltr'> 8 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/JavaScript'> JavaScript </a> <span dir='ltr'> 7 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Allen%20Hutchison'> Allen Hutchison </a> <span dir='ltr'> 6 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/George%20Pirocanac'> George Pirocanac </a> <span dir='ltr'> 6 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Zhanyong%20Wan'> Zhanyong Wan </a> <span dir='ltr'> 6 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Harry%20Robinson'> Harry Robinson </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Java'> Java </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Julian%20Harty'> Julian Harty </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Adam%20Bender'> Adam Bender </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Alberto%20Savoia'> Alberto Savoia </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Ben%20Yu'> Ben Yu </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Erik%20Kuefler'> Erik Kuefler </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Philip%20Zembrod'> Philip Zembrod </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Shyam%20Seshadri'> Shyam Seshadri </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Chrome'> Chrome </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dillon%20Bly'> Dillon Bly </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/John%20Thomas'> John Thomas </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Lesley%20Katzen'> Lesley Katzen </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Marc%20Kaplan'> Marc Kaplan </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Markus%20Clermont'> Markus Clermont </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Max%20Kanat-Alexander'> Max Kanat-Alexander </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Sonal%20Shah'> Sonal Shah </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/APIs'> APIs </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Abhishek%20Arya'> Abhishek Arya </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Alan%20Myrvold'> Alan Myrvold </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Alek%20Icev'> Alek Icev </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Android'> Android </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/April%20Fools'> April Fools </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Chaitali%20Narla'> Chaitali Narla </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Chris%20Lewis'> Chris Lewis </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Chrome%20OS'> Chrome OS </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Diego%20Salas'> Diego Salas </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dori%20Reuveni'> Dori Reuveni </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jason%20Arbon'> Jason Arbon </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jochen%20Wuttke'> Jochen Wuttke </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kostya%20Serebryany'> Kostya Serebryany </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Marc%20Eaddy'> Marc Eaddy </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Marko%20Ivankovi%C4%87'> Marko Ivanković </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Mobile'> Mobile </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Oliver%20Chang'> Oliver Chang </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Simon%20Stewart'> Simon Stewart </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Stefan%20Kennedy'> Stefan Kennedy </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Test%20Flakiness'> Test Flakiness </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Titus%20Winters'> Titus Winters </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Tony%20Voellm'> Tony Voellm </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/WebRTC'> WebRTC </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Yiming%20Sun'> Yiming Sun </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Yvette%20Nameth'> Yvette Nameth </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Zuri%20Kemp'> Zuri Kemp </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Aaron%20Jacobs'> Aaron Jacobs </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Adam%20Porter'> Adam Porter </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Adam%20Raider'> Adam Raider </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Adel%20Saoud'> Adel Saoud </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Alan%20Faulkner'> Alan Faulkner </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Alex%20Eagle'> Alex Eagle </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Amy%20Fu'> Amy Fu </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Anantha%20Keesara'> Anantha Keesara </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Antoine%20Picard'> Antoine Picard </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/App%20Engine'> App Engine </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Ari%20Shamash'> Ari Shamash </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Arif%20Sukoco'> Arif Sukoco </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Benjamin%20Pick'> Benjamin Pick </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Bob%20Nystrom'> Bob Nystrom </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Bruce%20Leban'> Bruce Leban </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Carlos%20Arguelles'> Carlos Arguelles </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Carlos%20Israel%20Ortiz%20Garc%C3%ADa'> Carlos Israel Ortiz García </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Cathal%20Weakliam'> Cathal Weakliam </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Christopher%20Semturs'> Christopher Semturs </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Clay%20Murphy'> Clay Murphy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dagang%20Wei'> Dagang Wei </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dan%20Maksimovich'> Dan Maksimovich </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dan%20Shi'> Dan Shi </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dan%20Willemsen'> Dan Willemsen </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dave%20Chen'> Dave Chen </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dave%20Gladfelter'> Dave Gladfelter </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/David%20Bendory'> David Bendory </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/David%20Mandelberg'> David Mandelberg </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Derek%20Snyder'> Derek Snyder </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Diego%20Cavalcanti'> Diego Cavalcanti </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Dmitry%20Vyukov'> Dmitry Vyukov </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Eduardo%20Bravo%20Ortiz'> Eduardo Bravo Ortiz </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Ekaterina%20Kamenskaya'> Ekaterina Kamenskaya </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Elliott%20Karpilovsky'> Elliott Karpilovsky </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Elliotte%20Rusty%20Harold'> Elliotte Rusty Harold </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Espresso'> Espresso </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Felipe%20Sodr%C3%A9'> Felipe Sodré </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Francois%20Aube'> Francois Aube </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Gene%20Volovich'> Gene Volovich </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Google%2B'> Google+ </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Goran%20Petrovic'> Goran Petrovic </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Goranka%20Bjedov'> Goranka Bjedov </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Hank%20Duan'> Hank Duan </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Havard%20Rast%20Blok'> Havard Rast Blok </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Hongfei%20Ding'> Hongfei Ding </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jason%20Elbaum'> Jason Elbaum </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jason%20Huggins'> Jason Huggins </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jay%20Han'> Jay Han </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jeff%20Hoy'> Jeff Hoy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jeff%20Listfield'> Jeff Listfield </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jessica%20Tomechak'> Jessica Tomechak </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jim%20Reardon'> Jim Reardon </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Joe%20Allan%20Muharsky'> Joe Allan Muharsky </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Joel%20Hynoski'> Joel Hynoski </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/John%20Micco'> John Micco </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/John%20Penix'> John Penix </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jonathan%20Rockway'> Jonathan Rockway </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Jonathan%20Velasquez'> Jonathan Velasquez </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Josh%20Armour'> Josh Armour </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Julie%20Ralph'> Julie Ralph </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kai%20Kent'> Kai Kent </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kanu%20Tewary'> Kanu Tewary </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Karin%20Lundberg'> Karin Lundberg </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kaue%20Silveira'> Kaue Silveira </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kevin%20Bourrillion'> Kevin Bourrillion </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kevin%20Graney'> Kevin Graney </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kirkland'> Kirkland </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Kurt%20Alfred%20Kluever'> Kurt Alfred Kluever </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Manjusha%20Parvathaneni'> Manjusha Parvathaneni </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Marek%20Kiszkis'> Marek Kiszkis </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Marius%20Latinis'> Marius Latinis </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Mark%20Ivey'> Mark Ivey </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Mark%20Manley'> Mark Manley </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Mark%20Striebeck'> Mark Striebeck </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Matt%20Lowrie'> Matt Lowrie </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Meredith%20Whittaker'> Meredith Whittaker </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Michael%20Bachman'> Michael Bachman </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Michael%20Klepikov'> Michael Klepikov </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Mike%20Aizatsky'> Mike Aizatsky </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Mike%20Wacker'> Mike Wacker </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Mona%20El%20Mahdy'> Mona El Mahdy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Noel%20Yap'> Noel Yap </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Palak%20Bansal'> Palak Bansal </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Patricia%20Legaspi'> Patricia Legaspi </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Per%20Jacobsson'> Per Jacobsson </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Peter%20Arrenbrecht'> Peter Arrenbrecht </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Peter%20Spragins'> Peter Spragins </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Phil%20Norman'> Phil Norman </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Phil%20Rollet'> Phil Rollet </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Pooja%20Gupta'> Pooja Gupta </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Project%20Showcase'> Project Showcase </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Radoslav%20Vasilev'> Radoslav Vasilev </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Rajat%20Dewan'> Rajat Dewan </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Rajat%20Jain'> Rajat Jain </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Rich%20Martin'> Rich Martin </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Richard%20Bustamante'> Richard Bustamante </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Roshan%20Sembacuttiaratchy'> Roshan Sembacuttiaratchy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Ruslan%20Khamitov'> Ruslan Khamitov </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Sam%20Lee'> Sam Lee </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Sean%20Jordan'> Sean Jordan </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Sebastian%20D%C3%B6rner'> Sebastian Dörner </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Sharon%20Zhou'> Sharon Zhou </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Shiva%20Garg'> Shiva Garg </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Siddartha%20Janga'> Siddartha Janga </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Simran%20Basi'> Simran Basi </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Stan%20Chan'> Stan Chan </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Stephen%20Ng'> Stephen Ng </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Tejas%20Shah'> Tejas Shah </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Test%20Analytics'> Test Analytics </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Test%20Engineer'> Test Engineer </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Tim%20Lyakhovetskiy'> Tim Lyakhovetskiy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Tom%20O%27Neill'> Tom O&#39;Neill </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/Vojta%20J%C3%ADna'> Vojta Jína </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/automation'> automation </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/dead%20code'> dead code </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/iOS'> iOS </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://testing.googleblog.com/search/label/mutation%20testing'> mutation testing </a> <span dir='ltr'> 1 </span> </li> </ul> <div class='clear'></div> </div> </div><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <div class='tab'> <i class='material-icons icon'> &#58055; </i> <h2> Archive </h2> <i class='material-icons arrow'> &#58821; </i> </div> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2025/'> 2025 </a> <span class='post-count' dir='ltr'>(1)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2025/01/'> Jan </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/'> 2024 </a> <span class='post-count' dir='ltr'>(13)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/12/'> Dec </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/10/'> Oct </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/09/'> Sep </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/08/'> Aug </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/07/'> Jul </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/05/'> May </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/04/'> Apr </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/03/'> Mar </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2024/02/'> Feb </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2023/'> 2023 </a> <span class='post-count' dir='ltr'>(14)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2023/12/'> Dec </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2023/11/'> Nov </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2023/10/'> Oct </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2023/09/'> Sep </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2023/08/'> Aug </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2023/04/'> Apr </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2022/'> 2022 </a> <span class='post-count' dir='ltr'>(2)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2022/02/'> Feb </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2021/'> 2021 </a> <span class='post-count' dir='ltr'>(3)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2021/06/'> Jun </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2021/04/'> Apr </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2021/03/'> Mar </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2020/'> 2020 </a> <span class='post-count' dir='ltr'>(8)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2020/12/'> Dec </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2020/11/'> Nov </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2020/10/'> Oct </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2020/08/'> Aug </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2020/07/'> Jul </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2020/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2019/'> 2019 </a> <span class='post-count' dir='ltr'>(4)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2019/12/'> Dec </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2019/11/'> Nov </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2019/07/'> Jul </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2019/01/'> Jan </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2018/'> 2018 </a> <span class='post-count' dir='ltr'>(7)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2018/11/'> Nov </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2018/09/'> Sep </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2018/07/'> Jul </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2018/06/'> Jun </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2018/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2018/02/'> Feb </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/'> 2017 </a> <span class='post-count' dir='ltr'>(17)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/12/'> Dec </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/11/'> Nov </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/10/'> Oct </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/09/'> Sep </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/08/'> Aug </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/07/'> Jul </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/06/'> Jun </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/05/'> May </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/04/'> Apr </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/02/'> Feb </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2017/01/'> Jan </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/'> 2016 </a> <span class='post-count' dir='ltr'>(15)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/12/'> Dec </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/11/'> Nov </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/10/'> Oct </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/09/'> Sep </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/08/'> Aug </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/06/'> Jun </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/05/'> May </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/04/'> Apr </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/03/'> Mar </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2016/02/'> Feb </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/'> 2015 </a> <span class='post-count' dir='ltr'>(14)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/12/'> Dec </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/11/'> Nov </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/10/'> Oct </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/08/'> Aug </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/06/'> Jun </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/04/'> Apr </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/03/'> Mar </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/02/'> Feb </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2015/01/'> Jan </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/'> 2014 </a> <span class='post-count' dir='ltr'>(24)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/12/'> Dec </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/11/'> Nov </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/10/'> Oct </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/09/'> Sep </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/08/'> Aug </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/07/'> Jul </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/06/'> Jun </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/04/'> Apr </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/03/'> Mar </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/02/'> Feb </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2014/01/'> Jan </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/'> 2013 </a> <span class='post-count' dir='ltr'>(16)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/12/'> Dec </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/11/'> Nov </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/10/'> Oct </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/08/'> Aug </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/07/'> Jul </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/06/'> Jun </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/04/'> Apr </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/03/'> Mar </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2013/01/'> Jan </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2012/'> 2012 </a> <span class='post-count' dir='ltr'>(11)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2012/12/'> Dec </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2012/11/'> Nov </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2012/10/'> Oct </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2012/09/'> Sep </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2012/08/'> Aug </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/'> 2011 </a> <span class='post-count' dir='ltr'>(39)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/11/'> Nov </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/10/'> Oct </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/09/'> Sep </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/08/'> Aug </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/07/'> Jul </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/06/'> Jun </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/05/'> May </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/04/'> Apr </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/03/'> Mar </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/02/'> Feb </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2011/01/'> Jan </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/'> 2010 </a> <span class='post-count' dir='ltr'>(37)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/12/'> Dec </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/11/'> Nov </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/10/'> Oct </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/09/'> Sep </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/08/'> Aug </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/07/'> Jul </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/06/'> Jun </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/04/'> Apr </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/03/'> Mar </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/02/'> Feb </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2010/01/'> Jan </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/'> 2009 </a> <span class='post-count' dir='ltr'>(54)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/12/'> Dec </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/11/'> Nov </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/10/'> Oct </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/09/'> Sep </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/08/'> Aug </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/07/'> Jul </a> <span class='post-count' dir='ltr'>(15)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/06/'> Jun </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/05/'> May </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/04/'> Apr </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/02/'> Feb </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2009/01/'> Jan </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/'> 2008 </a> <span class='post-count' dir='ltr'>(75)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/12/'> Dec </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/11/'> Nov </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/10/'> Oct </a> <span class='post-count' dir='ltr'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/09/'> Sep </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/08/'> Aug </a> <span class='post-count' dir='ltr'>(9)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> &#9660;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/07/'> Jul </a> <span class='post-count' dir='ltr'>(9)</span> <ul class='posts'> <li> <a href='https://testing.googleblog.com/2008/07/circular-dependency-in-constructors-and.html'> Circular Dependency in constructors and Dependency... </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/tott-testing-against-interfaces.html'> TotT: Testing Against Interfaces </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/how-to-write-3v1l-untestable-code.html'> How to Write 3v1L, Untestable Code </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/breaking-law-of-demeter-is-like-looking.html'> Breaking the Law of Demeter is Like Looking for a ... </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/yui-and-gwt-how-do-you-test.html'> YUI and GWT... How do you test? </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/call-for-attendance-gtac-2008.html'> Call for Attendance: GTAC 2008 </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/how-to-think-about-new-operator-with.html'> How to Think About the &quot;new&quot; Operator with Respect... </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/tott-expect-vs-assert.html'> TotT: EXPECT vs. ASSERT </a> </li> <li> <a href='https://testing.googleblog.com/2008/07/announcing-new-google-c-testing.html'> Announcing: New Google C++ Testing Framework </a> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/06/'> Jun </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/05/'> May </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/04/'> Apr </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/03/'> Mar </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/02/'> Feb </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2008/01/'> Jan </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/'> 2007 </a> <span class='post-count' dir='ltr'>(41)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/10/'> Oct </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/09/'> Sep </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/08/'> Aug </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/07/'> Jul </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/06/'> Jun </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/04/'> Apr </a> <span class='post-count' dir='ltr'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/03/'> Mar </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/02/'> Feb </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> &#9658;&#160; </span> </a> <a class='post-count-link' href='https://testing.googleblog.com/2007/01/'> Jan </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> </div> </div> <div class='clear'></div> </div> </div><div class='widget HTML' data-version='1' id='HTML6'> <div class='widget-content'> <a href="http://googletesting.blogspot.com/atom.xml"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAihJREFUeNrsWa9Pw0AU7viRMDFRBAkzJDMIBIhJJhCzk7NILIqMv4AEhdz+BCY3OYssAlGBoAJREpZwAlHEBO8lr8nSvNeVbu1dyX3JlzTrXfa+u/e9d7c5joWFhYVO1Fa8PwH2gK6m+BRwAvSlAdsrgr8E1jUuMH73GTAEzrkBWymTewZlihhLmgDXIAFuHgGVQOUF7OSYM1p6PgTuA1vAZlUEvAnPdapcMY0VICECekQ0XRfYrqoHsAGNgXfAoMomRiFDEhOZkkL3S88hMaB2LwXp0bj+ps2edpToZpjfoIDQtBeU+xjoDzP2G/gCPKZ5f8WsCAFJoJgOCcFdWSTeL9YQMSvTA1h9BkI5jaiXhLpSCL/8mVZY0UpyJ9ZdOkniu1dmJ96BpzQu9w6s28gcOq9j6pwLdR8/36NK5CQKwJSMrb2MhhSglBpt4UjsrdsnNu0B3J0HCozbCc4TjyY2srEgos/4RQljCzNxl4ireQD8FOq+T+W0mTB2g7njhlR+Sy2jsXFvU658U8YTbeaGpdIu7mWkEAq5ZtIjIhFZdtfX7QHckSvB2B6zC3VdAkZk0kAQwaXTk/CzTXK3wjIExCs6ZJpTnE4uY1KV+KzFzA3KTiFPENHJkOPcsfpLhwe4btoSuvUqAR+6TOxlCE6ZfKUsJLgsqGW8OpqAGx2X+sLxrwUog+JUeQRMDBIwyXOcnlPtPnL0/UsT/8LnOxYWFhZG4leAAQAAQHEaYuzHbAAAAABJRU5ErkJggg==" class="sidebar-icon" /> <h2>Feed</h2> </a> </div> <div class='clear'></div> </div></div> <div class='section' id='sidebar-bottom'><div class='widget HTML' data-version='1' id='HTML9'> <div class='widget-content'> <a href='http://cloud.feedly.com/#subscription%2Ffeed%2Fhttp%3A%2F%2Fgoogletesting.blogspot.com%2Ffeeds%2Fposts%2Fdefault' target='blank'><img id="feedlyFollow" src="https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_u-_WE4pZkE9NOCbod8VuhAzQJrnh-uJhNjRn7_pFomUFNiVBkBbdA6tqZMkwXxbZXNIlREoanJfO5G0EKSzOPiLrUVf7U5kVlYeBNOfX0iOLwxcweWs-1-_OQsuK56CllL7GRvOyxSe3YQJNueNfw=s0-d" alt="follow us in feedly" width="66" height="20"></a> <div class="share followgooglewrapper"> <button data-href="https://twitter.com/intent/follow?original_referer=http://googletesting.blogspot.com/&amp;screen_name=googletesting" onclick='sharingPopup(this);' id='twitter-share'><span class="twitter-follow">Follow @googletesting</span></button> <script> function sharingPopup (button) { var url = button.getAttribute("data-href"); window.open( url,'popUpWindow','height=500,width=500,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes'); } </script> </div> </div> <div class='clear'></div> </div></div> </div> </div> <div style='clear:both;'></div> </div> <!-- Footer --> <div class='google-footer-outer loading'> <div id='google-footer'> <a href='//www.google.com/'> <img class='google-logo-dark' height='36' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAABICAYAAABFoT/eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAACLVJREFUeNrsXd+L20YQ3vOprdLqiMXFXE2qB7dcwEcTSB7ykIc+9A/PQx/yEMq1TWhNuYIpJriNr7XpmZ5IxFEvmW2EKs3Ornb1w50PxIFP0kiz387OzM6uhGAwGAxGP3Ho+f7x7ri1O7LdccPqZjSNA4dEHsLfaHcEFedJom93x9Xu2OyOFTcBo6sED3fHZHeMEELrkAHJF0B8Rr+gDFsZ5n0luLTQ95AXs4W06D/tjpR50xtM4CjD0y48YGB4rnyZxNOzyA7zBHr+nLnDaJLg0mo/ALekCasg3Z4XbM0ZdTEgnDPeHY8bIne+Qz2GvwyGNwsuyT218KWvIIBMcwGpLiipcolecjMxfBDchNyS1EvxLiOSIecp31q6IJ/C3yrIrMqMm4jhg+AxkdwbIO3aUO4KjqqMjCT3uaazMBhWBJfuxH3CtRfiXf66DhSRZWbmlMnNaILgZxrXJQO/eO3wORZwvwm4JUxuhheCjzVBYAbW1ces45YDSoZrFNOEE835M8FT6oyeEnws8Fz3QnBxFKPHBMem4GU+m6fPGb0leCTwWcM5B36MPgeZI01gudyDdw3hPeXfo8L/rmCUWnuMMdqUL2WqWeRbhf+twfVsO7YagZGNC79fw7OthEVtkiJ4jJzTd3KPwf3CRqhhiTu23AP5sl0/0xiwISQXpNwLIJK87mHF+U8ddzzdmgKlGzlPYjyxGJQouIhNT4k9AqWEFkqfguIvagTWbcq3KW1WE3xS3m8NtA9WS451xofwjKT5kkDoK/b6mDk5FfXr1lWDL4BofZEv2/SRsK/EHGlGdBdu8QNRb8HMCFwt7Yy3DDI/QP7fx5z3VLhdlJEIs4rKNuXXJXdxZPdB7kfCzWqwCO4V1LHgLjInX3tQ1KzCR52Cz+vDj1dydeRuS74rcvs2Pi6fT5H8OaaUQPQPYcWwRSGXyhhscn5dpAnEFMkuEZetbfkTAnlSuH4DxisE+aMGeJAQ3lFl7C4LJE6QWCaCd583ORQ1jYAwjFctal7nOs2ZZvicwvlZx+RHGrcoAwKUVX8uwcc/9TT65INeDOr5shL9LDRB6QTeIy3zwfdh3WOi6axLCEhSjXU7F3h6LqggUtvyJxpynwu8tDkD98fXApOxRj8zoZ9MnGveYVIVZKaGrkBXCY65BCYNN9NkjpKOyQ81Q79JgdxS+Jn3SDTEXRI7SWzaiSTB32oI3nU3BvMfM0urhOVYgwKhuiAfc4tM07wXwm1ZRoQYSl2NUwiu01fEAHVcpixd745FvVz4dzUUc0o8rwoLy8ZSwU6CyFx1RP5II9+1bFPEFs9HWbNLiimDXE+vCm7u1CS47cofzD3aEhVY57mxRo5zlqdt+RFC1JUH2S7bcVXg4liTMakaBZZVxiTICRoivcn1sEUBlk24JmaC6kxUbYmWoqvyfck2xZGGnDFYa9MMzkYQ1ijkCX6qidybrgePiQ0QIQqoi6qRLeqQfIoRsEHaQJLBdHOnLGetSdm/IPcymJuS1PAnbQPH0MOw/39C1vL11DiLOqIsbDI8QcHvGiLnySi2qUXBicaqUSxN5LEB0g7Jt3ENXJLPJ5S1tnaZBoWbpRqrmjRE7qHmpSmNHdQcYrEUadoh+TbBnc9ri7iycI1kzPeNcLDIvbiqXpez9Tmdq6zGREPuzECBoxrPMiI2WtvyNwhJba2wy3JZ6ky5dD1lSvmZS3e4SPA1wcf1VTFHKX+cGwZzdUYcqpvUtvwrD/InDttVlyZeAKlNN5MKbAiurHhKIPlUuJvlTCCiDjSKSCsUmCFWbGLZwCESfK07JB8LvMYWVtw0D00JEHV8Mq2HkqPbE0oHLvvK2g0o8ETg+4cfwTlZDT9JDoWygu4uQQE/ivIvtcnfPkaCqhiupz7jWOAzqL/vjtcdkv9G4MVMt+EaylfuImiPAXEUjRF3pjjaHiPPZ6If9TGGAO4ZY0am6jOCb+DQ+ZCqLkIpOIPrdNfIjnFPY6nyFut7TS/fanrziOBOKMupKw94WaLMtuVnSFt9CPrWWdJE6PeltCX432DEBoh+5Dv8RRhdis8YAv9uyq4/JAwtlEApgBe9Cw9xDD3tdk4Jn0MDfiHwPHcRPxBePCMER3GuIx7kGlv9fkZ4V9lolx2Uv4X7hEj7qJ3LDoAMGbTRMRibu4L2xQ8bgt8AyU+Q+x7nYrvDnH4iuO5LxKsYwPVbkPMvKF9Zky9wXzRfVWizi62r9X5VHf55h+WHhDjGBZ4WRhyTr6z5SlCoLMxLSpBZFsQ9F80uQFbF/6aFWi+Ev51vzzsuX+msyzuQXXjUz8zEBy+zpq9yweXAoxJW4JbYrDS6gYDqGHxPl+TKeiBfxj9/EBIElPYeOA4y8/qRQfknjvSzgRgtq0Pw/M1eQeMdOSb2Bnrhr6Led+1vcp2x7oTFHMnedFW+Ivlty062BUt74oHgSj+vHepnhunn0JJAMtBZgDI/qmGtMujRv8DDpo47zBJ8UtPOuAR/7rKn8t9AJ0tBdmBAmJ/Fu71yxp4I3qh+DhyRqbi5Y1ShVPlSb8X7bRNcfgZFl+WRGYo7uecrWq1r8X5bhmzP5OdlDwsGRm1suSxkg5rYm7ConyGQ3Zl+DgSD8V/kPwrWBMG9YcBtyShBnTLdTiHgttw7qAW7cqh/ZnmPKr/6ignOaKsdyxbsToT5UkPsW00bJjijDXficcX/JsLs6w2BwGtherdckH3w/kNXRPVI0OqJQoHX42/66IMfMj/2huRjxIidgKV/W0JS+bsstDoTeAHcrI8E5zTh/sDkqxL5rZup55/3USlswfcHf4IrQplVDgW9XFlOqnwr6pVPMMEZTuC60EttvdzbLbaZ4PsFVa3nohhO+vW+yn/ZB2fUhpysmQrzBcTSai9EszuZMcEZ1lCFVrp9zGXhm69iLyY4oxFIa178lPe12I/P2DAYDAaDwWAwGAwGg8FgMBgMBoPBYDD2Cf8IMADDRGoQTe+E9AAAAABJRU5ErkJggg==' style='margin-top: -16px;' width='92'/> </a> <ul> <li> <a href='//www.google.com/'> Google </a> </li> <li> <a href='//www.google.com/policies/privacy/'> Privacy </a> </li> <li> <a href='//www.google.com/policies/terms/'> Terms </a> </li> </ul> </div> </div> <script type='text/javascript'> //<![CDATA[ // Social sharing popups. var postEl = document.getElementsByClassName('social-wrapper'); var postCount = postEl.length; for(i=0; i<postCount;i++){ postEl[i].addEventListener("click", function(event){ var postUrl = this.getAttribute("data-href"); window.open( postUrl,'popUpWindow','height=500,width=500,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes'); });} //]]> </script> <script type='text/javascript'> //<![CDATA[ var BreakpointHandler = function() { this.initted = false; this.isHomePage = false; this.isMobile = false; }; BreakpointHandler.prototype.finalizeSummary = function(summaryHtml, lastNode) { // Use $.trim for IE8 compatibility summaryHtml = $.trim(summaryHtml).replace(/(<br>|\s)+$/,''); if (lastNode.nodeType == 3) { var lastChar = summaryHtml.slice(-1); if (!lastChar.match(/[.”"?]/)) { if (!lastChar.match(/[A-Za-z]/)) { summaryHtml = summaryHtml.slice(0, -1); } summaryHtml += ' ...'; } } else if (lastNode.nodeType == 1 && (lastNode.nodeName == 'I' || lastNode.nodeName == 'A')) { summaryHtml += ' ...'; } return summaryHtml; }; BreakpointHandler.prototype.generateSummaryFromContent = function(content, numWords) { var seenWords = 0; var summaryHtml = ''; for (var i=0; i < content.childNodes.length; i++) { var node = content.childNodes[i]; var nodeText; if (node.nodeType == 1) { if (node.hasAttribute('data-about-pullquote')) { continue; } nodeText = node.textContent; if (nodeText === undefined) { // innerText for IE8 nodeText = node.innerText; } if (node.nodeName == 'DIV' || node.nodeName == 'B') { // Don't end early if we haven't seen enough words. if (seenWords < 10) { continue; } if (i > 0) { summaryHtml = this.finalizeSummary(summaryHtml, content.childNodes[i-1]); } break; } summaryHtml += node.outerHTML; } else if (node.nodeType == 3) { nodeText = node.nodeValue; summaryHtml += nodeText + ' '; } var words = nodeText.match(/\S+\s*/g); if (!words) { continue; } var remain = numWords - seenWords; if (words.length >= remain) { summaryHtml = this.finalizeSummary(summaryHtml, node); break; } seenWords += words.length; } return summaryHtml; }; BreakpointHandler.prototype.detect = function() { var match, pl = /\+/g, search = /([^&=]+)=?([^&]*)/g, decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, query = window.location.search.substring(1); var urlParams = {}; while (match = search.exec(query)) urlParams[decode(match[1])] = decode(match[2]); this.isListPage = $('html').hasClass('list-page'); this.isMobile = urlParams['m'] === '1'; this.isHomePage = window.location.pathname == '/'; }; BreakpointHandler.prototype.initContent = function() { var self = this; $('.post').each(function(index) { var body = $(this).children('.post-body')[0]; var content = $(body).children('.post-content')[0]; $(content).addClass('post-original'); var data = $(content).children('script').html(); data = self.rewriteForSSL(data); // If exists, extract specified editor's preview. var match = data.match(/([\s\S]+?)<div data-is-preview.+?>([\s\S]+)<\/div>/m); if (match) { data = match[1]; } // Prevent big images from loading when they aren't needed. // This must be done as a pre-injection step, since image loading can't be // canceled once embedded into the DOM. if (self.isListPage && self.isMobile) { data = data.replace(/<(img|iframe) .+?>/g, ''); } // Insert template to be rendered as nodes. content.innerHTML = data; if (self.isListPage) { var summary = document.createElement('div'); $(summary).addClass('post-content'); $(summary).addClass('post-summary'); body.insertBefore(summary, content); if (match) { // Use provided summary. summary.innerHTML = match[2]; } else { // Generate a summary. // Summary generation relies on DOM, so it must occur after content is // inserted into the page. summary.innerHTML = self.generateSummaryFromContent(content, 30); } // Add read more link to summary. var titleAnchor = $(this).find('.title a')[0]; var link = titleAnchor.cloneNode(true); link.innerHTML = 'Read More'; $(link).addClass('read-more'); summary.appendChild(link); } }); // Firefox does not allow for proper styling of BR. if (navigator.userAgent.indexOf('Firefox') > -1) { $('.post-content br').replaceWith('<span class="space"></span>'); } $('.loading').removeClass('loading'); }; BreakpointHandler.prototype.process = function() { if (!this.initted) { var makeInsecureImageRegex = function(hosts) { var whitelist = hosts.join('|').replace(/\./g,'\\.'); // Normal image tags, plus input images (yes, this is possible!) return new RegExp('(<(img|input)[^>]+?src=("|\'))http:\/\/(' + whitelist +')', 'g'); }; this.sslImageRegex = makeInsecureImageRegex(BreakpointHandler.KNOWN_HTTPS_HOSTS); this.sslImageCurrentDomainRegex = makeInsecureImageRegex([window.location.hostname]); this.detect(); this.initContent(); this.initted = true; } }; BreakpointHandler.KNOWN_HTTPS_HOSTS = [ "www.google.org", "www.google.com", "services.google.com", "blogger.com", "draft.blogger.com", "www.blogger.com", "photos1.blogger.com", "photos2.blogger.com", "photos3.blogger.com", "blogblog.com", "img1.blogblog.com", "img2.blogblog.com", "www.blogblog.com", "www1.blogblog.com", "www2.blogblog.com", "0.bp.blogspot.com", "1.bp.blogspot.com", "2.bp.blogspot.com", "3.bp.blogspot.com", "4.bp.blogspot.com", "lh3.googleusercontent.com", "lh4.googleusercontent.com", "lh5.googleusercontent.com", "lh6.googleusercontent.com", "themes.googleusercontent.com", ]; BreakpointHandler.prototype.rewriteForSSL = function(html) { // Handle HTTP -> HTTPS source replacement of images, movies, and other embedded content. return html.replace(this.sslImageRegex, '$1https://$4') .replace(this.sslImageCurrentDomainRegex, '$1//$4') .replace(/(<(embed|iframe)[^>]+?src=("|'))http:\/\/([^"']*?(youtube|picasaweb\.google)\.com)/g, '$1https://$4') // Slideshow SWF takes a image host, so we need to rewrite that parameter. .replace(/(<embed[^>]+?feed=http(?=[^s]))/g, '$1s'); }; $(document).ready(function() { var handler = new BreakpointHandler(); handler.process(); // Top-level navigation. $(".BlogArchive .tab").click(function(ev) { ev.preventDefault(); $(this).parent().toggleClass('active'); $(this).siblings().slideToggle(300); }); $(".Label .tab").click(function(ev) { ev.preventDefault(); $(this).parent().toggleClass('active'); $(this).siblings().slideToggle(300); }); // Blog archive year expansion. $('.BlogArchive .intervalToggle').click(function(ev) { ev.preventDefault(); if ($(this).parent().hasClass('collapsed')) { $(this).parent().removeClass('collapsed'); $(this).parent().addClass('expanded'); } else { $(this).parent().removeClass('expanded'); $(this).parent().addClass('collapsed'); } }); // Reverse order of months. $('.BlogArchive .intervalToggle + div').each(function(_, items) { var year = $(this); year.children().each(function(_, month) { year.prepend(month); }); }); // Set anchors to open in new tab. $('.post-content img').parent().each(function(_, node) { if (node.nodeName == 'A') { $(this).attr('target', '_blank'); } }); // Process search requests. $('.searchBox input').on("keypress", function(ev) { if (ev.which == 13) { window.location.href = 'https://www.google.com/search?q=site%3A' + window.location.hostname + '%20' + encodeURIComponent ($(this).val()); } }); }); (function($, window) { var archiveButton = $($('#sidebar .widget.BlogArchive h2')[0]); var folderIcon = $('#sidebar .widget.BlogArchive h2::after'); var archivePanel = $('#BlogArchive1'); archiveButton.click(function(e) { if (archivePanel.hasClass('archive-open')) { // It's open, so now we close it archivePanel.removeClass('archive-open'); archivePanel.addClass('archive-closed'); archiveButton.removeClass('archive-open'); archiveButton.addClass('archive-closed'); archivePanel.css('height', '60px'); } else { // It's closed, so open it archivePanel.removeClass('archive-closed'); archivePanel.addClass('archive-open'); archiveButton.removeClass('archive-closed'); archiveButton.addClass('archive-open'); archivePanel.css('height', 'auto'); folderIcon.css('content', 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggkDzi8QVSua_XxLOnfxWE_8nQc1MAhRPBxJej91JW2ZBbKvb2TjaNf66ZoTqCrBivwRr-TLJYxFm2ZAiMd-zfbJ0TjblXGvUszWFbdRncNOL7jseiJCL9uQoqN8BM8FpesdSw/s1600/keyboard_arrow_up_grey600_24dp.png'); } }); })($, window); (function ($, window, devsite) { devsite.devsite = {}; devsite.expandLeftNav = devsite.expandLeftNav || {}; devsite.expandLeftNav.ANALYTICS_LABEL_ = 'Hamburger menu'; devsite.expandLeftNav.ANALYTICS_ACTION_OPEN_ = 'Open'; devsite.expandLeftNav.ANALYTICS_ACTION_CLOSE_ = 'Close'; devsite.expandLeftNav.lastState_ = 0; devsite.expandLeftNav.chekovEnabled_ = false; devsite.expandLeftNav.init = function () { devsite.expandLeftNav.chekovEnabled_ = true; var navElement; if (devsite.expandLeftNav.chekovEnabled_) { navElement = $('.devsite-nav-responsive'); } else { navElement = $('.devsite-section-nav-responsive'); } this.drawerWidth = parseInt(navElement.css('width')); navElement.css({ 'left': -(this.drawerWidth) }); var expandButton = $('.devsite-expand-section-nav'); expandButton.click(function () { devsite.expandLeftNav.handleNavigationOpened(); }); navElement.find('.devsite-nav-responsive-forward').click( devsite.expandLeftNav.openPanel); navElement.find('.devsite-nav-responsive-back').click( devsite.expandLeftNav.closePanel); if ($('.devsite-nav-responsive-tabs-panel + ' + '.devsite-nav-responsive-sidebar-panel').length) { devsite.expandLeftNav.openPanel(); } }; devsite.expandLeftNav.handleNavigationOpened = function (opt_noAnimate) { var mask; if (devsite.expandLeftNav.chekovEnabled_) { var nav = $('.devsite-nav-responsive'); if (opt_noAnimate) { nav.addClass('devsite-nav-responsive-no-animate'); mask = devsite.devsite.showSiteMask(0); } else { mask = devsite.devsite.showSiteMask(); } nav.addClass('devsite-nav-responsive-open'); } else { devsite.expandLeftNav.lastState_ = devsite.sticky.currentState; devsite.sticky.setState(devsite.sticky.state.COLLAPSED_HEADER); var headerHeight = devsite.sticky.getHeaderHeight() - devsite.sticky.desiredMargin; var drawerHeight = $(window).height() - headerHeight; mask = devsite.devsite.showArticleMask(); $('.devsite-section-nav-responsive').css({ 'height': drawerHeight, 'left': '0', 'top': headerHeight, 'visibility': 'visible' }).focus(); } $(mask).click(devsite.expandLeftNav.handleNavigationClosed); $(document).on('keydown.escape', function (e) { if (e.keyCode == $.ui.keyCode.ESCAPE) { devsite.expandLeftNav.handleNavigationClosed(); $(document).off('keydown.escape'); } }); }; devsite.expandLeftNav.getScrollTop = function () { return $(window).scrollTop(); }; devsite.expandLeftNav.handleNavigationClosed = function () { var nav; if (devsite.expandLeftNav.chekovEnabled_) { nav = $('.devsite-nav-responsive'); devsite.devsite.hideSiteMask(); nav.removeClass('devsite-nav-responsive-open ' + 'devsite-nav-responsive-no-animate'); } else { nav = $('.devsite-section-nav-responsive'); devsite.devsite.hideArticleMask(); devsite.sticky.setState(devsite.expandLeftNav.lastState_); nav .css('left', -(devsite.expandLeftNav.drawerWidth)) .one('transitionend', function () { nav.css('visibility', 'hidden'); }); } nav.scrollTop(0); }; devsite.expandLeftNav.openPanel = function () { var parentPanel = $('.devsite-nav-responsive-tabs-panel'); var childPanel = $('.devsite-nav-responsive-sidebar-panel'); childPanel.show(); parentPanel .addClass('devsite-nav-responsive-transition') .addClass('devsite-nav-responsive-transform') .one('transitionend', function () { childPanel .removeClass('devsite-nav-responsive-transition') .removeClass('devsite-nav-responsive-transform'); parentPanel.hide(); }); setTimeout(function () { childPanel .addClass('devsite-nav-responsive-transition') .addClass('devsite-nav-responsive-transform'); }, 1); }; devsite.expandLeftNav.closePanel = function () { var parentPanel = $('.devsite-nav-responsive-tabs-panel'); var childPanel = $('.devsite-nav-responsive-sidebar-panel'); childPanel .removeClass('devsite-nav-responsive-transition') .addClass('devsite-nav-responsive-transform'); parentPanel .show() .removeClass('devsite-nav-responsive-transition') .addClass('devsite-nav-responsive-transform'); setTimeout(function () { parentPanel .addClass('devsite-nav-responsive-transition') .removeClass('devsite-nav-responsive-transform'); childPanel .addClass('devsite-nav-responsive-transition') .removeClass('devsite-nav-responsive-transform') .one('transitionend', function () { childPanel.hide(); parentPanel.removeClass('devsite-nav-responsive-transition'); }); }, 1); }; devsite.expandLeftNav.FADE_SLOW_ = 'slow'; devsite.expandLeftNav.FADE_FAST_ = 'fast'; devsite.expandLeftNav.SITE_MASK_CSS_ = '.devsite-site-mask'; devsite.devsite.showSiteMask = function(opt_animate) { if (opt_animate === undefined) { opt_animate = devsite.expandLeftNav.FADE_SLOW_; } devsite.devsite.setMouseScrollingEnabled(false); return devsite.devsite.setMask_(devsite.expandLeftNav.SITE_MASK_CSS_, false, opt_animate); }; devsite.devsite.hideSiteMask = function(opt_animate) { if (opt_animate === undefined) { opt_animate = devsite.expandLeftNav.FADE_FAST_; } devsite.devsite.setMouseScrollingEnabled(true); return devsite.devsite.setMask_(devsite.expandLeftNav.SITE_MASK_CSS_, true, opt_animate); }; devsite.devsite.showArticleMask = function() { devsite.devsite.setMouseScrollingEnabled(false); return devsite.devsite.setMask_('.devsite-article-mask', false, devsite.expandLeftNav.FADE_SLOW_); }; devsite.devsite.hideArticleMask = function() { devsite.devsite.setMouseScrollingEnabled(true); return devsite.devsite.setMask_('.devsite-article-mask', true, devsite.expandLeftNav.FADE_FAST_); }; devsite.devsite.setMask_ = function(className, out, opt_fadeTime) { var query = $(className); if (opt_fadeTime === 0) { out ? query.hide() : query.show(); } else { out ? query.fadeOut(opt_fadeTime) : query.fadeIn(opt_fadeTime); } return $(className)[0]; }; devsite.devsite.setMouseScrollingEnabled = function(trueOrFalse) { if (trueOrFalse == true) { $('html, body').css({ 'overflow': '' }); } else { $('html, body').css({ 'overflow': 'hidden' }); } }; })($, window, devsite = {}); if (window.jQuery) { $(document).ready(function () { if (window.devsite) { devsite.expandLeftNav.init(); } }); } //]]> </script> <style> .widget ul{ line-height: 1.6 !important; } #sidebar ul li a{ color:black; line-height: 20px; } #sidebar ul li a:hover{ color:#4184F3; } </style> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/60983134-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY7BxBAzh-itY2BkZXknw-L8Z4CPFA:1739829295019';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d15045980','//testing.googleblog.com/2008/07/','15045980'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '15045980', 'title': 'Google Testing Blog', 'url': 'https://testing.googleblog.com/2008/07/', 'canonicalUrl': 'https://testing.googleblog.com/2008/07/', 'homepageUrl': 'https://testing.googleblog.com/', 'searchUrl': 'https://testing.googleblog.com/search', 'canonicalHomepageUrl': 'https://testing.googleblog.com/', 'blogspotFaviconUrl': 'https://testing.googleblog.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': true, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': 'G-838ZCPQWM6', 'analytics4': true, 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Google Testing Blog - Atom\x22 href\x3d\x22https://testing.googleblog.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Google Testing Blog - RSS\x22 href\x3d\x22https://testing.googleblog.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Google Testing Blog - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/15045980/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/4b890f0df4aad4c4', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'archive', 'pageName': 'July 2008', 'pageTitle': 'Google Testing Blog: July 2008'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'custom', 'localizedName': 'Custom', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': true}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Google Testing Blog', 'description': '', 'url': 'https://testing.googleblog.com/2008/07/', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': true, 'isLabelSearch': false, 'archive': {'year': 2008, 'month': 7, 'rangeMessage': 'Showing posts from July, 2008'}}}]); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'lightboxEnabled': true, 'lightboxModuleUrl': 'https://www.blogger.com/static/v1/jsbin/918196653-lbx.js', 'lightboxCssUrl': 'https://www.blogger.com/static/v1/v-css/1964470060-lightbox_bundle.css'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML8', 'sidebar-top', document.getElementById('HTML8'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_LabelView', new _WidgetInfo('Label1', 'sidebar', document.getElementById('Label1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML6', 'sidebar', document.getElementById('HTML6'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML9', 'sidebar-bottom', document.getElementById('HTML9'), {}, 'displayModeFull')); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10