Show HN: A C# library to help you enforce a Given-When-Then structured Unit test
I always strive to write better, clean and readable code. But I often find unit tests are hard to read, and especially harder to quickly identify what are the important pieces, or even what the test is testing about.
So I came up with this lightweight library to help enforce unit tests with a Given-When-Then structure. I hope you find this useful. Any feedback are welcome.
https://github.com/cobrakai-lab/Cobrakai.GWTUnit
18 comments
[ 0.80 ms ] story [ 57.6 ms ] threadI'm designing an internal library myself that does the same thing using Kotlin's EDSL support (you can specify the "this" type of a function) and splits test logic up into required, act, and provided blocks. E.g.
The interesting thing here is that the polarity of the required and provided blocks can be flipped (check the required is true, and if it is make the provided true) to do fakes/mocks. Well, it is still something I'm working on.https://jakewharton.com/testing-robots/
I also prefer AAA tests, but I can't stand it when people leave those comments in as some kind of region markers. IMO, they're useful when teaching AAA tests, but it seems, in my experience, most developers actually have those comments in every. single. test. That's some hardcore cargo culting.
I just use a blank line to separate the different stages, and if you have problems making that readable, you probably need to refactor the Arrange or Assert parts to use some helper methods.
I realize I'm probably overreacting, but I feel the anger rising whenever I see this in the wild (and have to suppress it).
I generally also advise the leads to make sure there is a reasonable limit to the length of a test method. As you say if it's too long it probably needs some work before it's allowed in the main branch.
I of course mean leaving the comments in the final test. I don't care about the comments in the actual snippet.
Vs "arrange a csv with a missing column act read it assert the exception contains the missing column name"
> If we assume that we use your terms, "Given, When, Then" in place of "Arrange, Act, Assert"
What benefit do these abstractions give me over simply coding an Arrange/Act/Assert?
Tests in larger c# projects are often a mess.
People then turn to BDD or frameworks like to this to try to impose order.
Sometimes they produce better tests the second time around, but more often the additional overhead of the framework just means that "now you have 2 problems".
Probably no benefit, IMHO. Work on your tests, but avoid "high concept" frameworks.
Besides, it's been a while since I did any C# programming, but does it really "enforce" the structure, or only encourage it?
I mean, what's to stop people from going eg.
Putting some declarations outside of the "given" section?If it's just a matter of good will and adhering to the convention, then we're kind of back to square one - if you're a good scout, you could have stuck to the convention even without the extra library.
Unless there's something I'm missing
But when your system is a bit more complex or a legacy, your unit tests are complex, your team is not that mature, not everyone follows good practice, comments does not match with reality or even crunch multiple scenarios into a single tests, asking them to re-write unit test may sounds rude...(guess I might sounds more like complaining now...), but anyway, that is kinda how all of a sudden this idea came to me the other day while I was writing my own unit tests.
My ideas is if my team can adopt this, at least this can help us improve unit test qualities and readability. Then maybe once we become a more mature team, we can ditch the 'crutches'.
One point to note from your introduction was the following statement: I often find unit tests are hard to read, and especially harder to quickly identify what are the important pieces, or even what the test is testing about
Have you considered pairing with others in your team or using group code reviews to see if there is a style or understanding gap? This may be far more effective than trying to get people to use a novel unit testing framework with little or no real longevity.