Deliver your software, don't just write it.

Development teams have a nasty habit of writing too much code and putting aside testing and code review.

The Anti Pattern A common agile anti pattern I see is tasks piling up on the right hand side of boards. These tasks are waiting on another developer or team member to take some action. They may, for example, need to be subject to a code review or testing before being deployed or merged into the master/delivery branch.

When I look at the disposition of the developers both myself and those that I have worked with I am not surprised at this behaviour. We as a collective group love to build things, the joy of breaking down a problem, fixing a bug or seeing what's in our heads come to life on the screen is amazing. Contrast that with the feeling of digging through code developed by someone else. Potentially telling that developer that what they've done needs to be tweaked, that you've found a bug or that you disagree with the approach that they've taken. This at least f…

How do you find conferences to speak at?

Ahead of the Global Diversity CFP Day that I and some others are organising in Newcastle I was thinking of what questions I'd ask. A question that has always bothered me is how do speakers find out about conferences in time to submit a proposal?

I went to Twitter to see what help I could get from the wider community.
For those of you who speak at dev conferences in Australia how do you find out about conferences and CFPs? Asking for me but also to tell people next week at @gdcfpday. — Klee Thomas (@kleeut) January 9, 2020
The answer I got from people on Twitter was largely to follow some accounts on Twitter.

For ease I've combined these into a Twitter list

The other suggestion was to follow conferences that you're interested in on Twitter.
I've also got a Twitter List for conferences. By virtue of the fact that I'm…

Testing functions that use local storage with Jest

Testing functions that use the browsers local storage API seems easy when you know how. Here's a quick run down on how to mock it out with Jest if, like me, you're not familiar with how to test it. In the end it's very little code. Consider the following TypeScript code.

import { get, save, key } from "./storage"; describe(save, () => { let setItem: jest.Mock; beforeEach(() => { setItem = jest.fn(); Storage.prototype.setItem = setItem; }); it("should call set item with predefined key and json object", () => { const valueToStore = { value: "toStore" }; save(valueToStore); expect(setItem).toHaveBeenCalledWith(key, JSON.stringify(valueToStore)); }); });
The key lines are in the beforeEach call where the setItem function of the Storage prototype is assigned to an instance of jest.fn(). This allows us to make assertions on what is passed to the local storage setItem API.

JAM stack: Deploying a S3 website form commandline.

Hosting the client facing page is an important part of creating a performant JAM stack app, To do this I will be using Amazon's AWS S3 offering and the AWS CLI.

From here I will assume that you have the AWS CLI installed and have it configured to use an account that is capable of creating and configuring S3 buckets.
I'm using Powershell emulated through cmndr on Windows as my command line.
Create the bucket The first thing we need is to create the bucket. If every thing is fine it will look like this. 
(replace kleeut-jamblog with your bucket name, they need to be unique)
aws s3api create-bucket --acl public-read --bucket kleeut-jamblog --create-bucket-configuration LocationConstraint=ap-southeast-2 { "Location": "" } Gotchas: The error messages are pretty good, these are the ones I've commonly run into.

If you're already run the command or for you own the bucket you'll see:
An error occurre…

100% code coverage is false safety

It is really easy to lie to yourself when doing Test Driven Development that your code is good, safe, predictable and well understood, just because you have that magic 100% code coverage number.
If you test just the happy case it is easy to get to 100% code coverage, while still leaving code paths untested and unexpected behaviour unexplored.

Consider this simple function that takes in an object with 2 properties, an array of strings and a separating string to concatenate between them.

1: export const concatStrings = ({ strings, joiner }) => { 2: return strings.join(joiner); 3: };
Testing the Happy Path is really easy.
1: import { concatStrings } from "./stringConcat"; 2: describe(concatStrings, () => { 3: it("Should concatinate strings", () => { 4: const actual = concatStrings({ joiner: ", ", strings: ["one", "two"] }); 5: expect(actual).toBe("one, two"); 6: }); 7: })…