How not to fail the "take home" test
Tags: javascript, hiring
Published: 2020-07-03 12:50:46

As a senior dev I have done take home tests multiple times and I have also graded them. Every place has their own criteria, so no _universal truth exists_, however I can give you some ammo for nailing the task.

In these types of tests you are usually assigned a small engineering task (make a todo list in X technology) to do in usually a week. The aim of this is (and should be!) to see what the **candidate thinks about maintainable code**. However these types of tasks take a long time which leads to my **first tip**:

> If you already have a project up on GitHub that shows your chops, you can try to convince the recruiter to take a look at that.

The place I currently work at accepted my code written for another assignment. The key was being _polite and assertive_ while still _leaving open the option_ that I can do their particular assignment. But since the task was ready and they did not need to wait, I saved theirs and my time. Win-win.

## Make your work visible
One of the worst things when you grade a test is the ambiguity: is this smart looking stuff was written by the candidate or inherited from a good template?

> After the initial working commit (preferably with green unit tests) **create a branch** which contains only your work over the template. Then share the link for the closed **pull request**.

To give you an example, I did this for a company: https://github.com/latobibor/icf-homework/pull/1

They could see exactly what I have written for their assignment.

## Less is good, but it also should look great
If they want _unit test coverage_ it is OK not to cover every line. That is a lot of _unpaid_ work! However writing just a couple of snapshots test for **React** is _no bueno_.

So get a _decent coverage_ over a _small amount of files_. Strategically cover parts of the application:
- these are my detailed unit tests for the business logic in this file
- these are exhaustive UI tests for this important UI interaction
- these are a couple of API tests to see if the data is actually committed to the DB
- ...

And so on. The task is to showcase your testing style, that you _understand what good tests are about_.

The same applies to **clean coding**. Make sure you have some very neat files and do not forget to mention in your answer letter or in the `Readme.md`.

I usually set up `prettier` part of my initial commit. From that point on I will be sure that my code also looks neat without giving much thought.

## Communication is - as always - the key
As I have mentioned above, the aim is to see your coding skills, therefore many limitations of the take home tests are flexible: given you have very solid reasoning.

> Therefore it is very important to give a reasonably long disclaimer when you submit your work _pointing to strength of your work_ and _giving explanation to its weaknesses_. 

I would say the "softer" side of your explanation should be featured in a reply email while the technical stuff should be in your [Readme.md](https://github.com/latobibor/icf-homework/blob/master/README.md) file (link is my own example):

![Explain your decisions in Readme.md](https://dev-to-uploads.s3.amazonaws.com/i/cfo0fh1dy71vn8wqxykn.png)

_Example: explaining your decisions_

**In concretion:**
- Never forget to _thank them_ for the opportunity and the time spent on grading your work.
- The usual take home test is built on a template, so make sure that you help the graders _point_ to the most important source code files.
- Make sure to _detail_ how your take home test can be _tried out_. _(A bit more on this later 👇)_
- If you have _deviated from their specification_ give a good explanation.
- Be _upfront_ about the possible **known issues** and why you could not fix it - there's a good chance the graders will find it, and it is a sign of a mature developer to make a note about these.
- If possible ask them to _give feedback_; even if you fail the task you can learn something from it.

With the graders knowing where to look and what to check it is time to introduce another important factor:

## Your code should work out of the box
Usually this is how I expect take home tests to behave:
1. I need to run `npm i` for dependencies
1. And then `npm start` for the ability to try it
1. Finally `npm test` for checking the tests written

Now onto the list of what I see as red flags and my reasoning behind them.

### ⛔️ It does not run out of the box
This one is obvious, yet I frequently run into this: it just doesn't work.

To make sure it works clone your repository in another folder, do a clean install of your dependencies and run your app. Also...

### ⛔️ I have to install global packages 
Your global packages should be CLI tools only for things like creating a new app (e.g. `create-react-app`). 

It is usually a _bad engineering practice_ to rely upon this. Why? It is not documented in the `dependencies` part of `package.json` so it is _very easy to forget about them_, and also not included in `package-lock.json` which will lead to the "it works on my machine" shrug.

Now imagine that you have to grade 10 take-home tests a week and now you need to install all their global packages. Come on...

### ⛔️ Setup is too long or not documented
Setup is a tell-tale sign that an engineer will take care of the developer experience of their colleague or not.

> And developer experience means productivity!

Having worked in a company with the _weak ownership model_ (i.e. anyone can create a pull-request to anyone's repository) I realized how insanely important is having a well-documented easy setup. And as such I no longer wish to work with people who I need to nag for their arcane `bash_profile.rc` configurations.

### 😅 Easy on the experimentation side
Take-home tests are usually taking a substantial amount of time, so there is the desire to learn something new about it. However with new things there is a higher chance you are running into the **hateful spiral**; a day wasted on chasing an error message that leads to another.

My advice is if you are introducing a new lib/tool into your work is to do it in a _fresh, separate commit_. So worst case scenario when you are under a lot of stress you can safely _revert to a working point_.

However if you do have the time (for example you are in-between jobs) then...
> 👍 Take home tests can be valuable **learning opportunities**!

Wanted to try out [Overmind.js](https://overmindjs.org/) instead of `Redux`? If you have a knack of extra time now it is your chance!

### 💪 Great templates are life savers
I cannot stress how important is start your work with something that already **works out of the box**. This is especially true for UI projects: the fact that I could see a piece of fresh UI minutes after I started working on an assignment is a huge productivity and morale boost. And you gonna need them both 😉.

So this is not the time to start experimenting with new build scripts.

-------

The key takeaway of my little list is to realize that your take-home test is the **holistic showcase** of you as engineer, including your _coding chops_, your _ability to communicate_ and your willingness to _do the extra mile for the team_.

Good luck with those job interviews! :)