DEV Community

Why I don't use a third-party assertion library in Go unit tests

Yawar Amin on May 20, 2024

TL;DR: I don't need it, and you probably don't either. I'll explain below. As we know of course, Go ships with a built-in unit testing framework i...
Collapse
 
bcamphart profile image
B. Camphart

My philosophy is to not introduce any external dependency until I absolutely need it. Creating a small assertion helper function that you have total control over is better than pulling in a dependency that you have no control over. Until the project absolutely needs all the extra features that an external dependency provides, it's more maintainable to roll out simple functionality yourself.

Collapse
 
alaindet profile image
Alain D'Ettorre

I wrote my assertions too until I moved to another project and had to copy-paste them all. Testify is great, it's worth it.

Collapse
 
antoine_toussaint_05992e5 profile image
Antoine Toussaint

Why would you care about adding an external dependency for your tests? They won't even be included in your runtime binaries.
The point is that your own implementation will cover a lot of test cases (99%) but when you get to that 1%, then you have to add the external dependency anyway so all the work you did before goes in the trash.

Collapse
 
yawaramin profile image
Yawar Amin

It's not just about how heavy the runtime binary is, it's also about how much third-party code I am depending on. By introducing a new dependency, I am now relying on a third party's unpaid efforts. If I can avoid that with less than 15 lines of code, why shouldn't I?

Sure, I might end up needing more advanced assertion libraries. But why borrow problems from the future? If I need something in the future, I'll use it. And nothing is going to go 'in the trash' because I'll just keep using my own assertion whenever possible anyway.

Collapse
 
antoine_toussaint_05992e5 profile image
Antoine Toussaint

You say "By introducing a new dependency, I am now relying on a third party's unpaid efforts."
which effort? What fact do you have to back it up? Maybe I am wrong, but you make strong points and they need proof.

Thread Thread
 
yawaramin profile image
Yawar Amin

What facts and proof are you looking for? When you use an OSS library maintained by someone, that person has to spend some effort to maintain the project–writing code, triaging issues, responding to queries, doing code reviews, tagging releases. The OSS doesn't magically maintain itself out of thin air.

Thread Thread
 
antoine_toussaint_05992e5 profile image
Antoine Toussaint

So you don’t rely on OSS at all?

Thread Thread
 
yawaramin profile image
Yawar Amin

Of course I rely on OSS, as almost every developer does. But I want to be able to pick and choose which OSS I rely on and I want to reduce my dependency surface area as much as possible. If I can get 90% of the benefit of a third-party library with less than 15 lines of hand-written code that I know like the back of my hand, why shouldn't I just do that?

Collapse
 
psydvl profile image
Dmitriy P

So, you don't use third-party assertion library just because you wrote new one by yourself

Collapse
 
ccoveille profile image
Christophe Colombier

I thought the article was about using fmt.Println + // want: whatever

But no 🤔

Collapse
 
duongphuhiep profile image
DUONG Phu-Hiep

it is a not true that assert.Equal cover 99% of Go unit testing needs! Let's compare it with for example "assert.Panic": only 1% test case used "assert.Panic"...

However 99% of the projects need "assert.Panic", evens for 1 or 2 calls (similar to other assert.True, assert.Nil, assert.Empty...)

when your co-worker comes to your project and need "assert.Panic". He/She will conveniently uses the testify/assert and throw away your "home made" assert. As 99% Go project needs "assert.Panic, assert.True.." There 99% probability that your assert will be throw away...

your point of reducing dependency surface is reasonable but choose assert library to show case the point is just a bad example

Collapse
 
yawaramin profile image
Yawar Amin

Dunno what to tell you. The Go standard library's testing package doesn't provide an assertion for 'panic', and I've never needed one. Or in other words, I've never needed to trigger or test for a panic. It's a crash condition; testing for it is imho missing the point. But I have found that almost every useful assertion can be expressed in terms of comparing two strrings, which covers my 99% cases.

Collapse
 
duongphuhiep profile image
DUONG Phu-Hiep

If your application have never call the "panic()" function then it is fine, you don't need "assert.panic()" in the tests.

However if your app calls panic() somewhere, and you didn't have test to cover this call then you are missing the test, it shows that Your tests covered only the "happy path", you didn't write test for the edge cases which make your application call the panic function and crashed.

Most of my application call panic somewhere and I have test to cover this case. The test make sure that when the situation happen, then the application would panic instead of running in an unpredictable condition.

Thread Thread
 
yawaramin profile image
Yawar Amin

No, I don't directly call Panic() in my applications and I don't think it's a good practice to do it either in application code. Panic should immediately crash the app; the fact that some libraries catch panics is a design decision that they made and it is their responsibility to ensure they are using it safely. I have no control over that and I don't test code I don't control.

If I made a library that caught panics, then I would test it as such.

Collapse
 
dehypnosis profile image
dehypnosis • Edited

it seems that you wrote a tiny testify by yourself. why?

Collapse
 
antoine_toussaint_05992e5 profile image
Antoine Toussaint

By writing your own thing instead of using well-known, quasi-standard way of testing, you also hurt uniformity and ease of collaboration since people have to learn your API instead.

Collapse
 
yawaramin profile image
Yawar Amin

So just to clarify, are you making both arguments at the same time:

  1. My assertion function is too simple and won't cover the last 1% of test cases that might be needed
  2. I am placing a heavy burden on my team to learn this one simple, well-documented, self-explanatory function

?