Our approach to quality at Volkswagen Software Dev Center Lisbon
Assuring the quality of the demanding software products we build at Volkswagen SDC:LX is not easy. Saying we’re agile is not enough, so I’ll present the factors that ensure the required standards are met.
5 min readSep 18, 2019
As a disclaimer, this is solely my point of view.
Culture
- Team members are involved in the hiring evaluation stages, which greatly improves compatibility and ensures continuity in culture and methodology.
- Critical thinking is highly appreciated, and everyone is free to challenge what’s defined and the others (regardless of the role). Our non-judgmental environment supports this.
- We rely on a scientific approach to problems by setting hypotheses and assumptions and seeking to confirm or disprove them.
- Team empowerment fosters ownership: since the team is responsible for the product (building and operating it), everyone is more dedicated to it. We have a flat structure, and teams (PMs, designers, and developers) are balanced for autonomy reasons.
- Context switching is expensive, so focus is essential to our work. For example, you only work on a single product at a time, and we reduce work in progress.
- Discussions of good practices are welcomed, valued, and common.
- We promote rotation amongst teams and even offices (we run programs to interchange people between offices). This allows for sharing ideas and solutions, comparing and learning, and questioning the implemented habits.
- A feedback culture promotes individual and team improvement (team, product, and office retrospectives, individual feedback, etc.). Everyone reflects on it and gets continuously better.
- Transparency and happiness are maintained so everyone feels like they are part of the office. Weekly office syncs are held with everyone, and the happiness team regularly organizes social events.
- A culture of constant learning is held. It’s common to share interesting articles and other web resources. We have a book library and free access to online courses. We organize, attend, and host events. We have internal weekly meetups where anyone can present something.
Practices
- Every potential product starts with a scoping meeting to define the boundaries of the problem to be tackled; this is followed by a discovery/framing phase to understand the problem better and validate if we should move on. If so, we do inception to develop an MVP to test it in a real environment quickly. This ensures we do the minimum to validate it quickly and get feedback as soon as possible (lean development).
- We follow a user-centric philosophy. Every feature in the backlog is clearly written to bring value to the user, which explains why you won’t find stories split by backend and frontend—we always split “vertically.”
- We do small experiments within the teams and the office by trying new things that could improve our work (e.g., regarding our practices). Everyone is free to suggest improvements.
- Most documents are produced collaboratively and are quickly iterated. This is achieved using collaborative tools like digital whiteboards, word processors, issue trackers, etc.
- By constantly pairing, we run continuous live code reviews instead of decoupled/async code reviews; the feedback is immediate and contextualized, thus making it more valuable.
- Pairing guarantees knowledge sharing because of its nature and also due to the daily pair rotations. Consequently, the team knows the codebase/architecture and is less dependent on individuals (‘no heroes’ culture). Pairing also happens with designers and product managers (PMs), which promotes know-how sharing amongst roles.
- Decisions are debated, which improves their quality. By default, they are done as a pair, but if needed, they’ll contact the team or other teams for discussion.
- In addition to all the automatic quality checks, the team performs manual testing per feature: developers validate the stories, and PMs/designers accept them in a near-production environment.
- Continuous improvement happens at a codebase level. Refactorings are usually done when working on a story. Other refactors and tech debts are tracked so as not to be lost (any team member can add them to the backlog). Keeping the code maintainable is a core value.
- Voluntary facilitators improve the quality and outcome of meetings. They make sure the meeting is time-boxed and focused. We start by diverging and converge in the end.
- Test-driven development (TDD) ensures a better software design, and code gets documented and tested. Since we focus on the behavior (BDD), the implementation derives directly from the user requirements.
- The whole team (and possibly other people) is frequently invited to design sessions (e.g., to design a feature) organized by the designers. This feedback is considered, and the designs are iterated.
Technology
- Developers are full-stack, which promotes feature know-how/ownership from top to bottom, start to end, and a skill set across multiple technologies.
- There’s a general passion for technology (that’s almost a requirement), but we have methods to ensure that it doesn’t bias our decisions, so we keep our focus on the users.
- The team is free to choose the languages, runtimes, and frameworks and tries to make informed decisions when picking them.
- For each language and runtime, we choose and set up our IDEs, editors, utilities, and plugins so that we get code warnings, tips, validations, autocomplete, etc., and these are always up-to-date.
- Attention to warnings: Every warning in the code editor, logs, or other documents is a symptom of something, so we always try to fix it.
- Static code analysis: the code is automatically analyzed regarding code conventions and other concerns.
- Versions checking: we make sure that the latest versions of the runtimes, frameworks, and libraries are used. This reduces the number of bugs such as security fixes.
- Unit testing, integration testing, and end-to-end (E2E) testing are done by default for all software components, testing multiple layers and combinations. Since those are developed in TDD, we feel safe refactoring or adding features. All the test suites are run per code push.
- Continuous Delivery/Integration (CD/CI): the features are pushed to the master branch (trunk-based development) and automatically deployed to pre-production. That way, we don’t have to track many feature branches and releases. The CI pipeline is constantly visible on a TV.
- Different environments in the CI before reaching production: if any test fails, the code is not deployed. This also gives more opportunities to find problems before production since all team members, directors, and POs use them.