Continuous attention to technical excellence and good design enhances agility.
Team and Technical Agility
Team and Technical Agility is one of the Five Core Competencies of the Lean Enterprise.
The Team and Technical Agility competency describes the critical skills and Lean-Agile principles and practices that are needed to create high-performing Agile teams who create high-quality, well designed technical solutions.
Why Team and Technical Agility?
In Lean enterprises, Agile Teams perform most of the work that delivers value to their customers. Consequently, an organization’s ability to execute depends on its collective teams’ ability to deliver solutions that reliably meet a customer’s needs with high quality. As a result, these teams have two essential characteristics:
- Team agility – Agile Teams are high-performing teams that are organized and operate with basic and effective Agile principles and practices.
- Technical agility – Agile Teams apply Agile technical practices to create high-quality, well-designed technical solutions that support current and future business needs.
Team agility enables teams to work in an environment that maximizes value delivery. Small, cross-functional teams aligned around a shared purpose apply a Lean-Agile, flow-based model. What’s more, they understand their role in the entire enterprise as well as the SAFe Agile Release Train (ART) which is a long-lived, team of agile teams which provides the larger vision, direction, and solution outcomes. Technical agility guarantees that team members have the requisite skills and technical practices to create the best possible solutions. They ensure systems are architecturally sound, high in code and component quality, and are easily modified to support future requirements.
These two competencies, team and technical, are the yin and yang of Agile teams, the complementary and dependent forces that create the high-performing units that power SAFe and, ultimately, the entire enterprise.
Team agility is the first half of this competency. Agile teams operate as a collaboration between the Business Owners, developers, and testers to create alignment, common understanding, and quick, predictable delivery of value. These teams have the authority and accountability to manage their own work, increasing productivity, and reducing overall speed-to-market. Agile teams commit to small batches of work, reducing feedback cycles, and adjusting to changing needs.
Agile teams are the engine that drives the ARTs, so it is critical that they are effective. A SAFe Agile Team is a cross-functional group of 5 to 11 people who are responsible for defining, building, testing, and (where applicable) deploying some element of Solution value, all in a short Iteration timebox. Specifically, the SAFe Agile team incorporates the Dev Team, Scrum Master, and Product Owner roles.
Create High-Performing Lean-Agile Teams
Merely grouping people and calling them an Agile team is no guarantee they will operate as an aligned, high-performing team. A true team is accountable and committed to common goals. Much like a sports team, they succeed and fail together. Agile teams are empowered, collaborative, aligned on a common shared goal, and have all the skills necessary to define, build, test, and whenever applicable deploy value in short iterations. A backlog organizes teams around a common goal and creates a shared understanding of what needs to be built, the relative value, and prioritization. SAFe Agile teams operate in the large context of an ART, which supports scaling.
Work in a Lean-Agile Process
SAFe Agile teams typically employ a blend of Agile methods, including Scrum and Kanban. Most teams base their work on Scrum and include the following Scrum practices:
- Work in short two-week iterations
- Break work into small user Story backlogs
- Plan the work for the upcoming iteration
- Meet daily to assess progress towards the iteration goals in daily stand-up meetings
- Demonstrate a working system at the end of the iteration
- Discuss how to improve the process before starting the iteration cycle again
To optimize flow, teams also visualize and manage their flow of work in a Kanban system. Kanban helps teams identify bottlenecks by defining work-in-process (WIP) limits to help teams stop working on new user stories and start finishing work in the queue. Teams are cross-functional and have all the skills necessary to complete work on a feature or component. Agile teams do not group by functional skill (tester team, developer team, etc.) or technical infrastructure, as silo-based teams create dependencies that slow overall value delivery.
Operate as Part of an Agile Release Train
Nothing beats an Agile team, except a team of Agile teams. To deliver complex systems, multiple teams need to collaborate under the umbrella of an ART. These trains bring together all the people needed to define, build, test, and deploy a solution for customers.
It is not enough for a team to plan and execute by itself. Instead, all teams on an ART need to plan together, integrate and demo together, deploy and release together, and learn together. Each team understands and commits to achieving not only their objectives but the larger ART objectives as well.
Team agility provides the way for teams to work and deliver value alone, or with other teams in short timeboxes. For the delivery to be effective, however, it’s essential to build quality in, which requires technical agility.
Technical agility, the second half of this competency, defines the Agile Software Engineering principles and practices teams use to deliver solutions quickly and reliably. Software Engineering is “the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software.”  Agile Software Engineering adds Lean-Agile values and principles and eXtreme Programming (XP) practices, agile modeling, proven approaches for software design, and more.
Agile teams operate in a fast, flow-based system to quickly develop and release high-quality business capabilities. Instead of performing most testing at the end, Agile teams define and execute many tests early, often, and at multiple levels. Tests are defined for code changes (Test-Driven Development (TDD) ), Story acceptance criteria (Behavior-Driven Development (BDD) ), and Feature benefit hypothesis (Lean-UX) to build in quality (Figure 1). Building in quality ensures that Agile’s frequent changes do not introduce new errors. Agile teams create designs that continually evolve to meet current and future business needs.
In traditional project management, success is measured by fully completing an entire initiative on time and on budget. Lean-Agile strives to quickly and continually release small, Minimal Marketable Features (MMF) to learn and adapt. MMFs define the smallest amount of functionality with intrinsic business and market value. Lean-UX treats every Feature and every requirement as an assumption that must be validated. The last step in Lean-UX validates the hypothesis to determine if the Feature truly provides the anticipated value. Teams implement telemetry along with each Feature that monitors the MMF’s benefit hypothesis and determines if the expected benefit has been achieved.
The solution’s architecture can impact flow and inhibit the team’s ability to independently release in small batches. Component/service-based architectures that communicate through well-defined interfaces allow teams to independently develop, test, deploy, and release system components/services. Intentional architecture creates an architectural runway consisting of enablers for future MMFs. Architecture is a collaborative between the architect and the teams using the architecture.
Think Test First
Fast flow depends on building quality into our development system through testing at multiple levels. Errors severely impact flow, delaying releases and making wait times uncertain. Accordingly, we generate tests for everything—Features, Stories, and code—ideally before the item is created, or test-first. Test-first applies to both functional requirements (Feature and Stories) as well as non-functional requirements (NFRs) for performance, reliability, etc. Figure 2 illustrates how a test-first approach collapses the traditional “V-Model” (left view) by creating tests earlier in the development cycle (right view).
To support fast flow, tests need to run quickly, and teams strive to automate them. Since larger, UI-based, end-to-end tests run much slower than small, automated tests, we desire a balanced testing portfolio with many small fast tests and fewer large slow tests. The Testing Pyramid in Figure 3 illustrates these goals. Unfortunately, many organizations testing portfolios are unbalanced, with too many large, slow, expensive tests, and too few small, quick, cheap tests. Test-first reverses those results. By building large amounts of code and Story-level tests, we reduce our reliance on slower, end-to-end, expensive tests.
Create Stories with Behavior-Driven Development
Agile teams apply user stories as small, implementable, and testable statements of system intent. Good user stories require multiple perspectives to understand and define behavior:
- Product Owners provides customer thinking for viability and desirability
- Developers provide technical feasibility
- Testers provide broad thinking for exceptions, edge cases, and other unexpected ways users may interact with systems
Together, these perspectives define user story behavior with the results represented in the story’s description, acceptance criteria, and acceptance tests. The acceptance tests (BDD) are written using the system’s domain language. Writing the tests in this manner assist everyone to communicate clearly and gain alignment on the story’s behavior. BDD tests are then automated and run continuously to maintain built-in quality. The BDD tests are written against system requirements (stories) and therefore can be used as the single source of truth for system behavior, replacing document-based specifications.
Teams use lightweight models to communicate system design and behavior. To illustrate how the system entities are related, or how they collaborate to provide behavior, a simple, quick diagram can be “worth a thousand words.” Models take two primary forms:
- Static, or structural, models that show the responsibilities of entities and the relationships between them
- Dynamic, or behavioral, models that show collaboration between entities to realize system functionality
Together, structural and behavioral models allow teams to collaborate on the system’s current design and how to evolve it into a new design.
Design for Quality
A solution’s code and design quality impact a team’s ability to reliably deliver new functionality quickly. Fast flow depends on how well teams build quality into their design and implementation. Along with other practices, several eXtreme Programming (XP) practices  encourage good design:
- Coding standards ensure consistent style and format to make engineering artifacts readable and therefore more easily and reliably modified.
- Pairing on work provides multiple perspectives and a continuous review process that enhances the team’s skills and produces higher-quality work products.
- Collective ownership allows any engineer to modify any part of the system at any time and creates broader collective knowledge that reduces delays and bottlenecks
As a system’s requirements evolve, its design must also evolve to support them. Low-quality designs are difficult to understand and modify, which typically result in slower delivery with more defects. Applying good coupling/cohesion and appropriate abstraction/encapsulation make implementations easier to understand and modify. SOLID principles  make systems flexible so they can more easily support new requirements:
- Single responsibility principle – Entities should do one thing well. Gather together things that change for the same reason and separate things which change for different reasons.
- Open/closed principle – Entities should be open for extension but closed for modification. Keep existing entities closed for change while extending them to support new behavior.
- Liskov substitution principle -Clients of an interface should not depend on a particular implementation and should be able to use any implementation without knowing.
- Interface separation principle – Favor multiple client-specific interfaces over one, large, general-purpose interface.
- Dependency inversion principle -High-level modules should not depend upon low-level modules and both should depend upon abstractions/interfaces.
Design Patterns  describe well-known ways to support these principles and provide a common language to ease understanding and readability. Naming an element ‘Factory’ or ‘Service’ quickly denotes its intent within the broader system. Using a set-based design explores multiple solutions to arrive at the best design choice, not the first choice. See Design Quality, part of SAFe’s Built-in Quality guidance, for more details.
Implementing with Quality
Agile teams continually implement solutions using quality practices including TDD, refactoring, and emergent design. TDD is ultimately a development mindset where a developer continually creates the smallest possible test and then implements the code for that test in a rapid cycle (ideally, minutes). To run tests fast, test doubles (mocks) are employed for entities that are slow or have less availability.
As a system evolves, its design must also evolve to better and more reliably support future changes. Refactoring modifies the internal code structure without changing the behavior, typically towards some design and/or architectural patterns. TDD creates a rich set of tests that allow developers to reliably and confidently refactor the solution’s design. Growing a systems design in this way allows it to emerge as requirements evolve, as opposed to trying to create a complete design upfront when all the requirements are not yet known.
Continuously Integrate and Deploy with Quality
Scaling agility results in many engineers making many small changes that must be continually checked for conflicts and errors. Continuous integration (CI) keeps all engineers working on the latest version of artifacts by frequently (every few hours) integrating changes. Continuous deployment (CD) provides fast feedback so changes are error-free, meet quality standards, and work correctly in a production-like context. As Figure 4 illustrates, every developer-commit automatically launches a process to build, test, and deploy changes through the Continuous Delivery Pipeline. ‘Masks’ represent test doubles for system elements needed to run the system under test but proxied to reduce testing time or costs. See the DevOps and Release on Demand competency article for more detail.
SAFe also provides a self-assessment that teams can use to continually assess and improve their teamwork and technical abilities.
Teams are the foundation of SAFe and the Lean enterprise, as they perform the clear majority of the work that delivers customer value. And as Michael Jordan tells us, talent alone is not sufficient. Achieving goals requires teamwork and intelligence. Organizations must create an environment for workers to operate as high functioning teams and ensure they have the requisite skills and knowledge to create quality solutions to meet current and future business. Both are vital to a Lean enterprise’s ability to execute and deliver.
Learn More IEEE STD 610.12-1990, IEEE Standard Glossary of Software Engineering Terminology, IEEE Computer Society, 1990.  Beck, Kent. Test-driven Development: By Example. Addison-Wesley. 2003  Pugh, Ken, Lean-Agile Acceptance Test-Driven Development: Better Software Through Collaboration. Addison-Wesley. 2010.  Gothelf, Jeff and Josh Seiden. Lean UX: Designing Great Products with Agile Teams. O’Reilly Media. 2016.  Beck, Kent. Extreme Programming Explained. Addison-Wesley. 1999.  Martin, Robert. Design Principles and Patterns. https://web.archive.org/web/20150906155800/http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf 2000.  Gama, Erich, et al. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. 1994.  Fowler, Martin. Refactoring: Improving the Design of Existing Code. Addison-Wesley. 1999.
Last update: 29 October 2018