In Part I of our interview with Jason Garber, one of the co-founders of Philadelphia-based PromptWorks, we talked with him about how consultancies approach the rescue of wayward software projects. As we noted, nobody knows the trouble companies can get into better than the guys usually brought in to pick up the pieces.
In Part II, we got into his view of why companies get into trouble, the value of DevOps and how PromptWorks uses Service Virtualization tools to stand in for dependencies that don’t yet exist.
Without naming companies, can you describe a project you’ve worked on that had particularly challenging issues in terms of technology, timeline or organizational culture? Were there any big lessons or takeaways that would help our readers deal with similar challenges?
We’ve had a number of clients — one in particular — hurt by setting unreasonable timelines. Some managers believe in “stretch goals” but that’s probably just because they haven’t had enough experiences of a good software process to trust it. All they can do is to “whip the ponies harder” as Ron Jeffries says in one of my favorite short books, The Nature of Software Development. Under pressure, software teams give up the wrong things, reducing value and making it harder to deliver value later. If everyone knows the goal is unreachable and the burndown chart shows the real delivery date but management won’t acknowledge the reality, then it just demoralizes the team when they miss the target, deliver a low-quality product, and have even more difficulty delivering subsequent releases.
The lesson companies should learn is to trust software experts and their processes. Industry pioneers like Martin Fowler, Kent Beck, Dave Thomas, and Bob Martin have spent decades refining how to estimate, plan and develop software effectively and they’ve been sharing their ideas all along, so there’s no good reason software development should be a black hole of resources or a project that’s always on fire. The way PromptWorks delivers software is calm and predictable. We pick a date with the client, prioritize and work stories from highest value to lowest, and by the release date we’ve delivered as much value as was humanly possible while keeping quality and productivity high. Dates can and do change for business reasons, but leveraging dates to influence the pace of development will hurt your project and your team.
What is your assessment of the DevOps phenomenon? Do you advocate for DevOps techniques? How do you see it being adopted in large organizations?
The DevOps movement is a powerful and lasting one. There may be some bubbles within DevOps, but describing infrastructure with code, automating the delivery pipeline, and standardizing environments are changes that have brought lasting benefits in the areas of predictability, efficiency, security and maintainability.
We advocate for DevOps best practices and have a team devoted to helping large organizations solidify their DevOps practices and infrastructure. It’s always a complex undertaking and DevOps perfection is a moving target, but we can improve DevOps infrastructure incrementally and tackle organizations’ largest pain points first to deliver the most value quickly.
Do you have any experience working with Service Virtualization tools for standing up simulated production environments? What’s your assessment of their value, and are there any favorite use cases you’ve seen for them?
Every project we do has numerous service dependencies — sometimes 20 or more! To fit with our rapid software development workflow, we’d need code or images for each one so that every developer, CI builder, QA analyst, and salesperson giving customers a preview could have their own isolated, disposable environment. That happens … well, never! Dependencies are almost always not built yet, Software as a Service (SaaS) beyond our control, not licensed for our use case, too heavy to stand up, or not capable of handling thousands of automated tests daily for the indefinite term.
PromptWorks has several ways of solving the problem: First, we make systems multi-tenant from the start. That doesn’t solve versioning and availability problems, but buys us a little test isolation. Second, we use stubs and mocks in our unit tests. That doesn’t help integration tests or live testing environments, but it helps not slow developers down. Third, we use simple Service Virtualization tools as part of our test framework. API recording and playback with tools like VCR in Ruby give us many of the benefits of full-blown Service Virtualization. It can be a little brittle, but it’s so easy to add onto a project, the cost of adoption is very low. We’ve also wrapped this up into an HTTP service, similar to solutions from CA Technologies and Parasoft but simpler and free.
As a last resort, we build our own virtualized services using lightweight open-source tools. We find this necessary when our end-to-end tests interact with interrelated services and behave in ways that can’t be captured with generally-available service virtualization tools. For example, in 2013 we were dependent on an API that required interaction over both HTTP and AMQP.
Building custom virtualized services is an expensive undertaking. The more interrelated your models are and the more interdependent state they have, the harder and more time-consuming it is to build, especially when the interfaces are inconsistent. I hate it when attribute getters and setters are named differently or have different types!
In your opinion, what’s the biggest mistake you still see companies making in the area of software? What should they be doing to correct that mistake?
Software developed in silos is the biggest mistake we see nearly every company making. Developers are isolated in cubicles, working solo on their own little corners of the app. Usually nobody sees their code for weeks or looks it over at a code review, but that’s too late. Architecture and technology choices are made ad-hoc and fiefdoms form around technologies and features. Like a single pilot in the cockpit of a 747, the risks are huge.
We’re big believers in pair programming, whether it’s two developers on the same team working together to finish a story or pairing across departments or even between companies! Pair programming, which is different from code reviews or just helping someone with their code, is invaluable for improving architecture, catching defects early, training junior developers, transferring knowledge around the team, and reducing the “bus factor.” A healthy pairing culture prevents developers from going down rabbit holes, gold-plating, cutting corners, and not writing tests. When we compare the velocity and code quality of teams that pair versus the same number of individuals, the difference is clear: You can’t afford to not have your software capital built in pairs — and it’s beneficial for your human capital, too!