\r\n","bodyAsHTML":"

\r\nI define the end-game as everything between “feature-complete” and\r\nrelease. After all features are complete, the primary activities are\r\nintegration, bug-fixing, testing, and, documentation.

(Note: This is the final part of the Software Rhythm series, the other parts being Software Rhythm Part 1: The Opening and Software Rhythm Part 2: Mid-Game.)

Generally, you want to be doing all of these activities throughout\r\nthe release so that you avoid a big-bang integration at the end.\r\nHowever, releases are date-driven and your goal is always to satisfy\r\nthe business by putting as much value as possible into the release.\r\nThis inevitably means that you will be finishing several features at\r\nthe end of the development, especially the most important and riskiest\r\nlong-pole items.

\r\n

Thus, there is always integration work to be done at this point. As\r\nmuch as possible, you want to manage the risk of this end release\r\nintegration. If at all possible, it’s recommended to develop and test\r\nbig features in isolated branches so that you can manage the individual\r\nfeature risk (by deciding not to integrate). However, you then incur\r\nthat risk all at once at integration time and integrating multiple big\r\nfeatures at the same time compounds that risk.

\r\n

Testing

\r\n

You should be testing throughout the release, but generally once\r\nthings are considered “feature complete” the test team can start\r\nofficially doing verification activities. There are many kinds of\r\ntesting and my best advice is to not put all your eggs in any one\r\nbasket. [Note that I’m not including unit testing here as that must\r\noccur as part of development and thus should already be done.]

\r\n

You should use a mix of testing techniques and extract the 80/20\r\nfrom all of them. That means doing acceptance testing based on use\r\ncases, focused functional testing, interface testing, performance\r\ntesting, stress testing, exploratory testing, regression testing, etc.

\r\n

Pay attention to where you find bugs. If hot spots appear, focus on\r\nthe hot spots as you’ve likely found a problem area. As you develop new\r\ntests, record them for future regression testing. This builds a suite\r\nof tests that over time can be used strategically to fully test the\r\nproduct.

\r\n

Bug Barbecue

\r\n

As you test, you will inevitably find bugs. The more you test, the\r\nmore bugs you will find. This is good - you want to collect as many of\r\nthese bugs as you can possibly find.

\r\n

I suspect it would seem weird to most people outside the software\r\nworld to know that we release products with hundreds or thousands of\r\nknown issues but it happens in many or maybe most projects today. This\r\nused to bother me a lot, but I’ve come to accept it as simply the the\r\nstate of the world.

\r\n
\r\n

It’s not that we can’t find and fix those problems - it’s rather\r\nthat the cost of doing so is not worth it. Every day we use a stack of\r\nsoftware on every device we have where every layer of the stack from\r\nhardware up to a web app on a browser is full of bugs. Yet, this\r\ndoesn’t impede our productivity much. If that software was literally\r\nbug free, it might cost 10x or 100x as much to make and then people\r\nwouldn’t use it at all, so would derive no value from it. That’s not to\r\nsay there isn’t vast room for improvement of course.

\r\n

I’ve come to see the art of issue management as figuring out which\r\nbugs should be fixed. To do this, you want the widest possible input\r\nchannel - all the bugs you can find. You then need to really manage\r\nthat stream of bugs, just like a product manager manages a stream of\r\nfeature requests. Managing means regularly having a key group of\r\ndecision makers sit down, review all new issues and any important\r\nupdates and make decisions. Regularly means at minimum once a week and\r\nideally every single day.

\r\n

This applies not just during the end-game, but all the time. Even\r\nduring the Opening and the Mid-game, older releases experience problems\r\nor bugs are found while developing new features or doing maintenance on\r\nold ones. But during the End-game, managing those bugs rules what the\r\ndev team does, so must be given priority.

\r\n

I’m somewhat ambivalent about test-first development or TDD but\r\nbug-fixing is one area where I don’t think you should do anything till\r\nyou can reproduce the problem. There are exceptions but this should be\r\nyour rule. Over time you build a regression suite so that you can avoid\r\nbreaking and fixing the same problem over and over which creates a\r\npositive feedback cycle.

\r\n

It is also important to “trust but verify” as Reagan said. In other\r\nwords, don’t trust. It’s not enough to have someone submit a bug, and\r\nhave a developer fix it. A tester must go back and verify the fix. The\r\nnumber of bug fixes that don’t actually fix the bug is surprisingly\r\nhigh - but you won’t know how high till you start verification. You may\r\nnotice that this is yet another little feedback loop.

\r\n

Lockdown

\r\n

Putting all this together, how do you actually get to the point of\r\nrelease? You must ruthlessly ratchet up the quality (by testing, bug\r\nfixing, and verification) while ratcheting down the risk (by increased\r\nscrutiny of changes). Of course, these conflict to some degree so you\r\nmust make increasingly hard choices.

\r\n

To me, this process feels like planning for a party. A few weeks out\r\nyou can make sweeping changes about what you’re going to make, who’s\r\ncoming, etc. But as you get closer and closer to the day of the party\r\nyou’ve already bought some of the food, you have things planned, and\r\nchanges get harder and harder to make. Finally, there is a last minute\r\nexecution of pre-planned preparations and then ding-dong the doorbell\r\nrings. Things unfold rapidly from there, often not according to plan as\r\npeople arrive at different times, weather changes, I\r\nsomeone sets something on fire, etc. Everyone works together to get a\r\nproduct to the point of release, which inevitably means having a known\r\nset of issues that you must live with to get the product out the door.

\r\n

As the release point approaches, you must make finer and finer\r\ndecisions about what is really important to get into the release. At\r\nsome point, you have to start leaving out things that really should go\r\nin just because the risk is too great. You can change a message in an\r\nexception, but you can’t rewrite a web service. It’s just too risky.

\r\n

The best way to do this lockdown is to schedule a series of phases\r\nahead of time. Usually these have timelines attached to them but you\r\nshouldn’t plan to hit them necessarily. It’s better to define a series\r\nof quality gates that trigger the next phase. The quality gates can be\r\nwhether ceretain tests have been completed, # (or existence) of certain\r\npriority level bugs, incoming bug rate, incoming bug severity rate, and\r\nso on. If you’re not hitting quality gates fast enough, you’ll need to\r\ntake corrective action.

\r\n

You also then need to define the level of scrutiny that gets applied\r\nduring each phase. During the first phase, you might require just that\r\ndevelopers write a test to reproduce the bug and review with another\r\ndeveloper. Then add review by another developer or by a manager. And\r\nultimately, whoever is responsible for managing the release itself\r\nshould be approving any change.

\r\n

Beta

\r\n

One common practice is the “beta” release. The goal of the beta\r\nrelease is to give users the product early to get feedback. This can be\r\nvery useful to you because it increases your bug input funnel in ways\r\nthat either you can’t afford to or simply are not able to as you don’t\r\nhave the ability to run under real customer scenarios.

\r\n
\r\n

The trick is that the beta needs to work “enough” that users are\r\nable to actually test it and not feel like it’s a bunch of crap and you\r\nneed to do it early enough that you can address any changes that are\r\nfound before the final release. This is often hard to fit into a\r\nrelease schedule unless you have a significant portion of your overall\r\nschedule dedicated to the end-game.

\r\n

Thanks!

\r\n

Thanks everyone for reading one or more parts of this series. It was\r\nactually somewhat cathartic to dump the framework for everything I’ve\r\nlearned about software development. You’ll notice in many cases that\r\nyou’re trying to do two (or more) things at the same time and they\r\nconflict. To me, that’s why it’s fun. You have to balance those forces\r\nwhile trying to build the best product you can. There is no one single\r\nright answer - it’s how you arrange the problem to find your own\r\nsolution.

From http://tech.puredanger.com/

\r\n\t\r\n\t\t\r\n\r\n\r\n","author":{"id":214988,"username":"puredanger","realname":null,"emailHash":"89c8afd032c7b3473f67c9b00d3acd5a","avatar":"https://secure.gravatar.com/avatar/89c8afd032c7b3473f67c9b00d3acd5a?d=identicon&r=PG","reputation":0},"activeRevisionId":622910,"revisionIds":[622910],"lastActiveUserId":214988,"lastActiveDate":1221719122000,"parentId":null,"parentAuthor":null,"originalParentId":null,"childrenIds":[528037,528040],"commentIds":[528037,528040],"marked":true,"topics":["java","agile"],"primaryContainerId":8,"containerIds":[7,8],"plug":"software-rhythm-part-3-end-gam","wiki":false,"score":0,"depth":0},"enableThreadedComments":true,"portal":{"topic":{"id":"8","type":"topic","creationDate":1434655010000,"creationDateFormatted":"06/18/2015 07:16 PM","name":"agile","createdBy":{"id":2,"username":"matt"},"parentTopics":[],"childTopics":[],"usedCount":27866},"blurb":"Agile methodology news and training resources from DZone, the trusted source for learning advanced software design, web development and devops best practices.","code":"agile","id":2,"creationDate":1434673744000,"creationDateFormatted":"06/19/2015 12:29 AM","displayTitle":"Agile Zone: Agile methodology news, tutorials & tools","title":"Agile","new":false,"order":1,"shortTitle":"agile-methodology-training-tools-news","color":"red","pageTitle":"Agile Methodology Training, Tools, News & Jobs - DZone","active":true,"modificationDate":1437509321000,"modificationDateFormatted":"07/21/2015 08:08 PM"},"contentType":"article"}],"loadedStyles":[["/lib/bootstrap/bootstrap.less","/lib/font-awesome/font-awesome.less","/lib/fontello/css/fontello.css","/lib/fontello/css/animation.css","/lib/angular-ui/select.css","/lib/ngDialog/css/ngDialog.css","/less/ngDialog-theme.less","/lib/bootstrap-switch/bootstrap-switch.css","/less/dzone20.less","/less/fonts.less","/less/directives.less","/lib/slick/slick.css","/lib/bootstrap-slider/bootstrap-slider.css","/less/layout.less","/widgets/article/content/article-content.less","/widgets/article/infoBar/widget.less","/widgets/components/slider/widget.less","/widgets/content/commentsSlider/widget.less","/widgets/header/blackBar/widget.less","/widgets/header/main/header-common.less","/widgets/header/main/widget.less","/widgets/sidebar/content/list/list.less","/widgets/sidebar/tapBar/sidebar-list.less","/widgets/sidebar/tapBar/widget.less","/widgets/users/UserHomeMiniProfile/widget.less"]],"loadedScripts":[["/lib/jquery/jquery.js","/lib/lodash/lodash.js","/lib/moment/moment.js","/scripts/utils.js","/lib/angular/angular.js","/lib/angular/angular-sanitize.js","/lib/local-storage/angular-local-storage.js","/lib/bootstrap/bootstrap.js","/lib/angular-ui/bootstrap.js","/lib/angular-ui/select.js","/lib/bootstrap-switch/bootstrap-switch.js","/lib/ngDialog/js/ngDialog.js","/lib/angular-moment/angular-moment.js","/scripts/app.js","/scripts/socket.js","/scripts/services.js","/scripts/ui-services.js","/scripts/directives.js","/scripts/filters.js","/lib/angular-touch/angular-touch.min.js","/lib/elastic/elastic.js","/lib/ng-file-upload/angular-file-upload-all.js","/lib/angular-deckgrid/angular-deckgrid.js","/scripts/dzone.js","/scripts/ads.js","/scripts/head.js","/scripts/links.js","/scripts/utilities/directives.js","/scripts/utilities/services.js","/scripts/utilities/image-editor.js","/lib/bootstrap-slider/bootstrap-slider.js","/lib/bootstrap-slider/directive.js","/lib/angular-draganddrop/draganddrop.js","/widgets/article/content/utils.js","/widgets/article/infoBar/services.js","/widgets/components/slider/service.js","/widgets/header/main/angulartics-ga.js","/widgets/header/main/angulartics.js","/widgets/header/main/resize.js","/widgets/sidebar/content/list/service.js","/widgets/sidebar/tapBar/directive.js","/widgets/sidebar/tapBar/service.js"]],"TH_CSRF":"-6338601625539704826","botInfo":[{"isRenderBot":false}],"request":[{"site":{"id":7,"title":"DZone: Programming & DevOps news, tutorials & tools","keywords":"programming, software development, devops, java, agile, web, iot, database, mobile, big data, cloud","description":"Programming, Web Development, and DevOps news, tutorials and tools for beginners to experts. Hundreds of free publications, over 1M members, totally free.","name":"DZone.com"},"dev":false,"cdn":["dz2cdn1.dzone.com","dz2cdn2.dzone.com","dz2cdn3.dzone.com","dz2cdn4.dzone.com"],"theme":"dz20","context":"","user":{"id":2500002,"authenticated":false,"name":"Anonymous","realName":null,"avatar":"https://secure.gravatar.com/avatar/?d=identicon&r=PG","profile":"/users/2500002/anon-user.html"}}],"portals":[[{"topic":8,"id":2,"shortTitle":"agile-methodology-training-tools-news","color":"red","name":"Agile","code":"agile","url":"/agile-methodology-training-tools-news"},{"topic":6129,"id":3,"shortTitle":"big-data-analytics-tutorials-tools-news","color":"green","name":"Big Data","code":"big-data","url":"/big-data-analytics-tutorials-tools-news"},{"topic":30,"id":4,"shortTitle":"cloud-computing-tutorials-tools-news","color":"orange","name":"Cloud","code":"cloud","url":"/cloud-computing-tutorials-tools-news"},{"topic":59,"id":5,"shortTitle":"database-sql-nosql-tutorials-tools-news","color":"purple","name":"Database","code":"database","url":"/database-sql-nosql-tutorials-tools-news"},{"topic":31,"id":6,"shortTitle":"devops-tutorials-tools-news","color":"yellow","name":"DevOps","code":"devops","url":"/devops-tutorials-tools-news"},{"topic":1138,"id":7,"shortTitle":"enterprise-integration-training-tools-news","color":"green","name":"Integration","code":"integration","url":"/enterprise-integration-training-tools-news"},{"topic":48,"id":8,"shortTitle":"iot-developer-tutorials-tools-news-reviews","color":"orange","name":"IoT","code":"iot","url":"/iot-developer-tutorials-tools-news-reviews"},{"topic":1,"id":1,"shortTitle":"java-jdk-development-tutorials-tools-news","color":"purple","name":"Java","code":"java","url":"/java-jdk-development-tutorials-tools-news"},{"topic":29,"id":9,"shortTitle":"mobile-app-developer-tutorials-tools-news","color":"yellow","name":"Mobile","code":"mobile","url":"/mobile-app-developer-tutorials-tools-news"},{"topic":653,"id":10,"shortTitle":"apm-tools-performance-monitoring-optimization","color":"red","name":"Performance","code":"performance","url":"/apm-tools-performance-monitoring-optimization"},{"topic":35,"id":11,"shortTitle":"web-development-programming-tutorials-tools-news","color":"orange","name":"Web Dev","code":"webdev","url":"/web-development-programming-tutorials-tools-news"}]],"matchedUrl":{"name":"dzone:articles:view","mapping":"/articles/**","mappingPatterns":{}},"requiresModule":["angulartics","angulartics.google.analytics","dndLists","generalDirectives","monospaced.elastic","angularFileUpload","akoenig.deckgrid","ui.bootstrap-slider","ngSanitize","ui.select","ui.bootstrap","angularMoment","ngTouch","ngDialog","LocalStorageModule"]}; } catch(e) { console.error(e); }
4
Notification
  • Adam Van Grack started following you

  • Jessica Conaghan, Gumption Scott and 6 commented on a link you posted

    T-Mobile Unvells Cheaper, More Basic 'Simple Prepaid' Phone Plans

  • Jessica Conaghan replied on a comment you posted

    CSS counters are one of those "oh neat, didn't know CSS could do that" features with a lot of Xubuntu 14.10 Utopic Unicorn is the latest release of xubuntu based on Ubuntu 14.10

  • Jessica Conaghan started following you

See All
POWERED BY DZone TeamHub
\r\n","source":null,"views":6205,"articleDate":1221719122000,"tldr":null,"originalSource":"","published":true,"nComments":0,"articleType":"news"}]; WMODEL_DATA.perms = {"canDecidePick":false,"canPublish":false}; WMODEL_DATA.isPreview = false; WMODEL_DATA.OPTIONS = {}; TH.installWidgetController('article.content', 'articleContent7', WMODEL_DATA, typeof controller == 'function' ? controller : null, [{name: 'partners', data: true},{name: 'DEFAULT', data: true}], ' oUhbblYOaqbcblYOaqbcC', null); })(); (function() { function controller($scope, $service, $location, SideBarService, TH$Request) { SideBarService.ctx.pageSize = $scope.pageSize; SideBarService.ctx.isPreview = $scope.isPreview; SideBarService.ctx.mode = $scope.mode; SideBarService.fn.loader = $service; SideBarService.fn.scrollCheck = function() { $scope.$emit('thIfScrollCheck'); }; var currentFilter; $scope.$on('$locationChangeSuccess', function() { if (!$location.search().filter) { $scope.filter = 'latest'; } else { $scope.filter = $location.search().filter; if ($scope.filter == 'latest') { $location.search('filter', null); } } if (currentFilter == $scope.filter) { return; } currentFilter = $scope.filter; SideBarService.ctx.filter = $scope.filter; }); $scope.display = SideBarService.getList(); $scope.$watchCollection(function() { return SideBarService.getList(); }, function (n) { $scope.display = n; }); $scope.isActive = SideBarService.isActive; $scope.isExcluded = SideBarService.isExcluded; $scope.loadMore = SideBarService.load; $scope.loading = function() { return SideBarService.ctx.loading; } } var WMODEL_DATA = {}; WMODEL_DATA.pageSize = 20; WMODEL_DATA.isPreview = false; WMODEL_DATA.OPTIONS = {}; WMODEL_DATA.mode = null; TH.installWidgetController('sidebar.content.list', 'sidebarContentList10', WMODEL_DATA, typeof controller == 'function' ? controller : null, [{name: 'DEFAULT', data: true}], ' oUhbkSMaaqbcdvVkcC', null); })(); (function() { var WMODEL_DATA = {}; WMODEL_DATA.OPTIONS = {}; TH.installWidgetController('sidebar.tapBar', 'sidebar', WMODEL_DATA, typeof controller == 'function' ? controller : null, null, ' oUhbkSMadabfWVcC oUhbkSMadabbWQbVkcC', null); })(); (function() { function controller($scope, shareThis, TH$Dialog, TH$Service) { $scope.getEditUrl = function(id, type) { if (!type || type == 'article') { return '/content/' + id + '/edit.html'; } else { return '/dzone/staff/' + type + (type == 'refcard' ? 'z' : 's') + '/' + id + '/edit.html'; } } $scope.share = function(socialNet, url, title){ shareThis.shareThis(socialNet, url, title); }; $scope.canDelete = function(article) { return article.canDelete; } $scope.edit = function(link) { TH$Dialog.open({ loadWidget: 'links.postPreview', widgetArgs: { edit: link.id }, size: 'xbig' }).then(function (result) { $scope.link.title = result.title; $scope.link.linkDescription = result.content; $scope.link.thumb = result.thumb; $scope.link.tags = result.topics; }); }; $scope.deleteLink = function(article) { var title = article.title; var type = 'link'; if(article.header){ title = (article.header.type == 'article') ? article.header.title : article.title; type = (article.header.type == 'article') ? 'article' : 'link'; } TH$Dialog.confirm('Do you want to delete "' + title + '"?').then(function() { return TH$Service.action('delete', {type: type, id: article.id}); }).then(function() { article.deleted = true; }); }; } var WMODEL_DATA = {}; WMODEL_DATA.OPTIONS = {}; TH.installWidgetController('content.commentsSlider', 'contentCommentsSlider9', WMODEL_DATA, typeof controller == 'function' ? controller : null, null, ' oUhbaqbcaibvnWffWVcC', null); })(); (function() { var WMODEL_DATA = {}; WMODEL_DATA.name = "commentsSlider"; WMODEL_DATA.slot = null; WMODEL_DATA.OPTIONS = {"name":"commentsSlider"}; TH.installWidgetController('components.slider', 'componentsSlider8', WMODEL_DATA, typeof controller == 'function' ? controller : null, null, ' oUhballbvbdSaoUhM', null); })();