ssh
, tmux
and vim
: A Simple Yet Effective Pair Programming Setup
At my work, Drift+Noise, we try to use Agile software development methods where possible. For instance, we use TDD largely for our unit tests, BDD for functional tests (sometimes also called customer tests) as well as Continuous Integration and Continuous Delivery via Jenkins. Basically, if the test suite passes, the new code gets rolled out to production automatically. Of course, this requires good test coverage and code quality.
One thing which can aid code quality is pair programming and I thought I’d share our work setup here, which we’ve found works well both in the office as well as remotely.
We’ve found it to be fun and it has worked rather well. We can’t always pair program because we’re not always working on the same project(s), but when we are, we’ve noticed an enhanced knowledge transfer due to both of us working on a single problem at the same time. Each person brings different perspectives to the task at hand, and if the coding task is rotated, then each person is able to stay refreshed and focussed for longer.
The technical setup
To set up the shared sessions, it’s useful to have a similar setup on both computers. This way it’s possible to pair program using the other person’s environment if necessary. For instance, if one person has a particular project set up on their laptop and it would take some time to get the same setup working on the other person’s system, then it’s as simple as logging in to the already set up environment and one can become productive straight away.
Because we both use vim
as our editor, a console is sufficient for this
setup to work. If you use a graphical IDE, however, then this setup won’t
work and you’ll have to find some other way of sharing screens and
programming environments.
Install the necessary software
In our setup both systems need tmux
and vim
installed as well as an
ssh
server running. On Debian-based systems this will do the job:
$ sudo apt install openssh-server tmux vim
We shall call the system hosting the shared session the “host” system, and the other system, the “guest” system.
It’s preferable that both systems be Unix-based so that the command listings mentioned below can be used as-is. However, if the guest user is on a Windows system, it should be possible to use PuTTY to log in to the host system and share the session this way, however such a setup doesn’t allow guest and host systems to be swapped.
Give users sufficient permissions
To allow the guest user to access the host system, a user needs to be
created. This user should be added to the users
group on the host system
so that they can access the shared tmux
socket.
$ sudo adduser <username> # for user logging in remotely
$ sudo usermod -a -G users <username> # for both users to pair
Both users have to be in the same group since the tmux
session will be
shared via a socket (which will appear as a file on the filesystem) and each
user must be able to read and write to this socket so that both can control
the tmux
session.
For those wanting to be more restrictive, one could create a tmux
group
and assign specific users to this group. Nevertheless, using the users
group here does the job nicely, especially for the laptop-based (effectively
single user) systems used here.
Share a tmux
session
To initialise the shared tmux
session on the host computer, run:
$ tmux -S /tmp/sharedtmux new -s shared
This will create the special file sharedtmux
under /tmp
over which the
session is shared and creates a new tmux
session named shared
.
We need to ensure that both users can access (read from and write to) the
shared socket, so we change the group of the socket file to belong to the
users
group:
$ chgrp users /tmp/sharedtmux
The guest user then logs in via ssh
and attaches to the shared session via:
$ tmux -S /tmp/sharedtmux attach -t shared
Now it’s possible for both users to type in the terminal. In order to reduce confusion it’s recommended that only one person type at a time!
Working together on your own computer: a win-win situation
At one point in time we used to use an external monitor connected to one of the laptops and both people in the pair would look at the same monitor. This way we could sit next to one another and point at code on the screen.
As it turns out this isn’t necessary, since both people have their own
screen, and highlighting something is simple in tmux
, so we either sit at
our respective desks, or use the beanbags in our office1:
This allows us to be much more flexible with our working environment. The main thing, of course, is that we can talk to one another in order to discuss the changes that are being made or explain why something is being done the way it is.
Another advantage of this setup is that each participant is able to type more comfortably by using their own keyboard. If it were necessary to share a single physical keyboard this would reduce the efficiency of the programming session due to the time involved in shifting the keyboard between parties, as well as the cognitive break required in having to swap keyboards; the programming flow is thus better maintained with two separate keyboards.
One further advantage of this setup is that if the keyboard layouts are
different, it doesn’t matter since the same characters end up getting
through to tmux
. This is handy if one of you has e.g. a German keyboard
layout and the other has a US-English keyboard layout. Thus each person can
work comfortably in their own most familiar environment.
Remote pair programming needs verbal communication
A further cool thing about this setup is that not much needs to be changed
in order for it to work remotely. The missing ingredients are a VPN so that
the login via ssh
still works, and (most importantly) a verbal
communication channel. We often use Telegram for
this purpose, but one could use Skype or Google
Hangouts or something similar. The main thing
is that it’s possible to discuss what’s happening on the screen easily and
that the work can flow with as little friction as possible.
The social setup
Not only are the technical aspects interesting but also the social aspects. Two people working on the one problem at the same time definitely changes the dynamics of development; my impression of pair programming for work tasks has on the whole been very positive. Here are some of my observations:
- There is much more discussion. This seems an obvious observation, however it’s very important: if details of development aren’t discussed, then knowledge about the project isn’t transferred, potential solutions aren’t discussed, and it probably wouldn’t be as much fun. I find I try to explain what I’m doing as I type so that not only my colleague knows what I’m doing and why, but also I myself!
- Work can also be a game. We try to make development game-like by swapping between writing tests and writing production code: first one person writes a test for some new functionality, then the other tries to write the minimum amount of code to get the test to pass. This helps ensure that both developers are actively involved in development and that one party doesn’t necessarily dominate by doing most of the coding, or the other doesn’t get bored and distracted.
- One drives, the other thinks. Although both can type simultaneously, it’s important that this doesn’t happen since one person is thinking more or less exclusively about the problem while the other enters code, which leads to questions such as “hey, why are we doing it like that?”, or “wouldn’t it be an idea to consider this approach?”. Such questions stimulate thought and lead to discussion of potentially better solutions for the task at hand.
- Project milestones can be celebrated. Such things like the addition of a new feature, or little things like the first commit to the main repository, or the first push to production can be celebrated, (e.g. with a high-five) giving the feeling that things are moving forward.
- Don’t be a dominant driver. Sometimes one party drives more than the other (often the more experienced of the pair), and one needs to be careful not to type too much; the active, coding part is important for learning and gaining experience.
- Assertive navigation is important. My colleague is very good at stopping me when he doesn’t understand something, which I believe to be a good habit as part of the social aspects of pair programming. By me having to explain the code, the situation, or the concepts, I get to understand the problem and its solution better myself, and sometimes we’ve come up with better solutions, since in the explaining it’s become clear that an alternative way of solving the problem would actually do a better job.
- Have an open mind and be prepared to listen. My colleague often has different perspectives to a problem which I might not have seen and thus the solution space is much larger, leading sometimes to better solutions than I would have thought of alone.
- The development intensity is higher. We tend to code hard out from the beginning of the day until lunchtime and then after lunch until the day’s end. Keeping up this intensity when working alone can be difficult.
- It is still necessary to work alone. Although pair programming is a fun and productive way to get work done, there are times when one needs some quiet time working on tasks alone.
Conclusion
Pair programming is a fun and effective means of getting work done, it aids production of good quality code, and it helps knowledge transfer within a team. Because our setup uses console-based tools, it’s very low on resources (especially network bandwidth). Also, our setup works well both locally and remotely, giving both participants a lot of flexibility in their working environment. I hope it works as well for you as it does for us!
-
It’s fun to say this in German: die Sitzsäcke in der Sitzecke. ↩
Support
If you liked this post and want to see more, please buy me a coffee!
