Category: Development

Automated Tests for Asynchronous Processes

It’s been a while since I’ve worked on a server-side application that had asynchronous behaviour that wasn’t already an event-driven system. Asynchronous behaviour is always an interesting challenge to design and test. In general, asynchronous behaviour should not be hard to unit test – after all, the behaviour of an action shouldn’t necessarily be coupled temporally (see forms of coupling).

TIP: If you are finding the need for async testing in your unit tests, you’re probably doing something wrong and need to redesign your code to decouple these concerns.

If your testing strategy only includes unit testing, you will miss a whole bunch of behaviour which are often caught at high level of testing like integration, functional or system tests – which is where I need asynchronous testing.

Asychronous testing, conceptually, is actually pretty easy. Like synchronous testing, you take an action and then look for a desired result. However unlike synchronous testing, your test cannot guarantee that the action has completed before you check for the side-effect or result.

There are generally two approaches to testing asynchronous behaviour:

  1. Remove the asynchronous behaviour
  2. Poll until you have the desired state

Remove the asynchronous behaviour

I used this approach when TDD-ing a thick client application many years ago, when writing applications in swing applications was still a common approach. Doing this required isolating the action invoking behaviour into a single place, that, instead of it occurring in a different thread would, during the testing process, occur in the same thread as the test. I even gave a presentation on it in 2006, and wrote this cheatsheet talking about the process.

This approach required a disciplined approach to design where toggling this behaviour was isolated in a single place.

Poll until you have the desired state

Polling is a much more common approach to this problem however this involves the common problem of waiting and timeouts. Waiting too long increases your overall test time and extends the feedback loop. Waiting too short might also be quite costly depending on the operation you have (e.g. hammering some integration point unnecessarily).

Timeouts are another curse of asynchronous behaviour because you don’t really know when an action is going to take place, but you don’t really want a test going forever.

The last time I had to do something, we would often end up writing our own polling and timeout hook, while relatively simple is now available as a very simple library. Fortunately other people have also encountered this problem in java-land and contributed a library to help make testing this easier in the form of Awaitility.

Here is a simple test that demonstrates how easy the library can make testing asynchronous behaviour:

package com.thekua.spikes.aysnc.testing;

import com.thekua.spikes.aysnc.testing.FileGenerator;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static java.util.concurrent.TimeUnit.SECONDS;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;

public class FileGeneratorTest {

    private static final String RESULT_FILE = "target/test/resultFile.txt";
    private static final String STEP_1_LOG = "target/test/step1.log";
    private static final String STEP_2_LOG = "target/test/step2.log";
    private static final String STEP_3_LOG = "target/test/step3.log";

    private static final List<String> FILES_TO_CLEAN_UP = Arrays.asList(STEP_1_LOG, STEP_2_LOG, STEP_3_LOG, RESULT_FILE);


    @Before
    public void setUp() {
        for (String fileToCleanUp : FILES_TO_CLEAN_UP) {
            File file = new File(fileToCleanUp);
            if (file.exists()) {
                file.delete();
            }
        }
    }


    @Test
    public void shouldWaitForAFileToBeCreated() throws Exception {
        // Given I have an aysnc process to run
        String expectedFile = RESULT_FILE;

        List<FileGenerator> fileGenerators = Arrays.asList(
                new FileGenerator(STEP_1_LOG, 1, "Step 1 is complete"),
                new FileGenerator(STEP_2_LOG, 3, "Step 2 is complete"),
                new FileGenerator(STEP_3_LOG, 4, "Step 3 is complete"),
                new FileGenerator(expectedFile, 7, "Process is now complete")
        );

        // when it is busy doing its work
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (final FileGenerator fileGenerator : fileGenerators) {
            executorService.execute(new Runnable() {
                public void run() {
                    fileGenerator.generate();
                }
            });
        }

        // then I get some log outputs
        await().atMost(2, SECONDS).until(testFileFound(STEP_1_LOG));
        await().until(testFileFound(STEP_2_LOG));
        await().until(testFileFound(STEP_3_LOG));

        // and I should have my final result with the output I expect
        await().atMost(10, SECONDS).until(testFileFound(expectedFile));
        String fileContents = readFile(expectedFile);
        assertThat(fileContents, startsWith("Process"));

        // Cleanup
        executorService.shutdown();
    }

    private String readFile(String expectedFile) throws IOException {
        return new String(Files.readAllBytes(Paths.get(expectedFile)));

    }


    private Callable<Boolean> testFileFound(final String file) {
        return new Callable<Boolean>() {
            public Boolean call() throws Exception {
                return new File(file).exists();
            }
        };
    }
}

You can explore the full demo code on this public git repository.

Fixing ssh on Mac Sierra 10.12.1

I recently upgraded my mac to the latest OS only to find out that my ssh command wasn’t working.

>ssh <strong>servername</strong>

resulted in:

> .ssh/config: line 18: Bad configuration option: useroaming
> .ssh/config: terminating, 1 bad configuration options

which looks like because I added in the following entry to my

.ssh/config

file in response to a previous SSH vulnerability:

UseRoaming no

This vulnerability looks like it’s been fixed: https://www.solved.tips/sshconfig-line-7-bad-configuration-option-useroaming-macos-10-12-sierra/

The Well Rounded Architect

In this blog post, I explore the six different dimensions I covered in my recent talk at the O’Reilly Software Architecture conference in London called “The Well Rounded Architect.”

The elements of the well-rounded architect

The Well Rounded Architect

Acting as a Leader

Good software architects understand that their role as a leader is not necessarily telling developers what to do. Rather, good architects act like a guide, shepherding a team of developers towards the same technical vision drawing upon leadership skills such as story-telling, influencing, navigating conflict and building trust with individuals to turn their architectural vision into reality.

A good leader, and thus, a good architect, will listen carefully to the opinions of each contributor, fine-tuning their vision with feedback from the team. This leads well onto the next point.

Being a developer

Making good architectural choices is a function of balancing an ideal target architectural state with the current state of a software system. As an example, there is no sense in adding a document database to a system if the problem domain is better suited for a relational database, even if that’s boring. An architect may feel tempted to impose technologies or architectural choices without considering the fit for the problem space – AKA behaviours of the “ivory tower architect.”

The best way an architect can mitigate this is by spending time with developers and time in the code. Understanding how the system has been built up, and the constraints of the system as it stands today will give the architect more information about the right choices for today’s environment.

Having a systems focus

Seasoned developers know that code is only one aspect to working software. To make code run, a seasoned developer understands there are other important quality attributes necessary for code to run well in its production environment. They consider aspects like deployment processes, automated testing, performance, security, and supportability. Where developers may approach these quality attributes ad hoc, an architect will focus on understanding not just the code but also the quality attributes necessary to meet the many needs of different stakeholders such as support, security, and operations staff.

The good architect focuses on finding solutions that can satisfy as many of these different stakeholder needs instead of choosing a tool or approach optimised for the preferences or style of a single contributor.

Thinking like an entrepreneur

All technology choices have costs and benefits, and a good architect will consider new technology choices from both perspectives. Successful entrepreneurs are willing to take risks, but seek ways to learn quickly and fail fast. Architects can approach technology choices in a similar way, seeking real-world information about short- and long-term costs and the likely benefits they will realise.

A good example is when the architect avoids committing to a new tool based on reading a new article, or having heard about it at a conference. Instead they seek to understand how relevant the tool is in their environment by running an architectural spike to gather more information. They don’t pick a tool based on how good the sales pitch is, but what value it offers, given what they need for their system. They also look for the hidden costs of tools such as how well is a tool supported (e.g. level of documentation, community adoption), how much lock-in the tool brings or the extra risks it introduces over the long-term.

Balancing strategic with tactical thinking

A lot of teams build their software reactively with individual developers choosing tools and technologies that they are most comfortable with, or have the most experience with.

The good architect keeps an eye out for what newer technologies, tools or approaches might be useful but does not necessarily draw upon them immediately. Technology adoption requires a considered approach looking at a long-term horizon. Architects will seek for a good balance between agility (allowing the team to move fast) and alignment (keeping enough consistency) at both a team and organisational level.

An exercise like the Build your own Tech Radar is a useful tool to explore technologies with strategy in mind.

Communicating well

Architects know that effective communication is a key skill for building trust and influencing people outside of the team. They know that different groups of people use different vocabulary and that using the technical terms and descriptions with business people makes communication more difficult. Instead of talking about patterns, tools and programming concepts, the architect uses words their audience will be familiar with. Communicating technical choices to business people with words like risk, return, costs, and benefits will serve an architect better than the words they use with their development team.

An architect also realises that communicating within the team is just as important as outside, and will use diagrams and group discussions to establish and refine the technical vision, and use a written log like an Architectural Decision Log or a wiki to provide a historical trail for future generations.

Conclusion

Doing the job of a well-rounded architect is not easy. There are so many elements to focus us, each drawing upon many skills that a developer often doesn’t focus on practicing. What is most important is not necessarily the ability an architect has, but that they have enough expertise in each of these different areas to be effective. An architect who is skillful in only one of these six areas described above will not be as effective as an architect who has a good level of expertise in all of them.

Workshop outputs from “How Architects nurture Technical Excellence”

Workshop background

Earlier this week, I ran a workshop at the first ever Agile Europe conference organised by the Agile Alliance in Gdansk, Poland. As described in the abstract:

Architects and architecture are often considered dirty words in the agile world, yet the Architect role and architectural thinking are essential amplifiers for technical excellence, which enable software agility.

In this workshop, we will explore different ways that teams achieve Technical Excellence and explore different tools and approaches that Architects use to successfully influence Technical Excellence.

During the workshop, the participants explored:

  • What are some examples of Technical Excellence?
  • How does one define Technical Excellence?
  • Explored the role of the Architect in agile environments
  • Understood the broader responsibilities of an Architect working in agile environments
  • Focused on specific behaviours and responsibilities of an Architect that help/hinder Technical Excellence

What follows are the results of the collective experiences of the workshop participants during Agile Europe 2016.

Examples of Technical Excellence

  • A set of coding conventions & standards that are shared, discussed, abided by by the team
  • Introducing more formal code reviews worked wonders, code quality enabled by code reviews, user testing and coding standards, Peer code review process
  • Software modeling with UML
  • First time we’ve used in memory search index to solve severe performance RDBMS problems
  • If scrum is used, a good technical Definition of Done (DoD) is visible and applied
  • Shared APIs for internal and external consumers
  • Introducing ‘no estimates’ approach and delivering software/features well enough to be allowed to continue with it
  • Microservice architecture with docker
  • Team spirit
  • Listening to others (not! my idea is the best)
  • Keeping a project/software alive and used in prod through excellence customer support (most exclusively)
  • “The art must not suffer” as attitude in the team
  • Thinking wide!
  • Dev engineering into requirements
  • Problems clearly and explicitly reported (e.g. Toyota)
  • Using most recent libraries and ability to upgrade
  • Right tools for the job
  • Frequent availability of “something” working (like a daily build that may be incomplete functionality, but in principle works)
  • Specification by example
  • Setting up technical environment for new software, new team members quickly introduced to the project (clean, straightforward set up)
  • Conscious pursuit of Technical Excellence by the team through this being discussed in retros and elsewhere
  • Driver for a device executed on the device
  • Continuous learning (discover new tech), methodologies
  • Automatic deployment, DevOps tools use CI, CD, UT with TDD methodology, First implementation of CD in 2011 in the project I worked on, Multi-layered CI grid, CI env for all services, Continuous Integration and Delivery (daily use tools to support them), Continuous Integration, great CI
  • Measure quality (static analysis, test coverage), static code analysis integrated into IDE
  • Fail fast approach, feedback loop
  • Shader stats (statistical approach to compiler efficiency)
  • Lock less multithreaded scheduling algorithm
  • Heuristic algorithm for multi threaded attributes deduction
  • It is easy to extend the product without modifying everything, modularity of codebase
  • Learn how to use something complex (in depth)
  • Reuse over reinvention/reengineering
  • Ability to predict how a given solution will work/consequences
  • Good work with small effort (efficiency)
  • Simple design over all in one, it’s simple to understand what that technology really does, architecture of the product fits on whiteboard 🙂
  • Systems’ architecture matches team/org structure
  • Self organisation
  • Ideally separated tests, Automated performance testing, automatic front end functional testing with selenium, unit testing done for the first time 10 years ago, constructing new performance testing cases takes minutes, after refactoring unit tests are passing (majority of them – hopefully all!)
  • Constant curiosity for new technologies/approaches
  • Good knowledge of software patterns (when to use and when not)
  • Learn from mistakes

Examples of Technical Excellence

Definition of Technical Excellence

  • (Technical) Excellence is an attitude to be better than yesterday
  • Technical Excellence is the holy grail that inspires teams to stay on the path of continued improvement
  • Technical Excellence is a process that continuously improves product design and the development team. Examples: Automation, knowledge sharing, culture. Synonyms: Dream
  • Technical Excellence is an ability to consciously apply tools and practices to solve and continuously improve over complex problems in a sustainable way and within constraints (e.g. time and money). Examples: Continuous Delivery

Definition

Activities of an architect

  • Explains decisions
  • Able to choose the right solution amongst many possibilities (awareness of consequences and limitations)
  • Being able to justify technical decisions made
  • Thinking (find time to think about the product, structure, technologies used, etc)
  • Helps resolve interdependencies, helps to identify/minimise external noise (i.e. technical dependency change with negative impact), co-ordination of integration with other teams working on the same project
  • Start and moderate discussions on design, longer term consequences of decisions, etc
  • Requirements definition, making sure ‘nothing’ is omitted during analysis/design
  • Questions decisions to encourage thinking about wider picture amongst developers, asks questions (non obvious especially), Asking difficult questions about work being done
  • Listens to others
  • Encourage people to bring ideas, encourage idea sharing
  • Setup backlog for achieving technical excellence
  • Challenge old decisions
  • Business decision support (IT, 3rd party)
  • Make sure we don’t bite more than we can chew – incrementally/iterative
  • Ensure architecture is visible, understood and accessible to the team, keep the technical cohesion, helps team consider the bigger picture and interdependencies, helps team define the system and diagram it
  • Detailed knowledge of technologies/protocols used
  • Forward thinking
  • Proposes solutions to complex problems
  • Diagrams/presentations
  • Wide view of situation/projects, look what other teams are building for things to reuse or interface to
  • “Main” test scenarios definition
  • Definition of components structure and interactions
  • Guard technical vision (dialogue with stakeholders)
  • Focus on project goal
  • API specification
  • Verification of current design vs planned use
  • Ad hoc just in time consulting to feature teams when things get complex
  • Teaching teams, sharing technical knowledge (and expertise) with the team
  • Coaches team. Gets buy-in from the team for change they are about to trigger, coaches dev team
  • Identifies technical skillset gaps in the team
  • Pro-active thinking
  • Gaps identification
  • Mitigates the risks
  • Out of box ideas
  • Research for solution, helps team identify areas for experimenting, exploring new territories
  • Creating proof of concept (POC)
  • Learns new things, research and try new tools, ideas, technologies, etc
  • Gains an in-depth understanding of a system before attempting to change it
  • Reviews teams’ system design, performs code reviews and coding standard support, reviews code

Architect Activities

Architect Activities

Behaviours that support Technical Excellence

Active

  • Gives team rapid and timely feedback
  • Patiently explaining all the tiny details responding to simple questions
  • Be there whenever needed
  • be the safety net whenever devs need you
  • Set communication for knowledge sharing
  • Explain the reasons behind the design
  • Raising the visibility of good developers
  • Do pair programming, works with the team
  • Explain technical excellence value for business
  • Encourage team to think and work towards Technical Excellence
  • Growing people, mentoring developers to improve tech skills, training the team, educate actively – organise coding dojos, etc
  • Set up backlog for achieving Technical Excellence
  • Raising the team spirit and motivation
  • Waking up with 3am to connect with a team on a daily basis (for a distributed team)
  • Discussing discovered problems with the team
  • Sat down with the team to teach and record architecture training for future use
  • Keeping an eye on new things on the market and bringing them to the team
  • Staying current in technologies, tools, concepts, etc.
  • Being a visible role model in terms of pursuing Technical Excellence
  • Encourages experimentation
  • Support team in collaboration with other teams
  • Helps team identify blindspots
  • Active Encouragement

    Passive

  • ability to change contexts between projects
  • Lets the team make decisions
  • Take a step back and make room for technical advancements of the whole team
  • Not doing stuff from actively discourage column
  • Team makes decisions
  • Passive Encouragement

    Behaviours that discourage Technical Excellence

    Active

  • Dictatorship, have to do it my way, will to control (every small detail)
  • Blaming and shaming
  • Making arbitrary decisions, especially without explaining the reasoning behind it
  • Rejecting too complex C++ code
  • Using ambiguous, complex, uncertain English vocabulary
  • Shutting down emergent ideas from the team
  • Discouraging ideas “I couldn’t care less about your sophisticated C++ SPT initialisation”
  • Created ugly prototype for a demo and forced team to clean up afterwards
  • Imposing BDUF (Big Design Up Front) over the development team
  • Created non-viable design (i.e. could not be implemented with current constraints)
  • Enforcing old known technologies, etc out of inertia/ignorance, sticking to the “old ways”
  • Active Discouragement

    Passive

  • Doing too many activities to follow through – not focused on any (and no time to encourage Technical Excellence)
  • Invited but never attended meetings
  • “I don’t meet with the Architect”
  • Software Architect with poor development skills
  • Not working with the team
  • Leaving obsolete information in documentation
  • Getting involved in design only if prompted
  • “I don’t know how, so I won’t define it”
  • Passive Discouragement

    Stories

  • Developers supporting software (getting email feedback)
  • Anti-Story: “Let’s *NOT* sit together” – Person leaving showed them how it was done
  • “Let’s sit down together” (solving a memory leak problem)
  • Group Problem (Security problem)
  • Stories

    If you liked this article, you will be interested in “Talking with Tech Leads,” a book that shares real life experiences from over 35 Tech Leads around the world. Now available on Leanpub.

    Why you want to give up coding

    A background story

    A friend of mine worked as a Tech Lead, let’s call them Jo (not their real name) for most of their career. A few years ago, Jo moved into a management role that involved very little coding. They were no longer working full-time as a developer and they stopped playing a Tech Lead role. Jo now leads an organisation with six or seven large development groups.

    In the definition of a Tech Lead, I suggested a Tech Lead should write code a minimum of 30% of their time. Jo managed to find some time writing code, but it was inconsistent – about an hour a week. In a 40-hour week, that is less than 3%. Jo missed writing code. Jo was no longer a developer and Jo was no Tech Lead.

    What do you control? What do you influence?

    Every role comes with a set of responsibilities, and the authority to fulfil those responsibilities. This authority gives you a certain amount of control.

    For example, a developer has control over the code and tests that they design and write. Others may have influence over the code. Examples of influencing factors include architectural or product and/or platform constraints, team code standards and code reviews. Ultimately the developer has control over their own code.

    Every company has a certain organisational design. Developers (and other employees) work within this structure. The organisational design impacts on how effective software delivery is. Rigidly hierarchical structures with completely different departments (e.g. developers and testers) have difficulty collaborating. An ineffective organisational design is a sore point for many developers because it makes delivering software much harder.

    A developer has zero control over organisational design. They might be able to influence it, but it is ultimately controlled by managers. Some developers may try to change this, but most complain. I have heard this from developers in the past:

    Who’s brilliant idea was to setup a development [team] like this?

    Who's great idea was this?
    Another example.

    I can’t get anything done because I rely on those people to get something done and they sit on another floor.

    Developers can complain, which is an ineffective style of influencing, although there are many more effective ways. In the book Influence: The Psychology of Persuasion, the author, Robert Cialdini outlines six key influencing strategies: Reciprocity, Commitment (and Consistency), Social Proof, Liking (a variant of the Halo Effect), Authority, and Scarcity.

    Developers only influence their working environment. They do not control it. Note: An exception is, of course, when a company is small enough that the developer also takes on general organisational management responsibilities (e.g. in a startup)

    Trading control for influence

    Influence for control

    Jo, who moved from being a developer to a Tech Lead, and again from a Tech Lead to a general manager shared an interesting insight with me.

    You know those things I used to complain about as a developer? Well, now I have the ability to change them.

    Programmers see the “non-technical” path as a path with nothing to offer. When programmers step into a leadership role, they inherit both responsibilities and the authority to control more of their work environment. A developer works within these constraints. A Tech Lead has more authority to change those constraints, and a manager even more authority to control and change those constraints.

    How does this impact developers who become Tech Leads?

    When developers give up their control in trade of influence, their sphere of influence grows. Instead of developing a single feature, they can guide the entire technical solution. The Tech Lead’s influence also grows between the technical and the business side. A Tech Lead has much more influence over how technology can be used to solve business problems, while developers are engaged too late.

    I would suggest to Tech Leads never to give up all coding. Instead, it is trading more of the time you would spend crafting code, in exchange for a wider sphere of influence. The wider sphere of influence helps not just you, but also your team write better code in a better work environment.

    If you liked this article, you will be interested in “Talking with Tech Leads,” a book that shares real life experiences from over 35 Tech Leads around the world. Now available on Leanpub. The featured image from this post is taken from Flickr under the Creative Commons licence

    How do I still write code as a Tech Lead?

    I have previously suggested that effective Tech Leads spend an ideal minimum of 30% of their time writing code. A common question I hear in the Tech Lead training course I run is:

    Where do I find the time to code when I have all these other responsibilities to take care of?

    I know that many Tech Leads struggle to find the right amount of code, and also struggle to know what sort of tasks to take on. Here are some useful bits of advice that have helped me and others:

    Avoid working on critical path items

    Although Gantt charts have a bad name in IT, they do serve a useful visual model for depicting critical chains and seeing the critical path. A Tech Lead will usually find themselves interrupted and finding a solid block of coding time will be unusual. As a guideline, I advise Tech Leads not to focus on critical path tasks because they will often block progress on those tasks.

    If a critical path item requires knowledge or experience, that only the Tech Lead has, it is useful to work with another developer on the task, so that progress continues when the Tech Lead works on responsibilities.

    Learn to delegate

    Delegating is a skill that Tech Leads must develop, and a skill that developers rarely have an opportunity to build. The Situational Leadership Model clearly explains when to delegate. Effective delegation depends on the skill and motivation of an individual. The model explains four modes: Telling, Selling, Participating, Delegating with the end goal of aiming to delegate as much as possible.

    Delegating is only possible when a leader believes someone has the sufficient skill and sufficient motivation to complete a task.

    A common challenge for many Tech Leads is trusting that someone other than them writes code good enough to complete an appropriate task.

    Loosely pair program

    I’m not a big believer in full time pair-programming. But finding the right balance between full-time and nothing is hard to achieve. A good arrangement is to work with someone on the approach or design for a particular problem, and then to do regular reviews (or short pair-programming sessions) to see what new information or challenges emerge as code is written.

    This style of “co-working” on the design and code works well for a Tech Lead, who will find themselves constantly interrupted.

    Avoid unnecessary or poorly run meetings

    There is nothing worse for a programmer to sit in a meeting which has no purpose or no outcome. These are frustrating because the time spent in the meeting is waste. Learn how to run effective meetings, to avoid the frustrations of ineffective meetings.

    Use the “5 P’s of Effective Meetings” model:

    • Purpose – Is it clear what the meeting is for? Ensure each meeting has one clear purpose. Examples include: Distributing information, gathering information, brainstorming solutions, and seeking agreement or consensus.
    • Product – You can cut a meeting short, when you know what the outcome of that meeting should be. Define success criteria for the meeting (which will be related to purpose) to keep meetings focused and on track.
    • Participants – It is better to cancel/reschedule a meeting than to hold a meeting with the wrong people. This tweet from Esther Derby summarises it very well. Pointless Meetings
    • Probable Issues – What are the concerns or questions that will be raised during the meeting that need to be addressed, or threaten to derail the meeting?
    • Process – Every meeting should be clear about how the meeting will be run, how people are expected to participate, and special rules of what might need to be done. A meeting facilitator should start with clarifying the purpose of the meeting to reset people’s expectations.

    Learn to say no

    The art of leadership is saying no, not saying yes. It is very easy to say yes. — Tony Blair

    As a Tech Lead, you will be pressured to always take on more than you can possibly take on. The more activities you say yes to, the less time a Tech Lead has to code. If coding is really important to you (and it should be), then you need to develop an awareness of what things are really important and those that can be done by others or by non-technical people.

    Block out coding time

    I know some Tech Leads who block out calendar time in their diary on a regular basis to ensure that they have uninterrupted time to code. Developers know how interruptions break the train of thought and Tech Leads will find themselves even more interrupted in comparison to developers.

    Conclusion

    It is important a Tech Lead spends time writing code but the other responsibilities demand time away. Keeping the balance right is tricky, but the techniques described above can help you cutting code. Please leave a comment if you have other suggestions.

    If you liked this article, you will be interested in “Talking with Tech Leads,” a book that shares real life experiences from over 35 Tech Leads around the world. Now available on Leanpub.

    The Definition of a Tech Lead

    There are many names for leadership roles in software development such as Senior Developer, Architect, Technical Lead, Team Lead, and Engineering Manager. These are just a few. To me, the Technical Leader (Tech Lead) plays an unique and essential role that others cannot.

    The Definition

    The Short: A Tech Lead is a developer who is responsible for leading a development team.

    Tech Lead

    The Long: Leading a development team is no easy task. An effective Tech Lead establishes a technical vision with the development team and works with developers to turn it into reality. Along the way, a Tech Lead takes on traits that other roles may have, such as a Team Lead, Architect or Software Engineering Manager but they remain hands-on with code.

    To make the most effective choices and to maintain trust and empathy with developers, a Tech Lead must code. In “The Geek’s Guide to Leading Teams” presentation, I talked about an ideal minimum time of about 30%.

    Effective Tech Leads Code
    An extract from the The Geek’s Guide to Leading Teams presentation

    Not just a Team Lead

    Early in my career, I worked on a team that had both a Tech Lead and a Team Lead. The Team Lead didn’t have much of a technical background and had a strong focus on the people side and tracking of tasks. They would have 1-to-1s with people on the team, and co-ordinate with outside stakeholders to schedule meetings that didn’t interrupt development time where possible.

    The Team and Tech Lead

    While the Team Lead focused on general team issues, the Tech Lead focused on technical matters that affected more than just one developer. They stepped in on heated technical debates, and worked with outside stakeholders to define technical options and agree on solutions for future streams of work. They wrote code with the other developers and sometimes called for development “huddles” to agree on a direction.

    More hands-on than an Engineering Manager

    You manage things, you lead people – Grace Hopper

    Any reasonably-sized IT organisation has an Engineering Manager. They are responsible for more than one development, and have tasks that include:

    • Maintaining a productive working environment for development teams.
    • Acquiring appropriate budget for development to support business goals.
    • Representing the technology perspective on a management or board level.
    • Establishes and/or co-ordinates programmes of work (delivered through development).
    • Responsible for overall IT headcount.

    Engineering Manager

    Depending on the size of an organisation, an Engineering Manager may also be called a Chief Technical Officer (CTO) or Chief Information Officer (CIO) or Head of Software Development.

    Although an Engineering Manager represents technology, they are often very far-removed from a development team and rarely code. In contrast, a Tech Lead sits with developers, very much focused on moving them towards their goal. They work to resolve technical disputes, and are watchful of technical decisions that have long-term consequences. A Tech Lead works closely with the Engineering Manager to build an ideal work environment.

    A good Architect looks like a Tech Lead

    The Architect role ensures overall application architecture suitably fits the business problem, for now and for the future. In some organisations, Architects work with the team to establish and validate their understanding of architecture. A suitable amount of standardisation helps productivity. Too much standardisation kills innovation.

    Some organisations have the “Ivory Tower Architect” who swoops in to consult, standardise and document. They float from team-to-team, start new software projects, and rarely follow up to see the result of their initial architectural vision.

    An effective Architect looks like a good Tech Lead. They establish a common understanding of what the team is aiming for, and make adjustments as the team learns more about the problem and the technology chosen to solve it.

    What is a Tech lead again?

    A successful Tech Lead takes on responsibilities that sit with roles such as the Team Lead, the Architect and the Engineering Manager. They bring a unique blend of leadership and management skills applied in a technical context with a team of developers. The Tech Lead steers a team towards a common technical vision, writing code at least 30% of the time.

    If you liked this article exploring the Tech Lead role, you will be interested in “Talking with Tech Leads,” a book that shares real life experiences from over 35 Tech Leads around the world. Now available on Leanpub.

    Do we need a Tech Lead?

    A common question I hear is, “Is the Tech Lead role necessary?” People argue against the role, claiming a team of well functioning developers can make decisions and prioritise what is important to work on. I completely agree with this position in an ideal world. Sadly the ideal world rarely exists.

    Even when perfect conditions exist during which team members talk to each openly, discussing pros and cons before arriving at an agreed solution, it doesn’t take much to upset this delicate balance. Sometimes all it takes is for a new person joining the team, a person leaving or some stressful critical situation that drives the team into a state where arguing continues without end. My friend Roy Osherove calls this the “Chaos state.” I agree with him that a different style of leadership may be required, similar to the Situational Leadership Model.

    Technical debates occur frequently in development teams. There is nothing worse than when the team reaches a frozen state of disagreement.

    Tabs Spaces
    Image take from Emacswiki

    The Tech Lead has the responsibility to help the team move forwards. Sometimes that means using their authority. Sometimes it means working with the team to find a way forward. Facilitation and negotiation skills are invaluable assets to a Tech Lead. Understanding decision making models helps the Tech Lead decide when to step in, or when to step back. What is important is finding a way forward.

    Tech Leads are also beneficial to people outside of the team, forming a single point of contact. Medium to large organisations start to hit communication barriers because there are too many relationships to effectively build and maintain. The Tech Lead role simplifies the communication path, although simultaneously adds a single point of failure. The balance between these two trade-offs should be carefully managed and monitored.

    When played well, the Tech Lead provides countless other benefits, however the Tech Lead role does not have to played by a single person. I admire teams who say they don’t have a Tech Lead and software is still effectively delivered. They have successfully distributed the Tech Lead responsibilities or established processes to mitigate the need for the role. It does not necessarily mean the role itself is useless. The Tech Lead role is just that – just a role. Instead of focusing on whether or not the role should or should not exist, it is better to focus on ensuring all Tech Lead responsibilities are met.

    If you liked this article exploring the Tech Lead role, you will be interested in “Talking with Tech Leads,” a book that shares real life experiences from over 35 Tech Leads around the world. Now available on Leanpub.

    Top 5 Mistakes for First Time Tech Leads

    1. Spending too much time writing code

    Old habits die hard. When a developer suddenly steps into the Tech Lead role, it is not immediately clear what to do differently. Instead of taking on the Tech Lead responsibilities, they stay heads-down writing code. The more code they write, the better they feel that they are still contributing to the team. Other Tech Lead responsibilities are neglected in favour of writing code, even though they must still be fulfilled. A Tech Lead must spend enough time on non-coding responsibilities. They must ensure a Technical Vision exists, and the development team are working together towards the same goal. Both of these activities require more than just code-writing.

    2. Not spending enough time writing code

    The “Tech” in the Tech Lead role is there for a reason. It is too easy for a Tech Lead to sit in endless meetings instead of spending time with the team. They lose awareness of how the code is evolving and which patterns or anti-patterns emerge. Without an up-to-date awareness of the system and its technical constraints, a Tech Lead cannot effectively lead the team. A Tech Lead who codes has a better understanding of technical problems or opportunities whilst building and maintaining trust with developers. Writing code keeps the “Post Technical” label away.

    3. Making all the technical decisions

    The first time Tech Lead may feel compelled to make all decisions. To compensate for writing less code, or to demonstrate their new role, they give input to any and all decisions. Unfortunately this behaviour discourages the team from making contributions. It sends the message to the team they should do what they are told, or not think, even though a team member has the better solution to a particular problem. An effective Tech Lead knows when to give input, knows when to make decisions and when to step back and allow the team to take more ownership.

    4. Talking only Tech

    A Tech Lead interacts with many people who sit outside of the development team such as people from marketing, finance or a product division. These people usually have very limited technical knowledge. Talking to them in terms of frameworks, libraries and tools adds confusion, frustration and simultaneously signals a lack of empathy. A Tech Lead must find a way to communicate ideas in ways non-technical people can understand such as using analogies and using terms others can easily relate to.

    5. Constantly reacting

    A new Tech Lead will find themselves juggling several activities at once. The bane of a developer, interruptions, becomes an everyday occurrence. A first time Tech Lead can simply react to the loudest or most alarming situation, even if it is not the most important. Over time, the Tech Lead develops better time and task management skills in order to manage the many demands.

    If you liked this article exploring the Tech Lead role, you will be interested in “Talking with Tech Leads,” a book that shares real life experiences from over 35 Tech Leads around the world. Now available on Leanpub.

    Talking with Tech Leads

    I am proud to announce the release of my latest book, “Talking with Tech Leads” that is now available on Leanpub.

    I started this book project over a couple of years ago when I discovered a lack of resources for helping developers transition into a role which demanded more than good development skills.

    Talking with Tech Leads

    Book Description: A book for Tech Leads, from Tech Leads. Discover how more than 35 Tech Leads find the delicate balance between the technical and non-technical worlds. Discover the challenges a Tech Lead faces and how to overcome them. You may be surprised by the lessons they have to share.

    Buy it here on Leanpub.