Think about your dependencies

A little copying is better than a little dependency, says Go proverb.

Go has a huge standard library, which has support for many, many things. I think many developers, don’t utilize it fully. I mean I have seen many new gophers try to use packages for everything. For example, do you really need a dependency on github.com/stretchr/testify ?  If you are just using assert, maybe you can just can copy the assert function from benbjohnson/testing? Ben Johnson has  published these convenience functions (MIT license):

func assert(tb testing.TB, condition bool, msg string) 
func ok(tb testing.TB, err error) 
func equals(tb testing.TB, exp, act interface{}) 

If you are using the TestSuite stuff, maybe you can just avoid it entirely? The same goes for all the cool HTTP muxes. It’s cool, but if you don’t have a lot of endpoints, maybe you can just avoid that dependency and use standard library’s http package.

But why am I against dependencies? Well, for new developers learning a new language is a lot, if you complicate this by adding custom packages and frameworks it will be harder. And it will be harder for you too. If you get back to a project after a break, you will notice that you have to relearn the dependencies you have used.

With less dependencies you will spend less time managing them. Once, I spent 3 hours fixing a dependency problem with Glide. The problem was that one of my dependency (let’s call this dependency A) had a dependency on an older version of a package C and another dependency (let’s call it B) had a dependency on a newer version of a package C. The biggest problem was that package hadn’t used semantic versioning, so I had to try random library C commits and try to get this thing working… After doing that for an hour, I took a break and realized, that I can easily rewrite the code and remove a dependency on B.

But aren’t packages from standard library are dependencies too? Well yes, but by utilizing the standard library, you are learning the language. You will start to remember public functions, structs and interfaces, after awhile. Also, Go has version 1 compatibility guarantee, that means that standard library’s API won’t break down on you, for go 1.* versions.

Of course don’t go and reimplement Go MySQL driver or anything crazy like that. Just think before adding another dependency!

That’s all from me. Do you enjoy these articles? Follow me on twitter @PofkeVe and join my mailing list 🙂

Unit tests

Probably you have heard many advantages of unit testing such as getting bugs out of the code, producing better code design, having overall good code quality. But for me it’s all about reducing the fear of making changes in production. It gives me confidence in my code so that my new code additions didn’t break something. Also it shortens the development-testing cycle, which allows me to always publish code which works.

It’s important to distinguish unit tests from other kind of tests. If you put all kind of tests into same place it quickly can become a mess: some tests run slowly, some require testing database, a queue or other external dependency. At least in my company people don’t have a clear understanding what a unit test is and so we ended up with ice cream cone anti-pattern, where we have many end to end tests, a lot of manual testing, zero unit tests and few integration tests. Why this pattern is an anti pattern you can read in this blog post from Google testing blog.

So, what is a unit test? There are many different definitions what are the unit tests, I tend too look at them as the low-level tests, that test a single unit: function call, method, class or a group of classes. These tests should run quickly, use test stubs or mocks for external dependencies, so that they should test only the system under test and not the external dependencies. These tests are really really fast. you can run thousands of the in a second or two.

Lastly, I wanted to share some cool articles about what is and what isn’t a unit test: