DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Agile Topics

article thumbnail
DevOps is Killing Maintenance. Let's Celebrate.
There's a misconception that DevOps is killing developers, but its not, it is killing the idea of server and IT operations maintenance.
May 23, 2015
by Jim Bird
· 10,904 Views
article thumbnail
Adopting Microservices at Netflix: Lessons for Team and Process Design
[this article was written by tony mauro .] in a previous blog post , we shared best practices for designing a microservices architecture, based on adrian cockcroft’s presentation at nginx.conf2014 about his experience as director of web engineering and then cloud architect at netflix . in this follow-up post, we’ll review his recommendations for retooling your development team and processes for a smooth transition to microservices. optimize for speed, not efficiency source: [email protected] the top lesson that cockcroft learned at netflix is that speed wins in the marketplace. if you ask any developer whether a slower development process is better, no one ever says yes. nor do management or customers ever complain that your development cycle is too fast for them. the need for speed doesn’t just apply to tech companies, either: as software becomes increasingly ubiquitous on the internet of things – in cars, appliances, and sensors as well as mobile devices – companies that didn’t used to do software development at all now find that their success depends on being good at it. netflix made an early decision to optimize for speed. this refers specifically to tooling your software development process so that you can react quickly to what your customers want, or even better, can create innovative web experiences that attract customers. speed means learning about your customers and giving them what they want at a faster pace than your competitors. by the time competitors are ready to challenge you in a specific way, you’ve moved on to the next set of improvements. this approach turns the usual paradigm of optimizing for efficiency on its head. efficiency generally means trying to control the overall flow of the development process to eliminate duplication of effort and avoid mistakes, with an eye to keeping costs down. the common result is that you end up focusing on savings instead of looking for opportunities that increase revenue. in cockcroft’s experience, if you say “i’m doing this because it’s more efficient,” the unintended result is that you’re slowing someone else down. this is not an encouragement to be wasteful, but you should optimize for speed first. efficiency becomes secondary as you satisfy the constraint that you’re not slowing things down. the way you grow the business to be more efficient is to go faster. make sure your assumptions are still true many large companies that have enjoyed success in their market (we can call them incumbents ) are finding themselves overtaken by nimbler, usually smaller, organizations ( disruptors ) that react much more quickly to changing consumer behavior. their large size isn’t necessarily the root of the problem – netflix is no longer a small company, for example. as cockcroft sees it, the main cause of difficulty for industry incumbents is that they’re operating under business assumptions that are no longer true. or, as will rogers put it, it’s not what we don’t know that hurts. it’s what we know that ain’t so.” of course, you have to make assumptions as you formulate a business model, and then it makes sense to optimize your business practices around them. the danger comes from sticking with assumptions after they’re no longer true, which means you’re optimizing on the wrong thing. that’s when you become vulnerable to industry disruptors who are making the right assumptions and optimizations for the current business climate. as examples, consider the following assumptions that hold sway at many incumbents. we’ll examine them further in the indicated sections and describe the approach netflix adopted. computing power is expensive. this was true when increasing your computing capacity required capital expenditure on computer hardware. see put your infrastructure in the cloud . process prevents problems. at many companies, the standard response to something going wrong is to add a preventative step to the relevant procedure. see create a high freedom, high responsibility culture with less process . here are some ways to avoid holding onto assumptions that have passed their expiration date: as obvious as it might seem, you need to make your assumptions explicit, then periodically review them to make sure they still hold true. keep aware of technological trends. as an example, the cost of solid state storage drive (ssds) storage continues to go down. it’s still more expensive than regular disks, but the cost difference is becoming small enough that many companies are deciding the superior performance is worth paying a bit more for. [ed: in this entertaining video , fastly founder and ceo artur bergman explains why he believes ssds are always the right choice.] talk to people who aren’t your customers. this is especially necessary for incumbents, who need to make sure that potential new customers are interested in their product. otherwise, they don’t hear about the fact that they’re not being used. as an example, some vendors in the storage space are building hyper-converged systems even as more and more companies are storing their data in the cloud and using open source storage management software. netflix, for example, stores data on amazon web services (aws) servers with ssds and manages it with apache cassandra . a single specialist in java distributed systems is managing the entire configuration without any commercial storage tools or help from engineers specializing in storage, san, or backup. don’t base your future strategy on current it spending, but instead on level of adoption by developers. suppose that your company accounts for nearly all spending in the market for proprietary virtualization software, but then a competitor starts offering an open source-based product at only 1% the cost of yours. if people start choosing it instead of your product, than at the point that your share of total spending is still 90%, your market share has declined to only 10%. if you’re only attending to your revenue, it seems like you’re still in good shape, but 10% of market share can collapse really quickly. put your infrastructure in the cloud source: [email protected] in make sure your assumptions are still true , we mentioned that in the past it was valid to base your business plan on the assumption that computing power was expensive, because it was: the only way to increase your computing capacity was to buy computer hardware. you could then make money by using this expensive resource in the right way to solve customer problems. the advent of cloud computing has pretty much completely invalidated this assumption. it is now possible to buy the amount of capacity you need when you need it, and to pay for only the time you actually use it. the new assumption you need to make is that (virtual) machines are ephemeral. you can create and destroy them at the touch of a button or a call to an api, without any need to negotiate with other departments in your company. one way to think of this change is that the self-service cloud makes formerly impossible things instantaneous. all of netflix’s engineers are in california, but they manage a worldwide infrastructure. the cloud enables them to experiment and determine whether (for example) adding servers in particular location improves performance. suppose they notice problems with video delivery in brazil. they can easily set up 100 cloud server instances in são paulo within a couple hours. if after a week they determine that the difference in delivery speed and reliability isn’t large enought to justify the cost of the additional server instances, they can shut them down just as quickly and easily as they created them. this kind of experiment would be so expensive with a traditional infrastructure that you would never attempt it. you would have to hire an agent in são paulo to coordinate the project, find a data center, satisfy brazilian government regulations, ship machines to brazil, and so on. it would be six months before you could even run the test and find out that increased local capacity didn’t improve your delivery speed. create a high freedom, high responsibility culture with less process in make sure your assumptions are still true , we observed that many companies create rules and processes to prevent problems. when someone makes a mistake, they add a rule to the hr manual that says “well, don’t do that again.” if you read some hr manuals from this perspective, you can extract a historical record of everything that went wrong at the company. when something goes wrong in the development process, the corresponding reaction is to add a new step to the procedure. the major problem with creating process to prevent problems is that over time you build up complex “scar tissue” processes that slow you down. netflix doesn’t have an hr manual. there is a single guideline: “act in netflix’s best interest.” the idea is that if an employee can’t figure out how to interpret the guideline in a given situation, he or she doesn’t have enough judgment to work there. if you don’t trust the judgment of the people on your team, you have to ask why you’re employing them. it’s true that you’ll have to fire people occasionally for violating the guideline. overall, the high level of mutual trust among members of a team, and across the company as a whole, becomes a strong binding force. the following books outline new ways of thinking about process if you’re looking to transform your organization: the goal: a process of ongoing improvement by eliyahu m. goldratt and jeff cox. this book has become a standard management text at business schools since its original publication in 1984. written as a novel about a manager who has only 90 days to improve performance at his factory or have it closed down, it embodies goldratt’s theory of constraints in the context of process control and automation. the phoenix project: a novel about it, devops, and helping your business win by gene kim and kevin behr. as the title indicates, it’s also a novel, about an it manager who has 90 days to save a project that’s late and over budget, or his entire department will be outsourced. he discovers devops as the solution to his problem. replace silos with microservice teams most software development groups are separated into silos, with no overlap of personnel between them. the standard process for a software development project starts with the product manager meeting with the user experience and development groups to discuss ideas for new features. after the idea is implemented in code, the code is passed to the quality assurance (qa) and database administration teams and discussed in more meetings. communication with the system, network, and san administrators is often via tickets. the whole process tends to be slow and loaded with overhead. source: adrian cockcroft some companies try to speed up by creating small “start-up”-style teams that handle the development process from end to end, or sometimes such teams are the result of acquisitions where the acquired company continues to run independently as a separate division. but if the small teams are still doing monolithic delivery, there are usually still handoffs between individuals or groups with responsibility for different functions. the process suffers from the same problems as monolithic delivery in larger companies – it’s simply not very efficient or agile. source: adrian cockcroft conway’s law says that the interface structure of a software system will reflect the social structure of the organization that produced it. so if you want to switch to a microservices architecture, you need to organize your staff into product teams and use devops methodology. there are no longer distinct product managers, ux managers, development managers, and so on, managing downward in their silos. there is a manager for each product feature (implemented as a microservice), who supervises a team that handles all aspects of software development for the microservice, from conception through deployment. the platform team provides infrastructure support that the product teams access via apis. at netflix, the platform team was mostly aws in seattle, with some netflix-managed infrastructure layers built on top. but it doesn’t matter whether your cloud platform is in-house or public; the important thing is that it’s api-driven, self-service, and automatable. source: adrian cockcroft adopt continuous delivery, guided by the ooda loop a siloed team organization is usually paired with monolithic delivery model, in which an integrated, multi-function application is released as a unit (often version-numbered) on a regular schedule. most software development teams use this model initially because it is relatively simple and works well enough with a small number of developers (say, 50 or fewer). however, as the team grows it becomes a real issue when you discover a bug in one developer’s code during qa or production testing and the work of 99 other developers is blocked from release until the bug is fixed. in 2009 netflix adopted a continuous delivery model, which meshes perfectly with a microservices architecture. each microservice represents a single product feature that can be updated independently of the other microservices and on its own schedule. discovering a bug in a microservice has no effect on the release schedule of any other microservice. continuous delivery relies on packaging microservices in standard containers. netflix initially used aws machine images (amis) and it was possible to deploy an update into a test or production environment in about 10 minutes. with docker, that time is reduced even further, to mere seconds in some cases. at netflix, the conceptual framework for continuous development and delivery is an observe-orient-decide-act (ooda) loop . source: adrian cockcroft (http://www.slideshare.net/adrianco) observe refers to examining your current status to look for places where you can innovate. you want your company culture to implicitly authorize anyone who notices an opportunity to start a project to exploit it. for example, you might notice what the diagram calls a “customer pain point”: a lot of people abandoning the registration process on your website when they reach a certain step. you can undertake a project to investigate why and fix the problem. orient refers to analyzing metrics to understand the reasons for the phenomena you’ve observed at the observe point. often this involves analyzing large amounts of unstructured data, such as log files; this is often referred to as big data analysis. the answers you’re looking for are not already in your business intelligence database. you’re examining data that no one has previously looked at and asking questions that haven’t been asked before. decide refers to developing and executing a project plan. company culture is a big factor at this point. as previously discussed, in a high-freedom, high-responsibility culture you don’t need to get management approval before starting to make changes. you share your plan, but you don’t have to ask for permission. act refers to testing your solution and putting it into production. you deploy a microservice that includes your incremental feature to a cloud environment, where it’s automatically put into an ab test to compare it to the previous solution, side by side, for as long as it takes to collect the data that shows whether your approach is better. cooperating microservices aren’t disrupted, and customers don’t see your changes unless they’re selected for the test. if your solution is better, you deploy it into production. it doesn’t have to be a big improvement, either. if the number of clients for your microservice is large enough, then even a fraction of a percent improvement (in response time, say) can be shown to be statistically valid, and the cumulative effect over time of many small changes can be significant. now you’re back at the observe point. you don’t always have to perform all the steps or do them in strict order, either. the important characteristic of the process is that it enables you quickly to determine what your customers want and to create it for them. cockcroft says “it’s hard not to win” if you’re basing your moves on enough data points and your competitors are making guesses that take months to be proven or disproven. the state of art is to circle the loop every one to two weeks, but every microservice team can do it independently. with microservices you can go much faster because you’re not trying to get entire company going around the loop in lockstep. how nginx plus can help at nginx we believe it’s crucial to your future success that you adopt a 4-tier application architecture in which applications are developed and deployed as sets of microservices . we hope the information we’ve shared in this post and its predecessor, adopting microservices at netflix: lessons for architectural design , are helpful as you plan your transition to today’s state-of-the-art architecture for application development. when it’s time to deliver your apps, nginx plus offers an application delivery platform that provides the superior performance, reliability, and scalability your users expect. fully adopting a microservices-based architecture is easier and more likely to succeed when you move to a single software tool for web serving, load balancing, and content caching. nginx plus combines those functions and more in one easy to deploy and manage package. our approach empowers developers to define and control the flawless delivery of their microservices, while respecting the standards and best practices put into place by a platform team. click here to learn more about how nginx plus can help your applications succeed. video recordings fast delivery nginx.conf2014, october 2014 migrating to microservices, part 1 silicon valley microservices meetup, august 2014 migrating to microservices, part 2 silicon valley microservices meetup, august 2014
April 13, 2015
by Patrick Nommensen
· 9,764 Views
article thumbnail
Get Client (Browser) timezone and maintain it in cookie
Recently, I came with requirement where we need to get browser timezone and maintain it so our Spring MVC application can use it. Our application need to convert date and time from server timezone to client timezone. Below is overall idea of implementation: Get Browser timezone by javascript. We can use opensource 'jstz.min.js' file for getting this. We can find this from ‘http://pellepim.bitbucket.org/jstz/’. We need to maintain this timezone. For same, we will store this timezone in cookie. This can be done by creating one jsp 'findTimeZonePage.jsp'. This page will store timezone in cookie and again redirect to original page. Every method of Spring MVC controller will check whether cookie is available, If not then it will redirect to findTimeZonePage.jsp. While doing this we will also pass current Url(will set in model) so that findTimeZonePage jsp can redirect to same page again. Code: 1. findTimeZonePage.jsp loading the page... 2. Add below Methods in Util class: public static TimeZonegetBrowserTimeZone(HttpServletRequest request){ Cookie[] cookieArray = request.getCookies(); if(cookieArray != null){ for(Cookie cookie : cookieArray){ if("CalenderAppTimeZone".equals(cookie.getName())){ String timeZoneId = cookie.getValue(); return TimeZone.getTimeZone(timeZoneId); } } } return null; } public static StringgetFullURL(HttpServletRequest request) { StringBuffer requestURL = request.getRequestURL(); String queryString = request.getQueryString(); if (queryString == null) { return requestURL.toString(); } else { return requestURL.append('?').append(queryString).toString(); } } 3. In each method of MVC Controller class, Add below code at start of method: TimeZone currentTimeZone = MyUtil.getBrowserTimeZone(request); if(currentTimeZone == null){ String url = MyUtil.getFullURL(request); System.out.println("Url="+url); model.addAttribute("redirectUrl", url); //Redirect to 'findTimeZone' for setting timezone. System.out.println("####Timezone is not set. Redirecting to findTimeZone.jsp for setting timezone."); return "findTimeZonePage"; } System.out.println("####Current TimeZone="+currentTimeZone.getID()); Hope this will help.
March 28, 2015
by Rajeshkumar Dave
· 12,798 Views
article thumbnail
The 100% Utilization Myth
Many organizations in which I've coached are concerned when the people on their teams aren't being "utilized" at 100% of their capacity. If someone is at work for 8 hours per day, minus an hour for lunch and breaks, that's 7 hours of potential capacity. Some organizations are progressive enough to see that the organization's overhead of administrative activities lowers that value to 6 hours per day. By extension, a team's capacity is simply a multiple of the number of team members and the number of hours available to be utilized, i.e. a team of 5 has 30 person-hours per day. So, anything less than 30 person-hours per day spent on tasks means that a team isn't being utilized 100%. Which is bad, apparently. A Thought Exercise If you're reading this, you have a computer and it's connected to a network. Your computer might be a small one that makes phone calls or a large one that can also handle the complex scenery of games at 60 frames per second without breaking a sweat. Regardless, it's a computer. Thanks to John von Neumann, almost all computers today have the same basic architecture, the heart of which is the Central Processing Unit or CPU. When the CPU on your computer, regardless of its size, reaches 100% utilization, what happens? Your computer slows down. Significantly. The CPU is saturated with instructions and does its best to process them, but it has a finite limit on how quickly it can do that. There's a finite limit to the speed at which the instructions and the data they use can be passed around among the internal components of the CPU. That processor just can't go any faster. To a person using the computer, it appears to be locked up. To see this in action, try running a modern game like Faster Than Light on a 1st generation iPad. The older processor can't keep up with the computing demand from a game targeted towards more a powerful CPU. The communications network to which your computer is connected might be wireless or have a "hard" connection, but behind the scenes the public internet is dominated by TCP/IP and Ethernet. What happens when the network to which your computer is connected is running at 100% capacity? The network slows down. Significantly. The equipment moving the packets of data about will experience numerous collisions and will have to send requests back to your computer to resend data. The equipment will also begin to simply "drop" packets because it can't process them quickly enough. As far as you're concerned the network has become either very slow or has simply stopped. To see this in real life, look at what happens to a web site when it's the subject of a Denial of Service (DoS) attack, which effectively saturates that site's network with data requests. The site either crashes completely or appears to be unresponsive because it can't handle the traffic. Knowledge work such as software development requires a huge amount of thinking (processing) and a huge amount of collaboration (communication). The human brain is a processor, and like the von Neumann architecture has subcomponents (lobes), working memory, etc. What happens when our processor hits 100% utilization? We simply can't process all the inputs fast enough and our ability to process information slows down dramatically. We even reach a state where the decision-making centre in our brain shuts itself down. Coupled with a decreasing ability to process information and make decisions, we experience increasing levels of anxiety. Now, let's look at teams. They represent a communications network, with the people being the nodes in the network. When the team reaches 100% utilization, the individual processors (the brains of the people!) begin to slow as the ability to process information diminishes and anxiety increases. This has the effect of slowing the team's ability to communicate and operate effectively. When one or multiple people reach the point of shutting down, the network collapses. Why does anyone think that 100% utilization is a good thing? In manufacturing, 100% utilization of the capacity of your workers is actually desirable. The thinking aspects have already been done in the design and engineering of the item being created, and the assembly process is infinitely repeatable until a new item comes along. This approach to the process was taken from the manufacturing world and applied to the development of software, with the thinking that assembly was done by the programmers after all the design and engineering had taken place. Well, that simply isn't true. The "assembly" of software isn't programming, it's the compilation and packing into something deployable. Writing software is a confluence of design and engineering that has creative and technical aspects. It's not an assembly line, and probably won't ever be within my lifetime. As long ago as the late 1950's, management guru Peter Drucker realized that there were people who "think for a living". He coined the term knowledge worker to describe that type of work. Developing software is a classic knowledge worker role and therefore has different rules for productivity. As Drucker said in his 1999 book Management Challenges of the 21st Century, Productivity of the knowledge worker is not — at least not primarily — a matter of the quantity of output. Quality is at least as important. If we're pushing individuals and teams to 100% capacity, the quality of work and therefore the productivity of the team will be reduced. In 2001, Tom deMarco released Slack: Getting Past Burnout, Busywork and the Myth of Total Efficiency, an entire book describing the problems created by trying to achieve 100% utilization. I highly recommend the book, and also recommend you give your manager a copy. :) Here are some selected quotes that are pertinent to reducing the load on our processor and communication network: Very successful companies have never struck me as particularly busy; in fact, they are, as a group, rather laid back. Energy is evident in the workplace, but it's not the energy tinged with fear that comes from being slightly behind on everything. The principal resource needed for invention is slack. When companies can't invent, it's usually because their people are too damn busy. People under time pressure don't think faster. - Tim Lister How Can We Deal With This? First and foremost, stop trying to do so damned much! This is truly a slow down to go faster type of solution. For a Team If you're an agile team using iterations or sprints, pull less work into a sprint even if your velocity says you should be able to pull more. The extra time can be used to increase the quality of the work that you do complete, which is in itself a motivating factor for knowledge workers. Increased quality means decreased rework, which means the team as a whole delivers faster over the long term. Similarly, the reduced anxiety and stress on the team members increases their ability to think about what they're doing, meaning better and more innovative solutions to problems. Also, ensure that teams are focusing on activities that contribute directly to their work. Meetings tend to be the worst offenders of this, including the meetings defined within agile processes. Some suggestions: No meeting can be scheduled unless there is a specific question to be answered or specific information to be passed along. Reduce the default meeting length from 1 hour to 30 minutes in whatever calendar tool you use. Even better, reduce it to 20 minutes. Choose blocks of time that are deemed meeting free zones. No one, regardless of their position in the org chart can schedule a meeting with the team or the team members during that time. Minimize meetings where people are on a phone. My observation is that people who call into meetings tend to speak longer than when they are in the room with everyone else. I know that I do this, and I see it often in others. For an Individual Learn to say, "No." At the very least, learn to say, "Not yet." It's really difficult to do this, and I speak from personal experience. We want to help others, we want to be team players. However, if we don't say no, we take on too much, our processing and communication ability suffers and we end up disappointing those we were trying to help! Also, learn to take breaks. Yes, take breaks. The same concepts from Slack apply here, with brief diversions clearing our mind and allowing us to work better afterwards. At the extreme, if you feel like you can't keep your eyes open, take a nap! I highly recommend the Pomodoro Technique as at least a starting point for giving yourself some slack. Step away from your work for just a few minutes and return recharged. Conclusion We don't want the CPU in our computer to be working at 100% and we don't want the communications network to which it's connected to be at 100% capacity either. Our brains are processors and teams are a communications network, so why would we want those to be 100% busy all the time? In fact, ensuring that teams and the people on them are always busy is a provably wrong approach for software development. It has it's roots in a manufacturing mindset and developing software is knowledge work. Software development requires substantially different ways to make teams and the individual people on them as productive as possible. Finally, there is no magic number for what percentage of utilization is best. People are variable and 90% utilization for a person might be fine on a given day while %30 is all that the same person can handle on the next. Don't aim for a number, aim for an environment where people know that they don't have to appear busy. That will leave plenty of capacity for each person's processor and their team's communications network to run smoothly and deliver real value more effectively.
March 12, 2015
by Dave Rooney
· 22,584 Views · 2 Likes
article thumbnail
How to Support Multi-Speed IT with DevOps and Agile
These days a lot of organizations talk about Multi-Speed IT, so I thought I’d share my thoughts on this. I think the concept has been around for a while but now there is a nice label to associate this idea with. Let’s start by looking at why Multi-Speed IT is important. The idea is best illustrated by a picture of two interlocking gears of different sizes and by using a simple example to explain the concept. Different Speeds for Different Needs One easy way to recall what multi-speed IT looks like is to remember that there are multiple speeds for multiple needs. This is to say that there are different IT programs that may be most useful at various speeds. Some departments and applications need to move very rapidly, but others can move at a slower pace that works best for them. Regardless of which department you are focused on at the moment, it is important to know that it will have specialized needs that you need to look after, and that is why so many people are now looking at multi-speed IT as the best way to accomplish what they set out to accomplish. The smaller gear moves much faster than the larger one, but where the two gears interlock they remain aligned to not stop the motion. But what does this mean in reality? Think about a banking app on your mobile. Your bank might update the app on a weekly basis with new functionality like reporting and/or an improved user interface. That is a reasonable fast release cycle. The mainframe system that sits in the background and provides the mobile app with your account balance and transaction details does not have to change at the same speed. In fact, it might only have to provide a new service for the mobile app once every quarter. Nonetheless, the changes between those two systems need to align when new functionality is rolled out. However, it doesn’t mean both systems need to release at the same speed. In general, the customer-facing systems are the fast applications (Systems of Engagement, Digital) and the slower ones are the Systems of Record or backend systems. The release cycles should take this into consideration. So how do you get ready for the Multi-Speed IT Delivery Model? Release Strategy (Agile) – Identify functionality that requires changes in multiple systems and ones that can be done in isolation. If you follow an Agile approach, you can align every n-th release for releasing functionality that is aligned while the releases in between can deliver isolated changes for the fast-moving applications. Application Architecture – Use versioned interface agreements so that you can decouple the gears (read applications) temporarily. This means you can release a new version of a backend system or a front-end system without impacting the current functionality of the other. Once the other system catches up, new functionality becomes available across the system. This allows you to keep to your individual release schedule, which in turn means delivery is a lot less complex and interdependent. In the picture I used above, think of this as the clutch that temporarily disengages the gears. Technical Practices and Tools (DevOps) – If the application architecture decoupling is the clutch, then the technical practices and tools are the grease. This is where DevOps comes into the picture. The whole idea of Multi-Speed IT is to make the delivery of functionality less interdependent. On the flip side, you need to spend more effort on getting the right practices and tools in place to support this. For example, you want to make sure that you can quickly test the different interface versions with automated testing, you need to have good version control to make sure you have in place the right components for each application, and you also want to make sure you can manage your code line very well through abstractions and branching where required. And the basics of configuration management, packaging, and deployment will become even more important as you want to reduce the number of variables you have to deal with in your environments. You better remove those variables introduced through manual steps by having these processes completely automated. Testing strategies – Given that you are now dealing with multiple versions of components being in the environment at the same time, you have to rethink your testing strategies. The rules of combinatorics make it very clear that it only takes a few different variables before it becomes unmanageable to test all permutations. So we need to think about different testing strategies that focus on valid permutations and risk profiles. After all, functionality that is not yet live requires less testing than the ones that will go live next. The above points cover the technical aspects but to get there you will also have to solve some of the organizational challenges. Let me just highlight 3 of them here: Partnership with delivery partners – It will be important to choose your partners wisely. Perhaps it helps to think of your partner ecosystem in three categories: Innovators (the ones who work with you in innovative spaces and with new technologies), Workhorses(the ones who support your core business applications that continue to change) and Commodities (the ones who run legacy applications that don’t require much new functionality and attention). It should be clear that you need to treat them differently in regards to contracts and incentives. I will blog later about the best way to incentivize your workhorses, the area that I see most challenges in. Application Portfolio Management - Of course, to find the right partner you first need to understand what your needs are. Look across your application portfolio and determine where your applications sit across the following dimensions: Importance to business, exposure to customers, frequency of change, and volume of change. Based on this you can find the right partner to optimize the outcome for each application. Governance – Last but not least, governance is very important. In a multi-speed IT world you will need flexible governance. One size fits all will not be good enough. You will need lightweight system-driven governance for your high-speed applications and you can probably afford a more PowerPoint/Excel-driven manual governance for your slower-changing applications. If you can run status reports of live systems (like Jira, RTC, or TFS) for your fast applications you are another step closer to mastering the multi-speed IT world.
March 2, 2015
by Mirco Hering DZone Core CORE
· 8,363 Views
article thumbnail
We Can't Measure Programmer Productivity… or Can We?
If you go to Google and search for "measuring software developer productivity" you will find a whole lot of nothing. Seriously -- nothing. Nick Hodges, Measuring Developer Productivity By now we should all know that we don’t know how to measure programmer productivity. There is no clear cut way to measure which programmers are doing a better or faster job, or to compare productivity across teams. We “know” who the stars on a team are, who we can depend on to deliver, and who is struggling. And we know if a team is kicking ass – or dragging their asses. But how do we prove it? How can we quantify it? All sorts of stupid and evil things can happen when you try to measure programmer productivity. But let’s do it anyways. We’re Writing More Code, So We Must Be More Productive Developers are paid to write code. So why not measure how much code they write – how many lines of code get delivered? Because we've known since the 1980s that this is a lousy way to measure productivity. Lines of code can’t be compared across languages (of course), or even between programmers using the same language working in different frameworks or following different styles. Which is why Function Points were invented – an attempt to standardize and compare the size of work in different environments. Sounds good, but Function Points haven’t made it into the mainstream, and probably never will – very few people know how Function Points work, how to calculate them and how they should be used. The more fundamental problem is that measuring productivity by lines (or Function Points or other derivatives) typed doesn’t make any sense. A lot of important work in software development, the most important work, involves thinking and learning – not typing. The best programmers spend a lot of time understanding and solving hard problems, or helping other people understand and solve hard problems, instead of typing. They find ways to simplify code and eliminate duplication. And a lot of the code that they do write won’t count anyways, as they iterate through experiments and build prototypes and throw all of it away in order to get to an optimal solution. The flaws in these measures are obvious if we consider the ideal outcomes: the fewest lines of code possible in order to solve a problem, and the creation of simplified, common processes and customer interactions that reduce complexity in IT systems. Our most productive people are those that find ingenious ways to avoid writing any code at all. Jez Humble, The Lean Enterprise This is clearly one of those cases where size doesn’t matter. We’re Making (or Saving) More Money, so We Must Be Working Better We could try to measure productivity at a high level using profitability or financial return on what each team is delivering, or some other business measure such as how many customers are using the system – if developers are making more money for the business (or saving more money), they must be doing something right. Using financial measures seems like a good idea at the executive level, especially now that “every company is a software company”. These are organizational measures that developers should share in. But they are not effective – or fair – measures of developer productivity. There are too many business factors are outside of the development team’s control. Some products or services succeed even if the people delivering them are doing a lousy job, or fail even if the team did a great job. Focusing on cost savings in particular leads many managers to cut people and try “to do more with less” instead of investing in real productivity improvements. And as Martin Fowler points out there is a time lag, especially in large organizations – it can sometimes take months or years to see real financial results from an IT project, or from productivity improvements. We need to look somewhere else to find meaningful productivity metrics. We’re Going Faster, so We Must Be Getting More Productive Measuring speed of development – velocity in Agile – looks like another way to measure productivity at the team level. After all, the point of software development is to deliver working software. The faster that a team delivers, the better. But velocity (how much work, measured in story points or feature points or ideal days, that the team delivers in a period of time) is really a measure of predictability, not productivity. Velocity is intended to be used by a team to measure how much work they can take on, to calibrate their estimates and plan their work forward. Once a team’s velocity has stabilized, you can measure changes in velocity within the team as a relative measure of productivity. If the team’s velocity is decelerating, it could be an indicator of problems in the team or the project or the system. Or you can use velocity to measure the impact of process improvements, to see if training or new tools or new practices actually make the team’s work measurably faster. But you will have to account for changes in the team, as people join or leave. And you will have to remember that velocity is a measure that only makes sense within a team – that you can’t compare velocity between teams. Although this doesn't stop people from trying. Some shops use the idea of a well-known reference story that all teams in a program understand and use to base their story points estimates on. As long as teams aren't given much freedom on how they come up with estimates, and as long as the teams are working in the same project or program with the same constraints and assumptions, you might be able to do rough comparison of velocity between teams. But Mike Cohn warns that If teams feel the slightest indication that velocities will be compared between teams there will be gradual but consistent “point inflation.” ThoughtWorks explains that velocity <> productivity in their latest Technology Radar: We continue to see teams and organizations equating velocity with productivity. When properly used, velocity allows the incorporation of “yesterday's weather” into a team’s internal iteration planning process. The key here is that velocity is an internal measure for a team, it is just a capacity estimate for that given team at that given time. Organizations and managers who equate internal velocity with external productivity start to set targets for velocity, forgetting that what actually matters is working software in production. Treating velocity as productivity leads to unproductive team behaviors that optimize this metric at the expense of actual working software. Next: Just Stay Busy, Measure Outcomes, not Output; and more... Just Stay Busy One manager I know says that instead of trying to measure productivity “We just stay busy. If we’re busy working away like maniacs, we can look out for problems and bottlenecks and fix them and keep going”. In this case you would measure – and optimize for – cycle time, like in Lean manufacturing. Cycle time – turnaround time or change lead time, from when the business asks for something to when they get it in their hands and see it working – is something that the business cares about, and something that everyone can see and measure. And once you start looking closely, waste and delays will show up as you measure waiting/idle time, value-add vs. non-value-add work, and process cycle efficiency (total value-add time / total cycle time). “It’s not important to define productivity, or to measure it. It’s much more important to identify non-productive activities and drive them down to zero.” Erik Simmons, Intel Teams can use Kanban to monitor – and limit – work in progress and identify delays and bottlenecks. And Value Stream Mapping to understand the steps, queues, delays and information flows which need to be optimized. To be effective, you have to look at the end-to-end process from when requests are first made to when they are delivered and running, and optimize all along the path, not just the work in development. This may mean changing how the business prioritizes, how decisions are made and who makes the decisions. In almost every case we have seen, making one process block more efficient will have a minimal effect on the overall value stream. Since rework and wait times are some of the biggest contributors to overall delivery time, adopting “agile” processes within a single function (such as development) generally has little impact on the overall value stream, and hence on customer outcomes. Jezz Humble, The Lean Enterprise The down side of equating delivery speed with productivity? Optimizing for cycle time/speed of delivery by itself could lead to problems over the long term, because this incents people to think short term, and to cut corners and take on technical debt. We’re Writing Better Software, so We Must Be More Productive “The paradox is that when managers focus on productivity, long-term improvements are rarely made. On the other hand, when managers focus on quality, productivity improves continuously.” John Seddon, quoted in The Lean Enterprise We know that fixing bugs later costs more. Whether it’s 10x or 100+x, it doesn't really matter. And that projects with fewer bugs are delivered faster – at least up to a point of diminishing returns for safety-critical and life-critical systems. And we know that the costs of bugs and mistakes in software to the business can be significant. Not just development rework costs and maintenance and support costs. But direct costs to the business. Downtime. Security breaches. Lost IP. Lost customers. Fines. Lawsuits. Business failure. It’s easy to measure that you are writing good – or bad – software. Defect density. Defect escape rates (especially defects – including security vulnerabilities – that escape to production). Static analysis metrics on the code base, using tools like SonarQube. And we know how to write good software - or we should know by now. But is software quality enough to define productivity? Devops – Measuring and Improving IT Performance Devops teams who build/maintain and operate/support systems extend productivity from dev into ops. They measure productivity across two dimensions that we have already looked at: speed of delivery, and quality. But devops isn't limited to just building and delivering code – instead it looks at performance metrics for end-to-end IT service delivery: Delivery Throughput: deployment frequency and lead time, maximizing the flow of work into production Service Quality: change failure rate and MTTR It’s not a matter of just delivering software faster or better. It’s dev and ops working together to deliver services better and faster, striking a balance between moving too fast or trying to do too much at a time, and excessive bureaucracy and over-caution resulting in waste and delays. Dev and ops need to share responsibility and accountability for the outcome, and for measuring and improving productivity and quality. As I pointed out in an earlier post this makes operational metrics more important than developer metrics. According to recent studies, success in achieving these goals lead to improvements in business success: not just productivity, but market share and profitability. Measure Outcomes, not Output In The Lean Enterprise (which you can tell I just finished reading), Jez Jumble talks about the importance of measuring productivity by outcome – measuring things that matter to the organization – not output. “It doesn't matter how many stories we complete if we don’t achieve the business outcomes we set out to achieve in the form of program-level target conditions”. Stop trying to measure individual developer productivity. It’s a waste of time. Everyone knows who the top performers are. Point them in the right direction, and keep them happy. Everyone knows the people who are struggling. Get them the help that they need to succeed. Everyone knows who doesn't fit in. Move them out. Measuring and improving productivity at the team or (better) organization level will give you much more meaningful returns. When it comes to productivity: Measure things that matter – things that will make a difference to the team or to the organization. Measures that are clear, important, and that aren't easy to game. Use metrics for good, not for evil – to drive learning and improvement, not to compare output between teams or to rank people. I can see why measuring productivity is so seductive. If we could do it we could assess software much more easily and objectively than we can now. But false measures only make things worse. Martin Fowler, CannotMeasureProductivity
January 30, 2015
by Jim Bird
· 29,023 Views
article thumbnail
Why Customers Choose Datical DB to Automate Database Deployments
Over the past year, Datical has had amazing success with our flagship product, Datical DB. We’ve seen multiple visionary, sector-leading companies select Datical DB to drive their Application Schema changes. Now that the number has grown rapidly over the past year, we can begin to see patterns in why customers choose Datical DB. One of them turns out to be pretty emblematic of our other customers. So, let’s examine the reasons why they chose to adopt Datical DB. Customer Facing Applications are the Front Door When your competitor is only a mobile screen swipe away, this Datical customer focuses on brand reputation and customer satisfaction. They know that application uptime and fast delivery are key to customer retention and account expansion. All applications have a database backend. Though, when something goes wrong with the database, it is not apparent to the consumer. The consumer just knows that the app isn’t working. An unresponsive mobile app or website is often enough to make the customer take their business elsewhere. Customer stickiness due to the hassle of changing providers continues to lessen as the cost to change continues to drop. Therefore, immediate and fast access is a must have for today’s companies. Remember: Consumer facing applications don’t have business hours. They must ALWAYS be open. Cross Team Collaboration This Datical customer had difficulty in determining who made what change to the database. Moreover, answering which database and why was near impossible. All of the changes were stored in a single document. That solution is not multi-tenant, meaning that the team had to distribute the document to share information. Moreover, there was a single point of failure in the tracking process. Too often, people were required to visit the datacenter for days at a time during application changes. There was simply no method to notify team members of changes, when they occurred, and the change impact. This lack of communication led to almost 80% of all database change requests being rejected. There was clearly a need to increase communication of changes and increase the requested changes’ quality. Increase Staff Productivity With over 70% of the Database team’s time spent on managing change due to application requirements, the Database team was taxed in meeting other demands. Needs to improve scalability and reliability of the database servers became a lower priority as the DBAs struggled to keep up with change requests. Furthermore, development teams spent almost 10% of their time managing these change requests, including reworks of failed requests. By eliminating a manual, time-consuming process, this customer can now focus resources on addressing other needs such as managing continuity during server failure, better allocation of server resources, and certainly scalability concerns. Go Faster With the adoption of IBM UrbanCode Deploy, this customer quickly streamlined their deployments with all but the database automated. With all other components automated, the database changes required by application changes was clearly the weak link in the deployment chain. Truly, database automation is the last mile necessary to realize the promise of Agile, Continuous Delivery, and DevOps. Until the customer was able to apply Agile and Continuous Delivery to database changes, the entire application stack was, in effect, still using out-of-date development and deployment methods. To see the complete benefits of Agile and Continuous Delivery, automation throughout the entire stack, including the database, was absolutely necessary. Leverage Existing Infrastructure and Processes With out of the box integration with UrbanCode Deploy, Datical DB did not require an independent separate server. Furthermore, with Datical DB’s ability to utilize the customer’s existing source code control repository, the implementation cycle was shortened significantly. Too often, customers are asked by vendors to spend money on more server resources or make strange, unnatural changes to their network security to support potential solutions. By utilizing existing infrastructure and processes, Datical DB was able to deliver to this customer lightening quick ROI. We measure ROI in days and weeks, not months and years. Please join us for a webcast next Wednesday, February 4th, from 12:00 – 1:00 pm EST, as we discuss these customer benefits in detail and show how Datical DB integrates seamlessly with IBM UrbanCode Deploy.
January 30, 2015
by Robert Reeves
· 8,363 Views
article thumbnail
An Introduction to BDD Test Automation with Serenity and JUnit
serenity bdd (previously known as thucydides ) is an open source reporting library that helps you write better structured, more maintainable automated acceptance criteria, and also produces rich meaningful test reports (or "living documentation") that not only report on the test results, but also what features have been tested. and for when your automated acceptance tests exercise a web interface, serenity comes with a host of features that make writing your automated web tests easier and faster. 1. bdd fundamentals but before we get into the nitty-gritty details, let’s talk about behaviour driven development, which is a core concept underlying many of serenity’s features. behaviour driven development, or bdd, is an approach where teams use conversations around concrete examples to build up a shared understanding of the features they are supposed to build. for example, suppose you are building a site where artists and craftspeople can sell their good online. one important feature for such a site would be the search feature. you might express this feature using a story-card format commonly used in agile projects like this: in order for buyers to find what they are looking for more efficiently as a seller i want buyers to be able to search for articles by keywords to build up a shared understanding of this requirement, you could talk through a few concrete examples. the converstaion might go something like this: "so give me an example of how a search might work." "well, if i search for wool , then i should see only woolen products." "sound’s simple enough. are there any other variations on the search feature that would produce different outcomes?" "well, i could also filter the search results; for example, i could look for only handmade woolen products." and so on. in practice, many of the examples that get discussed become "acceptance criteria" for the features. and many of these acceptance criteria become automated acceptance tests. automating acceptence tests provides valuable feedback to the whole team, as these tests, unlike unit and integrationt tests, are typically expressed in business terms, and can be easily understood by non-developers. and, as we will se later on in this article, the reports that are produced when these teste are executed give a clear picture of the state of the application. 2. serenity bdd and junit in this article, we will learn how to use serenity bdd using nothing more than junit, serenity bdd, and a little selenium webdriver. automated acceptance tests can use more specialized bdd tools such as cucumber or jbehave, but many teams like to keep it simple, and use more conventional unit testing tools like junit. this is fine: the essence of the bdd approach lies in the conversations that the teams have to discuss the requirements and discover the acceptance criteria. 2.1. writing the acceptance test let’s start off with a simple example. the first example that was discussed was searching for wool . the corresponding automated acceptance test for this example in junit looks like this: @runwith(serenityrunner.class) public class whensearchingbykeyword { @managed(driver="chrome", uniquesession = true) webdriver driver; @steps buyersteps buyer; @test public void should_see_a_list_of_items_related_to_the_specified_keyword() { // given buyer.opens_etsy_home_page(); // when buyer.searches_for_items_containing("wool"); // then. buyer.should_see_items_related_to("wool"); } } the serenity test runner sets up the test and records the test results this is a web test, and serenity will manage the webdriver driver for us we hide implementation details about how the test will be executed in a "step library" our test itself is reduced to the bare essential business logic that we want to demonstrate there are several things to point out here. when you use serenity with junit, you need to use the serenityrunner test runner. this instruments the junit class and instantiates the webdriver driver (if it is a web test), as well as any step libraries and page objects that you use in your test (more on these later). the @managed annotation tells serenity that this is a web test. serenity takes care of instantiating the webdriver instance, opening the browser, and shutting it down at the end of the test. you can also use this annotation to specify what browser you want to use, or if you want to keep the browser open during all of the tests in this test case. the @steps annotation tells serenity that this variable is a step library. in serenity, we use step libraries to add a layer of abstraction between the "what" and the "how" of our acceptance tests. at the top level, the step methods document "what" the acceptance test is doing, in fairly implementation-neutral, business-friendly terms. so we say "searches for items containing wool ", not "enters wool into the search field and clicks on the search button". this layered approach makes the tests both easier to understand and to maintain, and helps build up a great library of reusable business-level steps that we can use in other tests. 2.2. the step library the step library class is just an ordinary java class, with methods annotated with the @step annotation: public class buyersteps { homepage homepage; searchresultspage searchresultspage; @step public void opens_etsy_home_page() { homepage.open(); } @step public void searches_for_items_containing(string keywords) { homepage.searchfor(keywords); } @step public void should_see_items_related_to(string keywords) { list resulttitles = searchresultspage.getresulttitles(); resulttitles.stream().foreach(title -> assertthat(title.contains(keywords))); } } //end:tail step libraries often use page objects, which are automatically instantiated the @step annotation indicates a method that will appear as a step in the test reports for automated web tests, the step library methods do not call webdriver directly, but rather they typically interact with page objects . 2.3. the page objects page objects encapsulate how a test interacts with a particular web page. they hide the webdriver implementation details about how elements on a page are accessed and manipulated behind more business-friendly methods. like steps, page objects are reusable components that make the tests easier to understand and to maintain. serenity automatically instantiates page objects for you, and injects the current webdriver instance. all you need to worry about is the webdriver code that interacts with the page. and serenity provides a few shortcuts to make this easier as well. for example, here is the page object for the home page: @defaulturl("http://www.etsy.com") public class homepage extends pageobject { @findby(css = "button[value='search']") webelement searchbutton; public void searchfor(string keywords) { $("#search-query").sendkeys(keywords); searchbutton.click(); } } what url should be used by default when we call the open() method a serenity page object must extend the pageobject class you can use the $ method to access elements directly using css or xpath expressions or you may use a member variable annotated with the @findby annotation and here is the second page object we use: public class searchresultspage extends pageobject { @findby(css=".listing-card") list listingcards; public list getresulttitles() { return listingcards.stream() .map(element -> element.gettext()) .collect(collectors.tolist()); } } in both cases, we are hiding the webdriver implementation of how we access the page elements inside the page object methods. this makes the code both easier to read and reduces the places you need to change if a page is modified. this approach encourages a very high degree of reuse. for example, the second example mentioned at the start of this article involved filtering results by type. the corresponding automated acceptance criteria might look like this: @test public void should_be_able_to_filter_by_item_type() { // given buyer.opens_etsy_home_page(); // when buyer.searches_for_items_containing("wool"); int unfiltereditemcount = buyer.get_matching_item_count(); // and buyer.filters_results_by_type("handmade"); // then buyer.should_see_items_related_to("wool"); // and buyer.should_see_item_count(lessthan(unfiltereditemcount)); } @test public void should_be_able_to_view_details_about_a_searched_item() { // given buyer.opens_etsy_home_page(); // when buyer.searches_for_items_containing("wool"); buyer.selects_item_number(5); // then buyer.should_see_matching_details(); } notice how most of the methods here are reused from the previous steps: in fact, only two new methods are required. 3. reporting and living documentation reporting is one of serenity’s fortes. serenity not only reports on whether a test passes or fails, but documents what it did, in a step-by-step narrative format that inculdes test data and screenshots for web tests. for example, the following page illustrates the test results for our first acceptance criteria: figure 1. test results reported in serenity but test outcomes are only part of the picture. it is also important to know what work has been done, and what is work in progress. serenity provides the @pending annotation, that lets you indicate that a scenario is not yet completed, but has been scheduled for work, as illustrated here: @runwith(serenityrunner.class) public class whenputtingitemsintheshoppingcart { @pending @test public void shouldupdateshippingpricefordifferentdestinationcountries() { } } this test will appear in the reports as pending (blue in the graphs): figure 2. test result overview we can also organize our acceptance tests in terms of the features or requirements they are testing. one simple approach is to organize your requirements in suitably-named packages: |----net | |----serenity_bdd | | |----samples | | | |----etsy | | | | |----features | | | | | |----search | | | | | | |----whensearchingbykeyword.java | | | | | | |----whenviewingitemdetails.java | | | | | |----shopping_cart | | | | | | |----whenputtingitemsintheshoppingcart.java | | | | |----pages | | | | | |----homepage.java | | | | | |----itemdetailspage.java | | | | | |----registerpage.java | | | | | |----searchresultspage.java | | | | | |----shoppingcartpage.java | | | | |----steps | | | | | |----buyersteps.java all the test cases are organized under the features directory. test cass related to the search feature test cases related to the ‘shopping cart’ feature serenity can use this package structure to group and aggregate the test results for each feature. you need to tell serenity the root package that you are using, and what terms you use for your requirements. you do this in a special file called (for historical reasons) thucydides.properties , which lives in the root directory of your project: thucydides.test.root=net.serenity_bdd.samples.etsy.features thucydides.requirement.types=feature,story with this configured, serenity will report about how well each requirement has been tested, and will also tell you about the requirements that have not been tested: figure 3. serenity reports on requirements as well as tests 4. conclusion hopefully this will be enough to get you started with serenity. that said, we have barely scratched the surface of what serenity can do for your automated acceptance tests. you can read more about serenity, and the principles behind it, by reading the users manual , or by reading bdd in action , which devotes several chapters to these practices. and be sure to check out the online courses at parleys . you can get the source code for the project discussed in this article on github .
December 12, 2014
by John Ferguson Smart
· 59,811 Views · 6 Likes
article thumbnail
Monoliths, Cookie-Cutter or Microservices
recently some pwc tech supremos wrote an article: agile coding in enterprise it: code small and local . subsections: moving away from the monolith why microservices? msa: a think-small approach for rapid development thinking the msa way: minimalism is a must where msa makes sense in msa, integration is the problem, not the solution conclusion msa is short for microservices architecture(s), in the above article. the article posits that microservices is the antidote to monoliths. it doesn’t mention cookie cutter scaling at all, which is another antidote to monoliths, with the right build infrastructure and devops. here’s a view of hypothetical architecture a company could deploy if they were doing microservices: w is web server. p and q don’t stand for anything in particular. here’s the same solution as cookie-cutter scaling, and the alternate (historical) choice of monolith to the right of it: the cookie cutter approach will often leverage components that are dependency injected into each other, and though monoliths might be the same today, pre 2004 they were probably hairballs of singletons (the design patten, not the springframework idiom). continuous delivery, agile? here’s one excerpt that confuses me: " … makes no sense to design and develop software over an 18-month process to accommodate all possible use cases when those use cases can change unexpectedly and the life span of code modules might be less than 18 months…. as i recall, the 18 month-delay problem was solved previously. agile methodologies principally, and continuous delivery/deployment in more recent times. it does not matter whether you’re compiling a monolith, a cookie-cutter solution, old soa services, or microservices, the 18-month fear isn’t real if you’re doing agile and/or cd. agile and cd were increasing the release cadence, and allowing the organization to pivot faster before microservices. it doesn’t matter whether you’ve got a monolith, something cookie-cutter scaled, or soa (micro or not), you’re going to be able to benefit from agile practices and devops setup that facilitates cd. in something like 30 thoughtworks client engagements since 2002, i have not seen the 18-month process at all. in fact i last encountered it in 1997 on an as/400 project, which was the last time i saw a waterfall process being championed. build(s) and trunk elsewhere there is a suggestion: “each microservice [has] its own build, to avoid trunk conflict”. that isn’t unique to microservices, of course. component based systems today also have a multiple build file (module) structure in a source tree. hopefully “trunk” mentioned is alluding to trunk based development, as i would recommend. build technologies this is a expansion on the above, and you can skip this paragraph if you want. hierarchical build systems like maven has allow you to have one build file per module (whether that’s a service or a simple jar destined for the classpath of a bigger thing). buck has a build grammar that allows for a build to grow/shrink/change based on what is being built (from implicitly shared source). maven is for the java ecosystem, while buck promises to be multi-language. both are doing multi-module builds for the sake of a composed or servicified deployment. both maven and buck are presently competing to draw the most reduced set of compile/test/deploy operations for the changes since last build for a hierarchy of modules. anyway, what is it we are striving for? what we want is to develop cheaply, and to deploy smoothly and often, without defect. we want the ability to deploy without large permanent or temporary headcount overseeing or participating in deployment. aside from development costs, and support/operation, deployment costs are a potentially big factor in total cost of ownership. what i like about cookie-cutter is the uniformity of the deployable things. the team size for deployment of such a thing doesn’t grow with the numbers of nodes that binary is being deployed to. at least, if you’re able to automate the deployment to those nodes, and have a strategy for handling the users connected to the stack at redeployment time somehow (sessions or stateless). the uniformity of the deployment is a cheapener, i think. when you have a number of dissimilar services, you might be able to minimize release personnel if you’re only doing one service. if more than one service is being updated in a particular deployment, you’re going to have to concentrate to make sure you don’t experience a multiplier effect for the participants. it is possible of course, to keep the headcount small, but the practice needed beforehand is bigger, which in turn allows for some calmness around the actual deployment. if we’ve stepped away from the project management office thinking that suggests three buggy releases a year (which is more usual than 18 month schedules of old), then we can employ continuous deployment to further eliminate personnel costs around going live. this is something that microservices does well at, but because the most adept proponents design forwards & backwards compatibility into the permutations most likely to co-exist in production. it is at least much quicker to redeploy and bounce one small service, n times than the the cookie-cutter uniform deployment.
December 10, 2014
by Paul Hammant
· 6,018 Views
article thumbnail
What is Product Management?
I often get asked what it takes to be an effective product manager or product owner, which product skills the individuals should have, and how a company can strengthen its product management function. Answering these questions requires an understanding of what effective product management looks like in the digital age. The following picture shows how I view product management: It depicts a product management framework that consists of six core knowledge areas and by six supporting ones. The core areas are orange and placed centrally. The supporting ones are purple and located at the edge of the circle. You can download the picture for free by simply clicking on it or from romanpichler.com/tools/product-management-framework. The core areas are particularly important for doing a great job as a product manager or product owner. You should hence strive to become knowledgeable in all of them. The supporting areas are also important for your work, especially when you manage commercial products, but generally not as crucial. If the product management framework with its knowledge areas feels overwhelming then don’t worry: Product management is a complex and demanding discipline that is not easy to master. It takes time and effort to become a competent product manager or product owner. The good news is that you can use the framework to spot gaps in your skill set so you can address them. The Core Knowledge Areas Vision and Leadership: Working as an effective product managers or product owner requires vision and leadership skills. You should be able to establish a shared vision, set realistic goals, and describe the benefits your product should deliver. You should be able to actively listen to others and negotiate to reach agreement and get buy-in. At the same time, you should not shy away from making the right product decisions even if they are tough and do not please everyone. You should be able to manage the stakeholders including customers and users, senior management, development, marketing, sales, support, and other business groups that have to contribute to the product success. You should be able to effectively communicate with and influence them. You be comfortable working with a broad range of people from diverse backgrounds including a cross-functional development team. Product Lifecycle Management: Managing a product successfully involves more than getting it built and released. You should understand the product lifecycle with its stages and the key events in the life of your product including launch, product-market fit, and end of sales; you should know how the lifecycle helps you maximise the benefits your product creates across its entire life; this includes the lifecycle’s impact on the product performance (revenue and profits), the product goals, the pricing and the marketing strategy; the options to revive growth as your product matures and growth starts to stagnate; and the process best suited for each lifecycle stage. (An iterative, Lean Startup and Scrum-based process tends to beneficial while your product is young; Kanban is usually preferable when your product starts to mature.) Product Strategy and Market Research: Your product exists to serve a market or market segment, a group of people whose need the product addresses. You therefore should be able to identify your target users and customers and segment the market; you should be able to clearly state the value proposition of your product, why people would want to use and buy it and why your product does a great job at creating value for them. You should be able to carry out a competitor analysis to understand their respective strengths and weaknesses; you should be able to position your product, and determine the values the brand needs to communicate. You should be able to perform the necessary market research work to test your ideas and assumptions about the market segment and the value proposition. This includes qualitative and quantitative methods including problem interviews, direct observations, and employing minimum viable products (MVPs); you should be able to leverage data to make the right decisions. This includes using an analytics tool, analysing the data effectively, and deciding if you should pivot and change your strategy or if you should persevere and refine it. Business Model and Financials: To provide an investment incentive for your company and to make developing and providing the product sustainable, you have to be able to determine the value the product creates for your firm. You should be able to formulate and prioritise business goals, for instance, enter a new market, meet a revenue or profit goal, save cost, or develop the brand. You should be able to describe how your product’s value proposition is monetised and capture how the business model works including the revenue sources and the main cost factors. You should also be able to create a financial forecast or business case that describes when a break-even is likely to occur and when your product may become profitable. In practice, you may want to partner with a colleague from the finance department to carry out this work. Product Roadmap: Many people have to contribute to the success of a digital product. To help them do their work and to provide visibility of how your product is likely to evolve, you should be able to create and use a product roadmap. This includes formulating realistic product goals (benefits), metrics and key performance indicators (KPIs), release dates or timeframes, and key features (deliverables or results). You should be clear on the relationship between the product strategy and the product roadmap. You should be able to formulate a go-to-market strategy and capture it in your roadmap. You should understand when the roadmap should be reviewed and changed. User Experience and Product Backlog: A great product has to offer a great user experience (UX). You should be able to describe the desired user experience. This includes describing users and customer as personas, capturing the user interaction, the visual design, the functional and the non-functional aspects of your product together with the help of the cross-functional team (a UX/UI expert should be part of the team). You should be able to create scenarios, epics, user stories, storyboards, workflow diagrams and storymaps, and be able to work with user interface sketches and mock-ups. You should be able to stock and manage the product backlog, prioritise it effectively, and select sprint goals. You should know how to understand if you develop a product with the right features and the right UX, how to test the appropriate aspects of your product and how to collect the relevant feedback and data. This includes the ability to perform product demoes, solution interviews, usability tests, A/B tests, and direct observation. You should be able to use an analytics tool to retrieve the relevant data and be able to analyse it effectively. You be able to change (or “groom”) the product backlog using the newly gained insights. Continue reading... The Supporting Knowledge Areas General Market Knowledge: Understand who your current customers and users are, what product you offer them today including their value proposition and business model, what competitors you have, how big your market share currently is, and which market segments you serve well. Development/Technologies: Be a competent partner for development/IT/engineering, have an interest in software technologies, be comfortable collaborating with a cross-functional technical team. Marketing: Be a respected partner for (product) marketing; be able to help select the right select the right marketing channels and to determine the right marketing mix; help marketing with creating the marketing collateral. Sales and Support: Be a respected partner for sales and support; be able to help select the right sales channels and create the sales collateral and training. Project/Release management: Be able to determine the primary success factor for a major release/product version and to steer the development project; be able to determine the project progress to forecast the progress, for instance, using a release burndown chart; be able to work with the Definition of Done; be able to trade-off scope, time, and budget. Process: Have a good understanding of ideation and innovation processes to generate and select ideas and to bring new products and new features to life. These should include Customer Development/Lean Startup, Business Model Generation, Scrum, and Kanban. Defining Product Roles with the Framework My product management framework helps you define product roles and the skills and responsibilities they should have. Using the framework, I can, for instance, define the role of a product owner in the following way: As the picture above shows, a product owner should have strategic product management skills such as product strategy and roadmapping as well as tactical ones (UX and product backlog). I have circled the areas, which are required by Scrum – the framework in which the role originated – in dark orange. The other areas are necessary to allow the product owner to do a great job and achieve product success even though they are not mandated by Scrum. You may, of course, disagree with my take on the product owner role and may want to use the framework to capture your definition of the role. Another example of how you can apply the framework is the description of the role of a tech product manager, a product manager who looks after a technical product and requires more in-depth technology/development skills, as the following picture illustrates. For instance, one of my clients is a major games development company, which has its own in-house developed physics engine, a complex piece of software that does all the clever animation. The product owner of the physics engine is a former developer. This makes sense, as the individual requires a detailed technical knowledge about the product and has to be able to communicate effectively with the users, the game developers. If you work as a product manager who looks after digital products that are developed and used in-house, for instance, a finance or HR application, then you probably have to tailor the supporting areas as the following picture shows: In the picture above, I have removed “Marketing” and replaced “Sales and Support” with “Operations”. I have kept “General Market Knowledge” as it is desirable for the product manager of a finance application to understand the market, that is, how the finance group works, what problems people struggle with, which products they use, and so forth. Determining Learning Measures with the Framework You can also use the product management framework to identify gaps in your skill set. Use the knowledge areas and reflect on your own knowledge. Then identify the areas where you lack some knowledge and skills, as I have done in the picture below by high-lightening the areas, which product owners often need to strengthen in my experience. Then rank them by determining how much the lack of knowledge is preventing you from doing a great job. For instance, a lack of product lifecycle management and product roadmap skills may be hurting you most if you manage a product that is in the growth stage. Finally identify how you best close the gap, for instance, reading one or more books, or blogs, attending a training course, finding someone to mentor or coach you, forming a community of practice with your fellow product managers or product owners to share knowledge and support each other. You can do the same exercise for a group of product managers or product owners to identify learning measure for the entire function. Learn More You can learn more about specific areas such as vision and leadership, product strategy and market research, product roadmap, or user experience and product backlog by attending one of my training courses. I also teach my courses onsite and in from of interactive virtual training sessions. If you would like me to help you apply the framework, define roles, or identify the right learning and development measures for product managers and product owners, then please contact me.
December 1, 2014
by Roman Pichler
· 21,146 Views · 9 Likes
article thumbnail
"How Thin is Thin?" An Example of Effective Story Slicing
Graphene is pure carbon in the form of a very thin, nearly transparent sheet, one atom thick. It is remarkably strong for its very low weight and it conducts heat and electricity with great efficiency. Wikipedia If you have spent any time at all working in an Agile software development environment, you've heard the mantra to split your Stories as thin as you possibly can while still delivering value. This is indeed great advice, but the term "thin" is relative - our notion of what thin means is anchored by our previous experience! To help communicate what I mean when I say that Stories should be thinly sliced, I'm going to provide examples from a recent client who was building a relatively standard system for entering orders from their wholesale customers. To start, here's a very simplified model of the entities we'll be working with (using GML - the Galactic Modeling Language). In plain language, the system creates Orders, which have a Customer and from 1 to some number of Products. For initial planning, the team (consisting of developers, QA person, business analyst and product owner) used Jeff Patton's Story Mapping technique to determine what work the salespeople did at a relatively high level. Not surprisingly, the group determined that creating an Order was the most fundamental part of the system! So we started with a simple sticky note with the title Create Order. Note that there wasn't any other descriptive text, no acceptance criteria, no indication of performance requirements, or even mention of how someone using the system would actually create the order. At this point, we simply didn't need all that - we just needed a placeholder for the conversations that were required for the action of creating orders. Everyone in the group knew that an order would need a customer and some number of products. When I asked what the first Story should be, reminding them that it should be very, very thin, the first suggestion was to have the user select a customer from a list, select products from a list, and save the order. I asked if it was possible to make that story even thinner, and received puzzled looks. I followed with another question - why did we need to select a customer at this point, or even products for that matter? More puzzled looks. Couldn't we just hard-code a customer ID and a single product SKU? More puzzled looks. Another question - if we presented a simple page with a button that when pressed created the order in our database with a hard-coded customer ID and a single, hard-coded product SKU, what percentage of the overall system infrastructure would be fleshed out. That was the point at which people started to understand. The response I received was, "Almost all of it... we need to render a page, capture the submit action, write the order to an Orders table, the product to the Order Lines table and the customer & product to the Customers and Products tables respectively". My response was, "Great!! But it's still a little too thick." More puzzled looks... how could that story be made any thinner? I asked, "Why do we need tables for Customers and Products right now?" More puzzled looks, followed by a sheepish, "Um, because...". The need to create those tables was an assumption at that point. Everyone in the room, myself included, knew that the database would have Customers and Products tables at some point, but we just didn't need them right now. All that was required from a persistence perspective was the Orders and Order Lines tables. Someone asked, "How do we know that the Customer ID and Product SKU are valid?" My response was, "We don't! And at this point, we don't care!" This is another way to split stories - assume the happy path where everything is valid, and build validation and error-handling later. So, this very thin story became, The acceptance criteria for the story were very simple as well: When you navigate to the page index.html, it should be displayed with a Submit button When the Submit button is clicked, the application creates one row in the Order table with a Customer ID of XXX, and one row in the Order Line table with a Product ID of YYY. Note that I could have gone even further and argued that we didn't even need the database yet. We could have simply used a flat file and broken all the rules of relational data modeling by putting all the Order and Order Line data in a single line in the file. Why? BECAUSE WE DIDN'T NEED IT YET! However, in the interest of establishing the overall architecture early, we decided to proceed with the database. It did add some complexity to the story, but it was on the order of hours rather than days or weeks. We also "gold-plated" the story to an extent by providing a rudimentary confirmation page that was displayed after submitting the Order. After the group created this one, simple, thin story with hard-coded values, the next steps were to gradually replace the hard-coding with the selections and searches that you would expect in this type of application. Subsequent stories were, You can now see the progression where the creation of an Order is gradually built out using very thin slices of functionality. Also note that the last two stories, which "wire up" the selection of Customers and Products to an external web service, could be implemented in either order - there is nothing in the story that indicates a dependency on anything else. Splitting Techniques In these stories we used several common splitting techniques: Hard coding values; Simple interface; Defer validation; Zero, then One, then Many (with the Products); Defer complexity. This is only a small handful of the available techniques, but it gave the group a powerful way to work in very, very small increments while still delivering some value with each one. We Can't Ship That!! The moment I suggested the first story with all the hard-coding, I was challenged by the group. Why would you want to build something that isn't production-worthy? The answer is that some aspects of the feature aren't production worthy when you look at the story in isolation. However, the whole concept of a Minimal Viable Product or Minimal Viable Feature is each consists of 1 to many smaller slices (stories in our case) that have been built together to provide enough value to warrant the cost of being put into production. The Product Owner or Product Manager is the person who decides when enough value has accrued to meet that threshold. The Benefits of Thin Slicing I've provide a number of examples from a real-world project but haven't really dug into the reasons why this is a good approach. There are a number of them: You are deferring design decisions as long as possible which gives you more options when it does come time to implement a Story; Having options also allows the Product Owner/Manager to defer business decisions as long as possible, providing the ability to make changes to the product that better suit the actual needs of the business; Thin slices (in conjunction with acceptance criteria) help prevent assumptions which can lead to bloated Stories that are seemingly never done, Agile's version of scope creep; Thin slices are much easier to verify since they are only providing a small increment of functionality beyond what has already been implemented; Thin slices allow a product to be reviewed sooner by both the Product Owner/Manager and users/stakeholders, such that their feedback can be incorporated sooner in the process; Thin slices allow the Product Owner/Manager decides to change or drop a Story without the burden of the Sunk Cost Fallacy. While these are all great reasons to split Stories into thin slices, here's the one that my experience suggests is by far the most important: With Stories sliced as thinly as possible, they all become nearly the same size in terms of effort. Therefore, no estimation of individual Stories is required and a team's capacity can simply be derived by counting the number of Stories completed for some unit of time. That means no haggling over whether a Story is a 3 or 5 on the modified Fibonacci series many teams use for sizing Stories. It means that the need for spending any time estimating individual Stories is no longer required, an activity that is downright painful for some groups. The group from which these examples came was in the situation where there was a hard release date to be met. This stories gave the Product Owner/Manager the ability to easily tweak the what was and wasn't going to be in that initial release and, in several cases which features could be released partially completed. If a group is in the situation where they are being asked for an estimate of when some work could be completed, my experience has also been that Story Mapping coupled with a technique called Blink Estimation provides a high-level estimate of the overall work that's much more grounded in reality. Once a group begins working on thinly-sliced Stories, you begin to have data points with respect to how many they can complete per some unit of time. Those real numbers can then be used to make better business decisions, and deliver a product without the pressure of Crunch Time. Conclusion The group with whom I worked for this example system never spent any time estimating individual Stories. Ever. There were some instances where a Story was larger than it first appeared, but those were either balanced out by Stories that were very small, or by further splitting. Like the graphene example at the beginning of the post, thin stories have remarkable properties far beyond the fact that they are just "thin". The value gained by learning how to split Stories effectively is enormous owing to the flexibility it provides by deferring decisions as long as possible and the removal of the need to estimate at a granular level. Splitting Stories this thin isn't really a specialized skill - it's something that can be learned by anyone in any domain. If you need help learning this technique, let's have a chat.
August 27, 2014
by Dave Rooney
· 35,601 Views
article thumbnail
From Personas to User Stories
1 Start with Personas The first step towards writing the right user stories is to understand your target users and customers. After all, user stories want to tell a story about the users using the product. If you don’t know who the users are and what problem we want to solve then it’s impossible to write the right stories and you end up with a long wish list rather than a description of the relevant product functionality. Personas offer a great way to capture the users and the customers with their needs. They are fictional characters that have a name and picture; relevant characteristics such as a role, activities, behaviours, and attitudes; and a goal, which is the problem that has to be addressed or the benefit that should be provided. Let’s look at an example. Say we want to create a game for children, which is fun to play and which educates the kids about music and dancing. We would then create at least two personas, one to represent the children, and one for the parents, as the following picture illustrates. The two sample personas above use my simple yet effective persona template. It encourages you to keep your personas concise, to focus on what really matters and to leave out the rest. You can download the template from romanpichler.com/tools/persona-template where more information on writing personas and using the template is available. Once you have created a cast of characters, select a primary persona, the persona you are mainly designing and building the product for. This helps you make the right product decision and get the user experience (UX) right. In the example above, I have chosen Yasmin as the primary persona. 2 Derive Epics from the Persona Goals Once you have created your personas, use their goals personas to identify the product functionality. Ask yourself what the product should do to address the personas’ problems or to create the desired benefits for them, as the following picture shows. Start with your primary persona and capture the functionality as epics, as coarse-grained, high-level stories. Write all the epics necessary to meet the persona goals but keep them rough and sketchy at this stage. For the dance game, we could write the epics below assuming that the game will be initially launched as an iPad app: As the epics above show, the game should allow the players to select different characters, to make them dance, to choose different dance floors and music tracks, to play the game with their friends, and to post a snapshot of their game on Facebook. While epics are great to sketch the product’s functionality, there is more to your product than epics and stories: You should also capture the user interaction and the sequences in which the epics are used, the visual design of your product, and the important nonfunctional qualities such as interoperability and performance. Use, for instance, workflow diagrams, story maps, storyboards, sketches, mock-ups, and constraint cards to describe them. You can find out more about describing the different product aspects in my post “User Stories are Not Enough to Create a Great User Experience”. 3 Progressively Decompose the Epics into User Stories With a holistic but coarse-grained description of your product in place start progressively decomposing your epics. Rather than detailing all epics and writing all user stories in one go, you derive your stories step by step as the following picture shows. As long as there are some significant risks present and you are figuring out what the product should look like and do, it’s best to derive just enough user stories just in time for the next sprint. Use your sprint goal or hypothesis to determine which epics to decompose and which stories to write as the following diagram illustrates. The approach depicted above minimises the amount of detailed items in your product backlog. This makes it easier to integrate new insights derived from exposing product increments or minimum viable products (MVPs) to users and customers. Say that we want to address the risk of creating the wrong game characters by developing an executable prototype that allows us to run a usability test with selected children. We could then write the following user stories: The stories above are derived from the epics “Choose character” and “Play with character”. The resulting prototype only partially implements the two epics – just to the extent of being able to test if the characters resonate with the users. Once you understand better how to meet the customer and user needs, you can start pre-writing user stories and have a larger inventory of detailed items on your product backlog as you are unlikely to experience bigger changes to your epics and your overall backlog. 4 Get the Stories Ready Before the development team starts working on the stories, check that each user story is ready: clear, feasible, and testable. A story is clear if there is a shared understanding between the product owner and the team about its meaning. It is feasible if it can be delivered in the next sprint according to the Definition of Done. This implies that the story is small enough to fit into the sprint but also that the necessary user interface design, test, and documentation work can be carried out. In the case of the sample stories above, we would have to add acceptance criteria, ensure that the stories are small enough to fit into the next sprint, and consider creating some very rough design sketches to indicate what the characters look like. For instance, to get the story “Yas chooses the little girl” ready, we could create the following rough sketch: The sketch above complement the user story and allows the team to implement the entire story including the visual design in the next sprint. With ready user stories in place the development team is in a good position to progress your product in an effective manner. For more details on getting user stories ready please take a look at my post “The Definition of Ready in Scrum”. Learn More You can learn more about writing the right epics and user stories by attending my Writing Great User Stories training course. If you want to learn more about the creating the UX artefacts mentioned in this post, then attend my Agile UX and Scrum training course. Please contact me if you are interested in having the courses delivered at your office. The persona pictures and the Manga girl sketch were created by Ole Størksen. Thanks Ole!
August 18, 2014
by Roman Pichler
· 15,371 Views · 5 Likes
article thumbnail
The Basics of Test-Driven Development
The objectives of Test Driven Development and unit testing are generally misunderstood. The problem is the word ‘test’, it is much less about testing and much more about specification of requirements, showing your working – as in maths, and the impact it has on design. TDD is much more important than only testing. Robert C Martin has a good analogy, he likens TDD to double entry bookkeeping: Software is a remarkably sensitive discipline. If you reach into a base of code and you change one bit you can crash the software. Go into the memory and twiddle one bit at random and very likely you will elicit some form of crash. Very, very few systems are that sensitive. You could go out to one of these bridges over here, start taking bolts out and they probably wouldn’t fall. I could pull out a gun and start shooting randomly and I probably wouldn’t kill too many people. I might wound a few but — you know — you get a bullet in the leg or a lung and you’d probably survive. People are resilient — they can survive the loss of a leg and so forth. Bridges are resilient — they survive the loss of components. But software isn’t resilient at all: one bit changes and — BANG! — it crashes. Very few disciplines are that sensitive. But there is one other [discipline] that is, and that’s Accounting. The right mistake at exactly the right time on the right spreadsheet — that one-digit error can crash the company and send the offenders off to jail. How do accountants deal with that sensitivity? Well, they have disciplines. And one of the primary disciplines is dual-entry bookkeeping. Everything is said twice. Every transaction is entered two times — once on the credit side and once on the debit side. Those two transactions follow separate mathematical pathways until they end up at this wonderful subtraction on the balance sheet that has to yield to zero. This is what test-driven development is: dual-entry bookkeeping. Everything is said twice — once on the test side and once on the production code side and everything runs in an execution that yields either a green bar or a red bar just like the zero on the balance sheet. It seems like that’s a good practice for us: to manage these sensitivities of our discipline… -Robert C. Martin The sensitivity of software is a good point to reflect upon, there is little in human experience that is so complex and yet so fragile. Without a strong focus on showing your working, no matter how good you are as a developer, if you omit the tests., your software will be worse than it could have been. The double-entry bookkeeping analogy only holds up though if you do test first development. If you write your test after the code it is generally not sufficiently independent to provide a valid “separate path” check. Test first is the idea that your write the test before you write the code that is being tested. This seems like a bizarre idea to many people at first, but actually makes perfect sense. If you write the test first and run it, you get to see it fail, so you are testing the test. If you write the test first then you are expressing what you want of your software from the outside in. It leads you to design for behaviour and so you have less of a tendency to get lost in irrelevant technicalities. This is a much more effective design approach than testing after you have written the code, and as a by product it leads inevitably to software that is easy to test – you have to be pretty dumb to write a test before you have written the code for an idea that can’t be tested! Finally there is a virtuous circle here. Software is easy to test when it is modular. It is easy to test when dependencies are externalised and it is easy to test when there is a clear separation of concerns. Now the software industry is famous for change, but if there is any idea that has remained constant for, literally, decades it is that quality software is modular, has well defined dependencies and clear separation of concerns – sound familiar? This has been how computer science has defined quality since before I started, and that was a very long time ago! Using TDD as a practice makes you produce higher quality software, not because it is well tested (though that is a nice by-product) but because it improves the quality of your designs. Want more detail: http://c2.com/cgi/wiki?TestDrivenDevelopment http://www.agiledata.org/essays/tdd.html http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd http://unitmm.sourceforge.net/fibonacci_example.shtml http://clean-cpp.org/test-driven-development/ http://agile2007.agilealliance.org/downloads/presentations/TDD-Cpp-Agile2007-HandsOnTddInCpp.ppt_801.pdf http://www.growing-object-oriented-software.com/
August 13, 2014
by Dave Farley
· 15,444 Views · 1 Like
article thumbnail
10 Tips for Creating an Agile Product Strategy with the Vision Board
1 Start with What You Know Now Traditionally, a product strategy is the result of months of market research and business analysis work. It is intended to be factual, reliable, and ready to be implemented. But in an agile, dynamic environment a product strategy is best created differently: Start with your idea, state the vision behind it, and capture your initial strategy. Then identify the biggest risk or the crucial leap-of-faith assumption, address it, and change and improve your strategy. Repeat this process until you are confident that your product strategy is valid. This iterative approach, piloted by Lean Startup, helps you acquire the new knowledge fast and in a goal-oriented, focused manner addressing the key risks or assumptions. It avoids the danger of carrying out too much and too little research, reduces time-to-market, and increases your chances of creating a successful product. 2 Focus on what Matters Most The term product strategy means different things to different people, and strategies come in different shapes and sizes. While that’s perfectly fine, an initial product strategy that forms the basis for subsequent correction and refinement cycles should focus on what matters most: the market, the value proposition, the product’s unique selling points, and the business goals. This is where my Vision Board comes in. I have designed it as the simplest thing that could possibly work to capture the vision and the product strategy. You can download it from romanpichler.com/tools/vision-board for free. For an introduction to the Vision Board, please see my post “The Product Vision Board”. 3 Create the Product Strategy Collaboratively A great way to create your product strategy is to employ a collaborative workshop. Invite the key people required to develop, market, sell and service your product and the senior management sponsor. Such a workshop generates early buy-in, creates shared ownership, and leverages the collective knowledge and creativity of the group. Selling an existing vision and product strategy can be challenging. Co-creation is often the better option. Your initial Vision Board has to be good enough to create a shared understanding of your vision and initial strategy and to identify the biggest risk so you can start re-working your board. But don’t spend too much time on it and don’t try to make it perfect. Your board will change as you correct, improve and refine it. 4 Let your Vision Guide you The product vision is the very reason for creating your product: It describes your overarching goal. The vision also forms the basis of your product strategy as the path to reach your overall goal. As the vision is so important, you should capture it before you describe your strategy. Here are four tips to help you capture your vision: Make sure that your vision does not restate your product idea but goes beyond it. For instance, the idea for this post is to write about creating an agile product strategy, but my vision is to help you develop awesome and successful products. Choose a broad vision, a vision that engages people and that enables you to pivot – to change the strategy while staying true to your vision. Make your vision statement concise; capture it in one or two sentences; and ensure that it is clear and easy to understand. Try to come up with a motivating and inspiring vision that helps unite everyone working on the product. Choosing an altruistic vision, a vision that focuses on the benefits created for others, can help you with this. 5 Put the Users First Once you have captured your vision, work on your strategy by filling in the lower sections of the Vision Board from left to right. Start with the “Target Group”, the people who should use and buy your product rather than thinking about the cool, amazing product features or the smart business model that will monetise the product. While both aspects are important, capturing the users and customers and their needs forms the basis for making the right product and business model decisions. While it’s tempting to think of all the people who could possibly benefit from your product, it is more helpful to choose a clear-cut and narrow target group instead. Describe the users and customers as clearly as you can and state the relevant demographic characteristics. If there are several segments that your product could serve then choose the most promising one. Working with a focused target group makes it easier to test your assumptions, to select the right test group and test method, and to analyse the resulting feedback and data. If it turns out that you have picked the wrong group or made the segment is too small then simply pivot to a new or bigger one. A large or heterogeneous target group is usually difficult to test. What’s more, it leads to many diverse needs, which make it difficult to determine a clear and convincing value proposition and therefore to market and sell the product. 6 Clearly State the Main Problem or Benefit Once you have captured your target users and customers, describe their needs. Consider why they would purchase and use your product. What problem will your product solve, what pain or discomfort will it remove, what tangible benefit will it create? If you identify several needs, then determine the main problem or the main benefit, for instance, by putting it at the top of the section. This helps you test your ideas and create a convincing value proposition. I find that if I am not able to clearly describe the main problem or benefit, I don’t really understand why people would want to use and to buy a product. 7 Describe the Essence of your Product Once you have captured the needs, use the “Product” section to describe your actual product idea. State the three to five key features of your product, those features that make the product desirable and that set it apart from its competitors. When capturing the features consider not only product functionality but also nonfunctional qualities such as performance and interoperability, and the visual design. Don’t make the mistake of turning this section into a product backlog. The point is not to describe the product comprehensively or in a great amount of detail but to identify those features that really matter to the target group. 8 State your Business Goals and Key Business Model Elements Use the “Value” section to state your business goals such as creating a new revenue stream, entering a new market, meeting a profitability goal, reducing cost, developing the brand, or selling another product. Make explicit why it is worthwhile for your company to invest in the product. Prioritise the business goals and state them in the order of their importance. This will guide your efforts and help you choose the right business model. Once you have captured the business goals, state the key elements of your business model including the main revenue sources and cost factors. This is particularly important when you work with a new or significantly changed business model. 9 Extend your Board The Vision Board’s simplicity is one of its assets, but it can sometimes become restricting: The Product and the Value sections can get crowded as the board does not separately capture the competitors, the partners, the channels, the revenue sources, the cost factors, and other business model elements. Luckily there is a simple solution: Extend your board and add further sections, for instance, “Competitors”, “Channels”, “Revenue Streams”, and “Cost Factors”, or download an extended version from my website. But before using an extended Vision Board make sure that you understand who your customers and users are and why they would buy and use the product. There is no point in worrying about the marketing and the sales channels or the technologies if you are not confident that you have identified a problem that’s worthwhile addressing. Additionally, a more complex board usually contains more risks and assumptions. This makes it harder to identify the biggest risk and leap-of-faith assumption. 10 Put it to the Test Capturing your vision and initial product strategy on the Vision Board is great. But it’s only the beginning of a journey in search of a valid strategy, as your initial board is likely to be wrong. After all, you have based the board on what you know now rather than extensive market research work. You should therefore review your initial Vision Board carefully, identify its critical risks or leap-of-faith assumptions, and select the most crucial risk or assumption. Determine the right test group, for instance, selected target users, and the right test method such as problem interviews. Carry out the test, analyse the feedback or data collected, and change your Vision Board with the newly gained knowledge as the picture below shows. If you find that the key risks and assumptions hard to identify then your board may be too vague. If that’s the case then narrow down the target group, select the main problem or benefit, reduce the key features to no more than five, identify the main business benefit, and remove everything else. Your board may significantly change as you iterate over your strategy, and you may have to pivot, to choose a different strategy to make your vision come true. If your Vision Board does not change at all then you should stop and reflect: Are you addressing the right risks in the right way and are you analysing the feedback and data effectively?
July 17, 2014
by Roman Pichler
· 8,935 Views
article thumbnail
On Collective Ownership and Responsibilities
Recently I’ve been butting heads with some people on the subject of Ownership, Responsibility and Accountability. There seems to be a very unhealthy obsession with these things sometimes, and I think this is indicative of a less-than-ideal culture. I don’t want to say that they’re “anti-agile” because that just sounds a bit weak, and because I also think they’re not just bad for agile, they’re bad for pretty much any system. I’m not sure how familiar most people are with the “RACI matrix” concept, but in my eyes it’s downright evil in the wrong hands, and I’ve been hearing “RACI Matrix” a lot recently (it’s now on my Bullshit Bingo card). I’ll start off by clarifying what I mean. I’ve got nothing against people owning actions or being accountable for certain particular (usually small) things, but I do take offence when pretty much everything has to be given an owner, someone accountable and someone to “take responsibility”. It’s divisive and results in lots of finger pointing, in my experience. I much prefer the concept of shared ownership, and collective accountability. As a software delivery team, we should all feel responsible for the quality of the product, as well as the performance and the feature richness. These things shouldn’t be assigned for ownership to individuals, as it’ll create an attitude of “well it’s not my problem” among the other team members. Here’s an example: I’ve worked in a team where one person was made the “owner” of the build system. They busied themselves making sure all the builds passed and that the system was regularly ticking over. Of course, the builds often failed and nobody cared except this one person, who then had to try to get people to fix their broken builds. It almost seemed as if people didn’t care about the fact that their software wasn’t capable of being compiled, or that the tests were failing, and in truth they didn’t. They cared about writing code and checking it in, because they didn’t “own” the build system. One message that I always try to drive home with software delivery teams is that our objective is to make software that works for our users, not just write code. I know how easy it is for developers to just focus on checking in code, or perhaps just make sure it passes the tests in the CI system, but beyond that, their focus drops off. I know because I was once one of those developers :-) These days I try to encourage everyone to care about things such as: How your code builds How the tests execute How good the tests are How good the code is How easy it is to deploy How easy it is to maintain How easy it is to monitor Because it takes all of these things to produce good software that users can enjoy, which means we get paid. Here’s another example of how “ownership” has hurt a product: A large system I once worked on was deployed into production using a complicated system of bash and perl scripts, which were cobbled together by a sysadmin who did the deployments. He became the de facto “owner” of the deployment system. There were untold issues with the running of the application because of permissions, paths etc and so forth. The deployment process was creaky and relatively untested. Since the “ownership” of this system was assigned to the sysadmin, rather than devolved or collectively shared throughout the delivery team, the “deployability” was seen as a second class citizen within the delivery team, because everybody felt like it was “owned” by one person who just happened to be on the periphery of the team at best. So here’s what I think: The ability to monitor, maintain, deploy, test, build and create software should all be treated as first class citizens and should be the collective responsibility of everyone in the team. They should all own it, and they should all be accountable. I would extend this out further, to include supporting systems such as environments, build systems, testing frameworks and so-on. Sure, each team might have an SME or two who focuses more on one of these things than any other, but that doesn’t make that one person accountable, responsible or the owner any more than any particular developer is the “owner” of any particular class, method or function. If I write some code that depends on a method that someone else has written, and that method is failing, I don’t just down tools, shrug my shoulders and say “well I’m not accountable for that”. That would be hugely unhelpful and I’d make no friends either. In the same way, we shouldn’t treat our supporting functions and systems as someone else’s responsibility. If we need it in order to make our software work for the end user, then it’s our collective responsibility, no matter what “it” is.
July 4, 2014
by James Betteley
· 9,466 Views
article thumbnail
Agile Assessments
This article was originally written by Sandi Keller for LeadingAgile. Assessments come in all forms and there are many reasons why we do them. In the end, we want to know something about the ability of someone or something. When working with a team or organization, an assessment can be introduced as a tool to assist in guiding an agile transformation and team improvement. For me as a coach, it’s an invaluable mechanism to communicate the transformation strategy and to measure progress. I love the simple approach taken in Elizabeth Hendrickson’s “Back-of-the-Napkin Agile Assessment Checklist” but sometimes we need something more extensive in an enterprise transformation setting, at least until our organization or team has reached a more mature state of agility. Over a series of posts, I’ll cover the why, what, when, and how of assessments and wrap it up with a post or two about how the data can be used once you’ve collected it. In this post, I’m going to talk about the Why and What of assessments. You will see at times that I refer to ‘assessment’ and at other times ‘self-assessment’. While the two are not completely interchangeable, I usually make the slight distinction that an assessment is scored by someone evaluating another group. Even for the self-assessment though, ideally there is an experienced guide facilitating the process until a team is more familiar with agile practices and capabilities. So why do an assessment anyway? Let’s consider some of the reasons you might be doing an assessment with a team or an organization: Baseline the current level agile adoption. Eventually you may think about measuring progress but take the time to baseline your abilities right from the start. See how you’re tracking against your adoption or transformation goals. Help sustain and grow your support. Determine if you’re ready to move to the next level of practice or adoption. Be honest, critical and brave! Recognize what has been mastered and what you are able to do with the new skill or capability. Change is tough so remember to celebrate your wins. Identify the next things you’re going to work on. Help the team narrow or target their focus. Set the context for organizational change. Use the assessment instrument as a change management tool. Make or support the case for needed coaching or training. Outside help can propel your progress. Sometimes an assessment or self-assessment may be for other reasons, such as creating a transformation roadmap or showing progress in order to secure continued funding. Even in these cases, I prefer to involve the team as much as possible so they can learn from the exercise and use the information derived from the assessment to target and make improvements. What sorts of things do we look at in an assessment? A team can be measured by improvement of a few practices or against more extensive measures that are part of a competency framework. A competency framework conceivably will focus on things we do, like Stand-ups, Iteration Planning or Retrospectives. It could also focus on capabilities such as Decomposing Features or Define Clear Acceptance Criteria. Or even against concepts like Whole Team or Open Workspace. Using a known competency framework can be useful to bring a level of consistent understanding across teams in the organization. It also facilitates alignment of good metrics as you plan and measure the finer nuance of implementing a particular practice or capability. The following section is a sample of assessment practices and capabilities along with a description for each. Roll Up Competency Practice or Capability Description Define the Product Identify Epics and Features Provide a clear definition of the product goals on the roadmap as feature and epic level deliverables valuable to the business. Produce visual specification around the Epic and Feature: personas, a feature flow chart, use case diagram, etc. Define Clear Acceptance Criteria Define what it takes for a product feature to be ready for use and the definition of done is clearly internalized by the team. Enterprise Alignment Demand Management Team is working from a single prioritized backlog, WIP is limited. Architectural Alignment Architecture aligned and actively involved in release planning. Architecture is actively working with teams to groom solutions Engineering Collective Code Ownership Developer can make code changes anywhere they need; developer can change code, fix bugs, refactor as necessary; few silos of knowledge. Continuous Integration Automated builds occur at every check in, tests pass locally before check in, immediate feedback when new code breaks the build. Plan & Coordinate Eliminate & Manage Risk Coordinate work across teams to limit impact of both internal and external risks to the team. Plan & Groom the Backlog Have enough work groomed ahead of the team so the team can do the work. Organization Enablement Empowered Teams People take ownership for their commitments and outcomes, within a defined set of organizational constraints. Develop Practice Competencies Do people have time to develop their craft? And do they put effort into it? Help the teams make appropriate decisions when applying the practices in their daily work. Communication Whole Team Team sits together, co-location of business/product owner, team is asset/product based, team has identity not based on project, product or department. Daily Stand-Up Occurs daily at same time, lasts 15 minutes or less, roadblocks surface and are visible, team selects stand-up time. The Roll Up Competency, or category, shown in the first column will bring perspective to your competency framework when you describe it to others and when you process the results. I’ll show a few analysis/reporting samples in my follow on post ‘Using the Data’. In my next post, I’ll talk about Rating Scales and Frequency, followed by Assessment Delivery Methods and finally, Using the Data you’ve collected, including use of the roll up categories. This article was originally written by Sandi Keller for LeadingAgile.
June 20, 2014
by Mike Cottmeyer
· 3,528 Views · 1 Like
article thumbnail
MapDB: The Agile Java Data Engine
MapDB is a pure Java database, specifically designed for the Java developer. The fundamental concept for MapDB is very clever yet natural to use: provide a reliable, full-featured and “tune-able” database engine using the Java Collections API. MapDB 1.0 has just been released, this is the culmination of years of research and development to get the project to this point. Jan Kotek, the primary developer for MapDB, also worked on predecessor projects (JDBM), starting MapDB as an entire from-scratch rewrite. Jan’s expertise and dedication to low-level debugging has yielded excellent results, producting an easy-to-use database for Java with comparable performance to many C-based engines. What sets MapDB apart is the “map” concept. The idea is to leverage the totally natural Java Collections API – so familiar to Java developers that most of them literally use it daily in their work. For most database interactions with a Java application, some sort of translator is required. There are many Object-Relational Mapping (ORM) tools to name just one category of such components. The goal has always been in the direction of making it natural to code in objects in the Java language, and translate them to a specific database syntax (such as SQL). However, such efforts have always come up short, adding complexity for both the application developer and the data architect. When using MapDB there is no object “translation layer” – developers just access data in familiar structures like Maps, Sets, Queues, etc. There is no change in syntax from typical Java coding, other than a brief initialization syntax and transaction management. A developer can literally transform memory-limited maps into a high-speed persistent store in seconds (typically changing just one line of code). A MapDB Example Here is a simple MapDB example, showing how easy and intuitive it is to use in a Java application: // Initialize a MapDB database DB db = DBMaker.newFileDB(new File("testdb")) .closeOnJvmShutdown() .make(); // Create a Map: Map myMap = db.getTreeMap(“testmap”); // Work with the Map using the normal Map API. myMap.put(“key1”, “value1”); myMap.put(“key2”, “value2”); String value = myMap.get(“key1”); ... That’s all you need to do, now you have a file-backed Map of virtually any size. Note the “builder-style” initialization syntax, enabling MapDB as the agile database choice for Java. There are many builder options that let you tune your database for the specific requirements at hand. Just a small subset of options include: In-memory implementation Enable transactions Configurable caching This means that you can configure your database just for what you need, effectively making MapDB serve the job of many other databases. MapDB comes with a set of powerful configuration options, and you can even extend the product to make your own data implementations if necessary. Another very powerful feature is that MapDB utilizes some of the advanced Java Collections variants, such as ConcurrentNavigableMap. With this type of Map you can go beyond simple key-value semantics, as it is also a sorted Map allowing you to access data in order, and find values near a key. Not many people are aware of this extension to the Collections API, but it is extremely powerful and allows you to do a lot with your MapDB database (I will cover more of these capabilities in a future article). The Agile Aspect of MapDB When I first met Jan and started talking with him about MapDB he said something that made a very important impression: If you know what data structure you want, MapDB allows you to tailor the structure and database characteristics to your exact application needs. In other words, the schema and ways you can structure your data is very flexible. The configuration of the physical data store is just as flexible, making a perfect combination for meeting almost any database need. They key to this capability is inherent in MapDB’s architecture, and how it translates to the MapDB API itself. Here is a simple diagram of the MapDB architecture: As you can see from the diagram, there are 3 tiers in MapDB: Collections API: This is the familiar Java Collections API that every Java developer uses for maintaining application state. It has a simple builder-style extension to allow you to control the exact characteristics of a given database (including its internal format or record structure). Engine: The Engine is the real key to MapDB, this is where the records for a database – including their internal structure, concurrency control, transactional semantics – are controlled. MapDB ships with several engines already, and it is straightforward to add your own Engine if needed for specialized data handling. Volume: This is the physical storage layer (e.g., on-disk or in-memory). MapDB has a few standard Volume implementations, and they should suffice for most projects. The main point is that the development API is completely distinct from the Engine implementation (the heart of MapDB), and both are separate from the actual physical storage layer. This offers a very agile approach, allowing developers to exactly control what type of internal structure is needed for a given database, and what the actual data structure looks like from the top-level Collections API. To make things even more extensible and agile, MapDB uses a concept of Engine Wrappers. An Engine Wrapper allows adding additional features and options on top of a specific engine layer. For example, if the standard Map engine is utilized for creating a B-Tree backed Map, it is feasible to enable (or disable) caching support. This caching feature is done through an Engine Wrapper, and that is what shows up in the builder-style API used to configure a given database. While a whole article could be written just about this, the point here is that this adds to MapDB’s inherent agile nature. By way of example, here is how you configure a pure in-memory database, without transactional capabilities: // Initialize an in-memory MapDB database // without transactions DB db = DBMaker.newMemoryDB() .transactionDisable() .closeOnJvmShutdown() .make(); // Create a Map: Map myMap = db.getTreeMap(“testmap”); // Work with the Map using the normal Map API. myMap.put(“key1”, “value1”); myMap.put(“key2”, “value2”); String value = myMap.get(“key1”); ... That’s it! All that was needed was to change the DBMaker call to add the new options, everything else works exactly the same as in the example shown earlier. Agile Data Model In addition to customizing the features and performance characteristics of a given database instance, MapDB allows you to create an agile data model, with a schema exactly matching your application requirements. This is probably similar to how you write your code when creating standard Java in-memory structures. For example, let’s say you need to lookup a Person object by username, or by personID. Simply create a Person object and two Maps to meet your needs: public class Person { private Integer personID; private String username; ... // Setters and getters go here ... } // Create a Map of Person by username. Map personByUsernameMap = ... // Create a Map of Person by personID. Map personByPersonIDMap = ... This is a very trivial example, but now you can easily write to both maps for each new Person instance, and subsequently retrieve a Person by either key. Another interesting concept with MapDB data structures are some key extensions to the normal Java Collections API. A common requirement in applications is to have a Map with a key/value, and in addition to finding the value for a key to be able to perform the inverse: lookup the key for a given value. We can easily do this using the MapDB extension for bi-directional maps: // Create a primary map HTreeMap map = DBMaker.newTempHashMap(); // Create the inverse mapping for primary map NavigableSet> inverseMapping = new TreeSet>(); // Bind the inverse mapping to primary map, so it is auto-updated each time the primary map gets a new key/value Bind.mapInverse(map, inverseMapping); map.put(10L,"value2"); map.put(1111L,"value"); map.put(1112L,"value"); map.put(11L,"val"); // Now find a key by a given value. Long keyValue = Fun.filter(inverseMapping.get(“value2”); MapDB supports many constructs for the interaction of Maps or other collections, allowing you to create a schema of related structures that can automatically be kept in sync. This avoids a lot of scanning of structures, makes coding fast and convenient, and can keep things very fast. Wrapping it up I have shown a very brief introduction on MapDB and how the product works. As you can see its strengths are its use of the natural Java Collections API, the agile nature of the engine itself, and the support for virtually any type of data model or schema that your application needs. MapDB is freely available for any use under the Apache 2.0 license. To learn more, check out: www.mapdb.org.
June 5, 2014
by Cory Isaacson
· 28,496 Views · 3 Likes
article thumbnail
Exploring Message Brokers: RabbitMQ, Kafka, ActiveMQ, and Kestrel
Explore different message brokers, and discover how these important web technologies impact a customer's backlog of messages, and cluster/data performance.
June 3, 2014
by Yves Trudeau
· 460,451 Views · 86 Likes
article thumbnail
Creating Complex Test Configurations with Red Deer
This is the second in a series of posts on the new “Red Deer” (https://github.com/jboss-reddeer/reddeer) open source testing framework for Eclipse. In the previous post in this series, we introduced Red Deer, learned how to install it into Eclipse, examined some of its cool features, and built and ran a sample test program from scratch. One of the challenges in creating effective automated tests is in making the tests self-sufficient enough to be able to set up their required operation environment, and robust enough to be able to determine whether that operating environment has been set up correctly. In the first post in this series, we took a quick look at Red Deer’s implementation of Requirements classes. In this post, we’ll take a more detailed look at Requirements, including how Red Deer supports your creating custom Requirements. The Case for Automated Test Requirements Let’s start by setting the context for why test programs need requirements. It’s often the case that a set of automated tests runs unattended and all the tests fail, not due to a bug in the software under test, but due to a broken or incomplete test environment. When we refer to a Red Deer “requirement,” we’re talking about actions that must be performed, or objects that must be created, before a test can be run. Examples of these requirements are having a user account defined or a connection to a database created and verified. What makes using Red Deer requirements different from your creating a less formal set of requirements with the @BeforeClass annotation provided by JUnit, is that if requirements are not met, then the test in question is not run. This can save you a lot of test execution time and test failure debugging time. Red Deer requirements are implemented in the RedDeerSuite. A test that makes use of requirements is must be run with a RedDeerSuite suite and annotated with @RunWith(RedDeerSuite.class) OOTB Red Deer Requirements As we saw in the first post in this series, Red Deer currently provides OOTB (out of the box) predefined requirements that enable you to clean out your current workspace and open a perspective. Using these requirements is simple. All you have to do is to add these import statements to your Red Deer test programs: import org.jboss.reddeer.eclipse.ui.perspectives.JavaBrowsingPerspective; import org.jboss.reddeer.requirements.cleanworkspace.CleanWorkspaceRequirement.CleanWorkspace; import org.jboss.reddeer.requirements.openperspective.OpenPerspectiveRequirement.OpenPerspective; And, we also have to add a reference to org.jboss.reddeer.requirements to the required bundle list in our example’s MANIFEST.MF file. And finally, add these annotations to the test program: @CleanWorkspace @OpenPerspective(JavaBrowsingPerspective.class) What if you want to define your own custom requirements? Let’s move on and examone how Red Deer supports that too. Different Ways to Implement New Red Deer Requirements Red Deer supports (4) ways to implement new requirements. We’ll look at them in order of their relative complexity: Simple Requirements Requirements with Parameters Requirements with Property Based Configuration Requirements with a Custom Schema In order to examine how Red Deer supports implementing new requirements, we’ll actually create some new requirements in Red Deer source code. In order to do this, we’ll have to download a copy of Red Deer’s source code. To perform this download, navigate to your desired directory and enter this command: git clone https://github.com/jboss-reddeer/reddeer.git And then, import Red Deer into eclipse as a set of existing Maven projects: If you navigate to the top level of the directory into which you downloaded the Red Deer source code, you’ll see this: What you want to do is to select all of the Red Deer projects. After you press the “Next>” key, Eclipse will import all the Red Deer packages as maven projects. (This may take a few minutes.) OK, now we can move on to creating some new requirements. We’ll start with the simplest of the (4) types, a simple requirement. Implementing a Simple Requirement A simple requirement consists of (2) parts: a “fulfilling” class that provides the code executed when the requirement is invoked, and an annotation that references that fulfilling class. As an illustration, let’s look at the skeleton “AdminUserRequirement” provided with your Red Deer download. This requirement is intended to serve as an example for implementing a full requirement to ensure that an admin-level user is defined before an attempt is made to run a test. The source file you want to look for is: /plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/annotation/simple/AdminUserRequirement.java While it’s a small file, it’s a full example. It’s worthwhile examining it line-by-line: package org.jboss.reddeer.junit.annotation.simple; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.jboss.reddeer.junit.requirement.Requirement; import org.jboss.reddeer.junit.annotation.simple.AdminUserRequirement.AdminUser; /** * Admin user test requirement * @author lucia jelinkova * */ public class AdminUserRequirement implements Requirement { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AdminUser { } public boolean canFulfill() { // return true if you can connect to the database return true; } public void fulfill() { // create an admin user in the database if it does not exist yet } public void setDeclaration(AdminUser declaration) { // no need to access the annotation } } The important elements in this file are: Line 17 - @Retention - Specifies how the marked annotation is stored—Whether in code only, compiled into the class, or available at runtime through reflection. Line 18 - @Target - Marks another annotation to restrict the types of Java elements to which the the annotation can be applied Line 20 - AdminUser interface - This defines the object type used by the defined requirement. Line 23 - canFulfill method - In a fully written requirement this method will include the code to determine if the requirement can be met (or “fulfilled”). This method is set to always return a value of true. Line 32 - fulfill method - And here is the code that will be executed if the canFulfill method returns a value of true. For an example of the corresponding annotation in action, let’s look at the test program that is included with the fulfilling class. The test program is here: /plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/annotation/simple/AdminUserTest.java This test program is also very short as it is a skeleton. The outline is there, but the specific logic that to implement the AdminUser requirement is left as an “exercise for the reader.” package org.jboss.reddeer.junit.annotation.simple; import org.jboss.reddeer.junit.runner.RedDeerSuite; import org.jboss.reddeer.junit.annotation.simple.AdminUserRequirement.AdminUser; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(RedDeerSuite.class) @AdminUser /** * Test with AdminUser requirement * @author lucia jelinova * */ public class AdminUserTest { @Test public void test(){ // put test logic here } } The @AdminUser annotation on line NN tells the whole story. When this annotation is executed, the fulfilling class is invoked and if the “canFulfill()” method returns true, the test is executed. If the method returns false, then the test is not executed. Let’s run this test and see what happens. First, locate the AdminUserTest.java file in the eclipse Navigator view: Then, right-click and specify that it be executed as a JUnit test: And, not surprisingly, here’s the successful output from the test: Before we move on, let’s modify the canFulFill() method to return a false value, and rerun the test. The results look like this: 22:11:04.923 INFO [main][RequirementsRunnerBuilder] Found test class org.jboss.reddeer.junit.annotation.simple.AdminUserTest 22:11:04.924 INFO [main][RequirementsBuilder] Creating requirements for test class org.jboss.reddeer.junit.annotation.simple.AdminUserTest 22:11:04.925 DEBUG [main][RequirementsBuilder] Found requirement class org.jboss.reddeer.junit.annotation.simple.AdminUserRequirement for annotation interface org.jboss.reddeer.junit.annotation.simple.AdminUserRequirement$AdminUser 22:11:04.927 INFO [main][Requirements] Requirement class org.jboss.reddeer.junit.annotation.simple.AdminUserRequirement can be fulfilled: false 22:11:04.927 INFO [main][RequirementsRunnerBuilder] All requirements cannot be fulfilled, the test will NOT run So, this time, the requirement was not met and the test was not run. Note that the requirement did the work for us. We did not have to write a lot of new code to determine if the requirement had been met to decide whether or not to run the test. That’s all well and good for a simple requirement. But what about if we want to make the requirement a bit more flexible by enabling us to pass it a parameter? Let’s look at that next. Implementing a Requirement with Parameters In order to implement a requirement that accepts one or more parameters, we have to make two additions to the simple requirement that we just examined. First, we have to use a different requirement definition. The code that we want to look at this time is here: /plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/annotation/advanced/UserRequirement.java The file looks like this: package org.jboss.reddeer.junit.annotation.advanced; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.jboss.reddeer.junit.requirement.Requirement; import org.jboss.reddeer.junit.annotation.advanced.UserRequirement.User; /** * Parameterized requirement with parameter name * @author vpakan * */ public class UserRequirement implements Requirement { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface User { String name(); } private User user; public boolean canFulfill() { // return true if you can connect to the database return true; } public void fulfill() { System.out.println("Fulfilling reuirement User with name: " + user.name()); // create an admin user in the database if it does not exist yet } public void setDeclaration(User user) { this.user = user; } } The important difference between this class and the original AdminUserRequirement that we examined a moment ago is: Line 20 - The interface “User” now defines a String parameter “name” and on line NNN here the User object is defined. Second, we have to change the declaration of the requirement in the test program. The test program that we’ll look at this time is here: /plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/annotation/advanced/UserTest.java Finally, our test program for this requirement looks like this: package org.jboss.reddeer.junit.annotation.advanced; import org.jboss.reddeer.junit.runner.RedDeerSuite; import org.jboss.reddeer.junit.annotation.advanced.UserRequirement.User; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(RedDeerSuite.class) @User(name="admin") /** * Test with parameterized requirement User * @author lucia jelinkova * */ public class UserTest { @Test public void test(){ // put test logic here } } The interesting line in this test is: Line 8 - @User(name="admin") - Where we set the value of the “name” parameter. When we run the UserTest as a JUnit test, we see this output: 20:46:03.554 INFO [main][RequirementsRunnerBuilder] Found test class org.jboss.reddeer.junit.annotation.advanced.UserTest 20:46:03.555 INFO [main][RequirementsBuilder] Creating requirements for test class org.jboss.reddeer.junit.annotation.advanced.UserTest 20:46:03.556 DEBUG [main][RequirementsBuilder] Found requirement class org.jboss.reddeer.junit.annotation.advanced.UserRequirement for annotation interface org.jboss.reddeer.junit.annotation.advanced.UserRequirement$User 20:46:03.558 INFO [main][Requirements] Requirement class org.jboss.reddeer.junit.annotation.advanced.UserRequirement can be fulfilled: true 20:46:03.558 INFO [main][RequirementsRunnerBuilder] All requirements can be fulfilled, the test will run 20:46:03.575 INFO [main][RedDeerSuite] RedDeer suite created 20:46:03.584 INFO [main][Requirements] Fulfilling requirement of class org.jboss.reddeer.junit.annotation.advanced.UserRequirement Fulfilling requirement User with name: admin 20:46:03.585 DEBUG [main][RequirementsRunner] Injecting fulfilled requirements into test instance 20:46:03.587 INFO [main][RequirementsRunner] Started test: test(org.jboss.reddeer.junit.annotation.advanced.UserTest)20:46:03.588 INFO [main][RequirementsRunner] Finished test: test(org.jboss.reddeer.junit.annotation.advanced.UserTest) While it makes requirements more flexible when you are able to add parameters to their definition, it is still limited as a solution as you have to handle the individual parameters one by one. Fortunately, Red Deer also supports defining test configurations in your own custom XML schemas. Defining Complex Configurations - Two Approaches Red Deer supports two different approaches to defining complex configurations. You can either: Define the configuration as a set of (key=value) properties. If you choose this approach, you will have to also define setter methods for each property in your requirement’s fulfilling class. Create a custom XML schema. If you choose this approach, you will have to create a configuration object in your test code and then inject that object into your requirement. Regardless of which approach you choose, you store the configuration data in either a single XML file, or directory of XML files and then pass those files to your test program by defining this JVM argument when you run your test programs: -Dreddeer.config=/home/path/to/file/or/directory Let’s examine each of these approaches in detail. We’ll start with the properties based approach. Requirements with a Property Based Configuration The first thing we have to do to use a property based configuration is to define the properties. We’ll do this in an an XML file that complies with the Red Deer requirements XSD schema file. You can view the XSD here: http://cloud.github.com/downloads/jboss-reddeer/reddeer/RedDeerSchema.xsd The code for this example is here: /jboss/local/reddeer_fork/reddeer/plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/configuration/simple And - here’s our properties file. Note that the requirement defined in this file contains two properties: name and ip (IP address). Let’s now expand on the “UserRequirement” example that we defined a few minutes ago. What we want to be able to do is to remove hardcoded requirements data from the source code and instead define that data in set of properties. To use this requirements.xml file, we have to make some changes to the UserRequirement.java class. package org.jboss.reddeer.junit.annotation.simple; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.jboss.reddeer.junit.requirement.Requirement; import org.jboss.reddeer.junit.annotation.simple.UserRequirement.User; import org.jboss.reddeer.junit.requirement.PropertyConfiguration; /** * Admin user test requirement * @author lucia jelinkova */ public class UserRequirement implements Requirement , PropertyConfiguration { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface User { } private String name; private String ip; public boolean canFulfill() { // return true if you can connect to the database return true; } public void fulfill() { System.out.println("Fulfilling User requirement with\nName: " + name + "\nIP: " + ip); // create an admin user in the database if it does not exist yet } @Override public void setDeclaration(User user) { // annotation has no parameters no need to store reference to it } public void setName(String name) { this.name = name; } public void setIp(String ip) { this.ip = ip; } public String getName() { return name; } public String getIp() { return ip; } } The important changes are the addition of this import statement at line 8: import org.jboss.reddeer.junit.requirement.PropertyConfiguration And the addition of the implement clauses for the Requirement (with a type of User), and the PropertyConfiguration (so that the properties can be read) at line 15: public class UserRequirement implements Requirement , PropertyConfiguration And addition of the setter methods for the name and ip properties. Finally, here is the updated test program: package org.jboss.reddeer.junit.annotation.simple; import org.jboss.reddeer.junit.runner.RedDeerSuite; import org.jboss.reddeer.junit.annotation.simple.UserRequirement.User; import org.junit.Test; import org.junit.runner.RunWith; import org.jboss.reddeer.junit.requirement.inject.InjectRequirement; @RunWith(RedDeerSuite.class) @User /** * Test with AdminUser requirement * @author lucia jelinova * */ public class UserTest { @InjectRequirement private UserRequirement userRequirement; @Test public void test(){ System.out.println("The test is running"); System.out.println(userRequirement.getName()); // put test logic here } } What’s new in the test program is the addition of the import statement for the requirement injection: import org.jboss.reddeer.junit.requirement.inject.InjectRequirement; And the code to define and inject the UserRequirement: @InjectRequirement private UserRequirement userRequirement; When we run the test, we have to reference the configuration file via a Java VM argument . This means that we must define a new “run configuration” that is based on the JUnit run configuration provided in Eclipse and provide the VM argument that references the configuration file: In our example, the -Dreddeer.config VM argument is defined as: -Dreddeer.config=/jboss/local/reddeer_fork/reddeer/plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/annotation/simple/reddeer.xml To execute the test, right-click on the UserTest class, and select the run configuration we just created: And, the test generates this test output in the console: 22:40:50.988 INFO [main][RedDeerSuite] Creating RedDeer suite... 22:40:50.990 INFO [main][SuiteConfiguration] Looking up configuration files defined via property reddeer.config=/jboss/local/reddeer_fork/reddeer/plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/annotation/simple/reddeer.xml 22:40:50.991 INFO [main][SuiteConfiguration] Found configuration file /jboss/local/reddeer_fork/reddeer/plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/annotation/simple/reddeer.xml 22:40:50.992 INFO [main][RedDeerSuite] Adding suite with name reddeer.xml to RedDeer suite 22:40:51.012 INFO [main][RequirementsRunnerBuilder] Found test class org.jboss.reddeer.junit.annotation.simple.UserTest 22:40:51.025 INFO [main][RequirementsBuilder] Creating requirements for test class org.jboss.reddeer.junit.annotation.simple.UserTest 22:40:51.027 DEBUG [main][RequirementsBuilder] Found requirement class org.jboss.reddeer.junit.annotation.simple.UserRequirement for annotation interface org.jboss.reddeer.junit.annotation.simple.UserRequirement$User 22:40:51.027 DEBUG [main][PropertyBasedConfigurator] Setting property based configuration to requirement class org.jboss.reddeer.junit.annotation.simple.UserRequirement 22:40:51.031 DEBUG [main][XMLReader] Reading configuration for class org.jboss.reddeer.junit.internal.configuration.entity.PropertyBasedConfiguration 22:40:51.827 DEBUG [main][PropertyBasedConfigurator] Configuration successfully set 22:40:51.828 INFO [main][Requirements] Requirement class org.jboss.reddeer.junit.annotation.simple.UserRequirement can be fulfilled: true 22:40:51.828 INFO [main][RequirementsRunnerBuilder] All requirements can be fulfilled, the test will run 22:40:51.865 INFO [main][RedDeerSuite] RedDeer suite created 22:40:51.874 INFO [main][Requirements] Fulfilling requirement of class org.jboss.reddeer.junit.annotation.simple.UserRequirement Fulfilling User requirement with Name: USERS_ADMINISTRATION IP: 127.0.0.1 22:40:51.875 DEBUG [main][RequirementsRunner] Injecting fulfilled requirements into test instance 22:40:51.876 INFO [main][RequirementsRunner] Started test: test reddeer.xml(org.jboss.reddeer.junit.annotation.simple.UserTest) 22:40:51.876 INFO [main][RequirementsRunner] Started test: test reddeer.xml(org.jboss.reddeer.junit.annotation.simple.UserTest) The test is running USERS_ADMINISTRATION 22:40:51.878 INFO [main][RequirementsRunner] Finished test: test reddeer.xml(org.jboss.reddeer.junit.annotation.simple.UserTest) 22:40:51.878 INFO [main][RequirementsRunner] Finished test: test reddeer.xml(org.jboss.reddeer.junit.annotation.simple.UserTest) Requirements with a Custom Schema The fourth and final approach to defining new requirements is to create a custom XML schema. This is the most complex approach, but it also provides you with the most flexibility as you can more easily share requirements in multiple configuration files. Also, this approach can protect you against forgetting to define properties in the configuration files by designating specific properties as required XML elements. To use this approach, you create a custom XML schema, then you create a configuration object in the test programs, and inject that object into your requirement. The configuration details are defined in an XML file and accessed through JAXB annotations. Let’s take a look at an example. The code for this example is available in Red Deer here: /plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/configuration/advanced In order to use a custom XML schema, you need a custom schema. In this example, the schema is defined in a local file: /plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/configuration/advanced/RedDeerRequirements.xsd This example schema is fairly simple, but it provides the flexibility needed for the example to define a test configuration of key=value pairs in the context of testruns and requirements. Also, the schema enforces the “required” setting for the requirement name. The configuration for requirement is defined in an XML requirement configuration file, the format of which complies with the custom schema: USERS_ADMINISTRATION 127.0.0.1 1111 In order to make use of this configuration, the Requirement class must instantiate a “UserConfiguration” object for the requirement. The UserRequirement class implements the org.jboss.reddeer.junit.requirement.CustomConfiguration interface with and specifies a type of UserConfiguration to enable the use of custom configurations: package org.jboss.reddeer.junit.configuration.advanced; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.jboss.reddeer.junit.requirement.CustomConfiguration; import org.jboss.reddeer.junit.requirement.Requirement; import org.jboss.reddeer.junit.configuration.advanced.UserRequirement.User; /** * User requirement using configuration from custom xml file * @author lucia jelinkova * */ public class UserRequirement implements Requirement, CustomConfiguration { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface User { String name(); } private User user; private UserConfiguration userConfiguration; public boolean canFulfill() { // return true if you can connect to the database return true; } public void fulfill() { System.out.println("fulfiling requirement User with\nName: " + user.name() + "\nDB name: " + userConfiguration.getDbName() + "\nPort: " + userConfiguration.getPort() + "\nIP: " + userConfiguration.getIp()); // create an admin user in the database if it does not exist yet } public void setDeclaration(User user) { this.user = user; } public Class getConfigurationClass() { return UserConfiguration.class; } public void setConfiguration(UserConfiguration config) { this.userConfiguration = config; } } The UserConfiguration object (see line 25) is used by the org.jboss.reddeer.junit.requirement.CustomConfiguration class to provide the values for the requirement. The UserConfiguration definition (see below) maps the requirement as defined in the elements defined in the requirement XML file. package org.jboss.reddeer.junit.configuration.advanced; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** * Stores user requirement configuration loaded from custom xml file * @author lucia jelinkova * */ @XmlRootElement(name="user-requirement", namespace="http://www.jboss.org/NS/user-schema") public class UserConfiguration { private String dbName; private String ip; private String port; public String getIp() { return ip; } @XmlElement(namespace="http://www.jboss.org/NS/user-schema") public void setIp(String ip) { this.ip = ip; } public String getPort() { return port; } @XmlElement(namespace="http://www.jboss.org/NS/user-schema") public void setPort(String port) { this.port = port; } public String getDbName() { return dbName; } @XmlElement(name="db-name", namespace="http://www.jboss.org/NS/user-schema") public void setDbName(String dbName) { this.dbName = dbName; } } Note the getter and setter methods in the class definition. These methods make use of JAXB annotations to access the configuration element values. The test program looks largely the same as the test programs that we’ve used in the earlier examples. (It’s a nice characteristic of Red Deer tests in that since the “heavy lifting” is performed by the Red Deer harness, the tests can be kept simple, and therefore kept easy to maintain.) package org.jboss.reddeer.junit.configuration.advanced; import org.jboss.reddeer.junit.runner.RedDeerSuite; import org.jboss.reddeer.junit.configuration.advanced.UserRequirement.User; import org.junit.Test; import org.junit.runner.RunWith; /** * User test using configuration from custom xml file * Set VM parameter -Dreddeer.config to point to directory with requirements.xml file * -Dreddeer.config=${project_loc}/src/org/jboss/reddeer/junit/configuration/advanced * @author lucia jelinkova */ @RunWith(RedDeerSuite.class) @User(name="admin") public class UserTest { @Test public void test(){ // put your test logic here } } When the program is run, the console shows that the requirement was successfully met: 21:26:25.075 INFO [main][RedDeerSuite] Creating RedDeer suite... 21:26:25.077 INFO [main][SuiteConfiguration] Looking up configuration files defined via property reddeer.config=/jboss/local/reddeer_fork/reddeer/plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/configuration/advanced/requirements.xml 21:26:25.077 INFO [main][SuiteConfiguration] Found configuration file /jboss/local/reddeer_fork/reddeer/plugins/org.jboss.reddeer.examples/src/org/jboss/reddeer/junit/configuration/advanced/requirements.xml 21:26:25.078 INFO [main][RedDeerSuite] Adding suite with name requirements.xml to RedDeer suite 21:26:25.084 INFO [main][RequirementsRunnerBuilder] Found test class org.jboss.reddeer.junit.configuration.advanced.UserTest 21:26:25.087 INFO [main][RequirementsBuilder] Creating requirements for test class org.jboss.reddeer.junit.configuration.advanced.UserTest 21:26:25.089 DEBUG [main][RequirementsBuilder] Found requirement class org.jboss.reddeer.junit.configuration.advanced.UserRequirement for annotation interface org.jboss.reddeer.junit.configuration.advanced.UserRequirement$User 21:26:25.089 DEBUG [main][CustomConfigurator] Setting custom configuration to requirement class org.jboss.reddeer.junit.configuration.advanced.UserRequirement 21:26:25.090 DEBUG [main][CustomConfigurator] Configuration object associated with requirement class org.jboss.reddeer.junit.configuration.advanced.UserRequirement is class org.jboss.reddeer.junit.configuration.advanced.UserConfiguration 21:26:25.090 DEBUG [main][XMLReader] Reading configuration for class org.jboss.reddeer.junit.configuration.advanced.UserConfiguration 21:26:25.782 DEBUG [main][CustomConfigurator] Configuration successfully set 21:26:25.832 INFO [main][Requirements] Requirement class org.jboss.reddeer.junit.configuration.advanced.UserRequirement can be fulfilled: true 21:26:25.832 INFO [main][RequirementsRunnerBuilder] All requirements can be fulfilled, the test will run 21:26:25.911 INFO [main][RedDeerSuite] RedDeer suite created 21:26:25.921 INFO [main][Requirements] Fulfilling requirement of class org.jboss.reddeer.junit.configuration.advanced.UserRequirement fulfiling requirement User with Name: admin DB name: USERS_ADMINISTRATION Port: 1111 IP: 127.0.0.1 21:26:25.922 DEBUG [main][RequirementsRunner] Injecting fulfilled requirements into test instance 21:26:25.923 INFO [main][RequirementsRunner] Started test: test requirements.xml(org.jboss.reddeer.junit.configuration.advanced.UserTest) 21:26:25.924 INFO [main][RequirementsRunner] Started test: test requirements.xml(org.jboss.reddeer.junit.configuration.advanced.UserTest) 21:26:25.925 INFO [main][RequirementsRunner] Finished test: test requirements.xml(org.jboss.reddeer.junit.configuration.advanced.UserTest) 21:26:25.925 INFO [main][RequirementsRunner] Finished test: test requirements.xml(org.jboss.reddeer.junit.configuration.advanced.UserTest) Before we move on, let’s try introducing an error in the XML test configuration and then see how Red Deer can trap that error. I don’t know about you, but avoiding typos is sometimes difficult for me. Let’s “inadvertently” remove the (required) name for the requirement. And rerun the test. This time, the console output shows: ERROR [main][XMLReader] cvc-complex-type.4: Attribute 'name' must appear on element 'user:user-requirement'. And the Junit output shows: org.jboss.reddeer.junit.configuration.RedDeerConfigurationException: Xml configuration is not valid. Recap In this post, we examined the (4) ways in which Red Deer supports creating your own custom test configurations. These methods range from simple requirements that optionally include parameters, to more complex requirements that can be defined in external XML files, either as key=value pairs or in a custom schema, that can be be shared between multiple test cases. It’s often the case that automated test runs can fail not because of bugs in software under test, but because the environment required by the test was properly initialized. Red Deer, by providing multiple approaches to create custom requirements helps you to ensure that your test failures can be more easily debugged and configuration errors are detected. What’s Next? In the next post in this series, we’ll take a look at how Red Deer makes creating new tests from scratch easier through its keystroke recorder feature. References https://github.com/jboss-reddeer/reddeer/wiki/Requirements http://www.oracle.com/technetwork/articles/javase/index-140168.html (JAXB)
March 14, 2014
by Len DiMaggio
· 6,852 Views
article thumbnail
A Template for Formulating Great Sprint Goals
I find it helpful to consider three questions when choosing a sprint goal: Why do we carry out the sprint? How do we reach its goal? And how do we know that the goal has been met? My sprint goal template therefore consists of three main parts: the actual goal, the method employed to reach the goal, and the metrics to determine if the goal has been met. It additionally provides a header section that allows you to state to which product and sprint the goal belongs, as the picture below shows. You can download the template as a PDF from romanpichler.com/tools/sprint-goal-template/ or by clicking on the image below. The template above has grown out of my experience of working with Scrum for more than ten years, and it is inspired by the scientific method and Lean Startup. Let’s have a look at the template sections in more detail. The Goal Section The goal section states why it is worthwhile to undertake the sprint. Examples are: Test an assumption about the user interaction and learn what works best for the user, for instance: “Will users be willing to register before using the product features?” Address a technical risk such as: “Does the architecture enable the desired performance?” Release a feature, for instance: “Get the reporting feature for general release.” The sprint goal hence differs from listing the user stories that should be implemented. It communicates the reason for carrying out the work, and it provides a motivation for running the sprint. The sprint goal should be shared: The product owner and the development team should believe that working towards the goal is the right thing to do. To choose the right sprint goal I find it helpful to consider the amount of uncertainty present. In the early sprints, addressing risks and testing assumptions allows me to learn about what the product should look like and do and how it is built. Once the key risks and critical assumptions have been dealt with, I like to focus on completing and optimising features, as the following picture shows: The Method Section This section addresses the question of how the goal is met. The default Scrum answer is simple: Create a (potentially shippable) product increment using the high-priority product backlog items, and demo it to the stakeholders in the sprint review meeting. But writing software and employing a product demo are not always the best methods to achieve the goal! A paper prototype can be good enough to test a visual design idea or an assumption about the user interaction, for instance. What’s more, other methods such as carrying out a usability test or releasing software to run an A/B test may well be more effective than a product demo. You should therefore carefully choose the right method and state it in this section. But don’t stop there. Determine the test group, the people who should provide feedback and data. Who these individuals are depends on the sprint goal: If you are validating an assumption about the visual design, the user interaction or the product functionality, then you probably want to collect feedback and data from the users. But if you are addressing a technical risk, then users may not be able to help you. Consider inviting a senior developer or architect from another team instead. Stating the test group clarifies who “the stakeholders” are, who is required to provide feedback so that the right product is developed. The Metrics Section The metrics section communicates how you determine if the goal has been met. Which metrics you use depends on the method chosen. For a product demo, you may state that at least two thirds of the stakeholders present should respond positively to the new feature, for instance; for a usability test, at least three of the five testers are complete the task successfully in less than a minute; and for the release of a new feature, you might say that at least 80% of the users use the new functionality at least once within five days after launching the feature. Whichever metrics you choose, make sure that they allow you to understand if and to which extent you have met the goal. The Header Section The header section consists of the two subsections “Product” and “Sprint”. They simply allow you to state which product and which sprint the goal belongs to. Customise this section according to your needs. If you work for an agencies or an IT solution provider, you could replace “Product” with “Project”, for instance. User Stories and the Sprint Goal You may be wondering how the template relates to the user stories. Let me first reiterate that your sprint goal should differ from your user stories. The goal explains the why it is a good idea to carry out the sprint an implement the stories. The user stories enable you to reach the goal. It’s a common mistake to confuse the two. To connect the template and the stories you have two options: You can state the relevant user stories in the template’s method section, or you can list them separately on the sprint backlog, as the following picture illustrates. In the picture above, the sprint goal is stated on the left to the sprint backlog, which lists the user stories and the tasks required to meet the goal in form of a task board. Learn more You can learn more about choosing effective sprint gaols and applying the sprint goal template by attending my Certified Scrum Product Owner training course. I have written in more detail about sprint planning in my book “Agile Product Management with Scrum”. Please contact me for onsite and virtual product owner training.
March 12, 2014
by Roman Pichler
· 14,144 Views · 1 Like
  • Previous
  • ...
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×