Image for post
Image for post
Photo by Nick Fewings on Unsplash

I’m a big fan of TDD. BDD has always been a bit elusive to me in the sense that I wish I could use it more often. However, I always seem to end up struggling to express the same nuances through BDD that come effortlessly through a standard test case.

Truth be told, I have’t touched BDD in a while. However, this question has been bouncing around my head lately:

Why is it often so difficult to express simple systems through BDD?

Code based tests are really good at describing how we complete a task. BDD is really good at describing what a task is trying to achieve. …


Image for post
Image for post
Photo by DDP on Unsplash

Go’s error handling is very explicit. It can also be very verbose compared to other languages. I want to talk about how we can minimize the need for explicit error handling by separating what are expected and unexpected errors.

Expected Errors

An expected error is generally something you can test/check/verify ahead of time or that would not have a detrimental effect on the system. Some examples of expected errors are:

  1. Validating an email address from an input.
  2. Verifying that a user has access to a certain part of the system.
  3. Retry on a known flaky or slow API endpoint.

Expected errors should always return an error. This lets the caller decide what to do in this case. It may want to bubble the error up, or it may choose to bail out of the current operation. …


Image for post
Image for post
Photo by Javier Allegue Barros on Unsplash

Go does not have any concept of enums like some other languages. There are arguments for and against this approach which I won’t go into here. However, there are times when you want to check that switch statements contain all enum values. Especially if you intend to add new enum values in the future and want to catch existing code that now needs to be updated accordingly.

For this, I developed a tool called switch-check. It’s a zero dependency, zero configuration CLI tool for doing just that. You can try it right now with:

go get -u github.com/elliotchance/switch-check
switch-check

Or, here is a quick…


Image for post
Image for post
Photo by John Schnobrich on Unsplash

It’s a common scenario — for me at least — to be building a CLI tool (main package) that has CLI options (flags package) that I want to add unit tests to.

Here’s a simple example of a CLI tool that adds or multiplies some input numbers:

Let’s try it:

5 + 7 + 9 = 21 — great… But wait! 3 * 2 * 5 != 0…I’ve put a deliberate bug in the command. Something that we will catch and fix with a unit test.

Don’t Try This At Home Kids

Let’s write a unit test that uses the same CLI arguments so we can fix the bug. However, we have a lot of global state that needs to be…


Image for post
Image for post
Photo by Levi Jones on Unsplash

If you need an in-memory, functional SQS client during unit tests you can now use github.com/elliotchance/mocksqs.

Getting Started

The simplest way to create a new SQS service is with mocksqs.New(). However, if you need queues prepopulated you can use mocksqs.NewWithQueues():

Wherever you pass around an SQS client in your application, you should use the sqsiface.SQSAPI interface.

Supported Functionality

Only some of the common SQS methods are implemented. Methods not implemented will panic.

You can view the specific implementation details in the godoc documentation.

Events

Functions can be set on queues to help with unit testing life cycle. For
example:

See the documentation for Queue for more information.

Simulating HTTP Latency

When enabled a sleep between 20 and 100 milliseconds is added to each call that would otherwise need to make a HTTP request with a real SQS client:


Image for post
Image for post
Photo by Jonah Pettrich on Unsplash

An ordered map (also called a linked hash map in Java) is a data structure that allows amortized O(1) for access and mutation just like a map, but the elements maintain their order.

For this I created the github.com/elliotchance/orderedmap package. Here is some basic usage:

m := orderedmap.NewOrderedMap()// Keys and values can be any type.
m.Set("foo", "bar")
m.Set("qux", 1.23)
m.Set(123, true)
m.Delete("qux")value, exists := m.Get("qux")

The most important feature of the *OrderedMap is that the order of the keys is maintained, so that we can iterate them in their creation order:

for _, key := range m.Keys() {
value, _ := m.Get(key)
fmt.Println(key, …


Image for post
Image for post
Photo by Florian Steciuk on Unsplash

Go ships with great tools for runtime performance monitoring. However, for one of the projects I am working on I needed tailored metrics around three channels that do the primary communication between the larger components of the processing service.

I wanted to be able to print realtime stats on movement and blocking of these channels only each minute. So I created ChannelPerf :

https://gist.github.com/elliotchance/7db9eb40a935f5526b62f0bcf77b7d2c

How does it work?

For the most part it is a drop in replacement-ish with how you would normally use a channel:

// ch := make(chan interface{}, 1)
ch := NewChannelPerf(1, "Some name")
// ch <- "foo"
ch.Send("foo")
// next, ok := <-ch
next, ok :=…


Image for post
Image for post
Photo by Franck V. on Unsplash
start:
display "Hi, I'm bento."

What is bento?

https://github.com/elliotchance/bento

bento is a forth-generation programming language that is English-based. It is designed to separate orchestration from implementation as to provide a generic, self-documenting DSL that can be managed by non-technical individuals.

Wow, what a mouthful… That’s a bunch of fancy talk that means that the developers/engineers can setup the complex tasks and make them easily implementable by non-technical people through (almost) plain English.

The project is still very young, but it has a primary goal for each half of its intended audience:

For the developer/engineer: Programs can be written in any language (called a backend) and easily exposed through a set of specific DSLs called sentences. …


Image for post
Image for post
Photo by Perry Grone on Unsplash

There are some cases where you need to read enough items from a channel to begin processing. However, you also want to a TTL to expire with a smaller batch if there are not more items for a while.

Here’s an example of streaming a channel of string into an output channel of []string that guarantees:

  1. Each batch contains at least one string.
  2. A batch will never contain more than maxItems.
  3. If there is at least one string to be read at any given time, it will always send a new batch within maxTimeout .
  4. A batch will contain less than maxItems if maxTimeout has occurred since the the last batch finished (not since the first item in the batch). This is important because it means that if the stream is scarce and infrequent — such as one item per maxTimeoutBatchStrings will prefer to send a consistently timed batch of one item rather than more volatile intervals that might contain two items. …


Image for post
Image for post
Photo by Goran Ivos on Unsplash

I like Go. I don’t like JavaScript. So I posed the question…

How could I write a reactive single page app without using the JavaScript or it’s ecosystem?

Here’s what I came up with:

package mainimport "github.com/elliotchance/pepper"type Counter struct {
Number int
}
func (c *Counter) Render() (string, error) {
return `
Counter: {{ .Number }}<br/>
<button @click="AddOne">+</button>
`, nil
}
func (c *Counter) AddOne() {
c.Number++
}
func main() {
panic(pepper.StartServer(func() pepper.Component {
return &Counter{}
}))
}

That code encapsulates the entire stack. If you have Go installed, you can try it right now:

go get -u github.com/elliotchance/pepper/examples/ex01_counter…

About

Elliot Chance

I’m a data nerd and TDD enthusiast originally from Sydney. Currently working for Uber in New York. My thoughts here are my own. 🤓 elliotchance@gmail.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store