❔ Tests best practice
Hello I'm interested in learning more about testing in general like unit tests and other kind of tests
I try looking at guides online, but they all show really bad examples that are not just not real.
I would like to unit test my ASPNet Api's database logic that seems to need mocks, but should controller be tested? Like if we have
ProductController
with method CreateProduct(Request)
do we test this or just logic inside it? Like services/Repos
Does the testing of API fall under different kind of tests like E2E testing for frontend46 Replies
I'm very interested on how we should approach testing one full production system
and how should I structure my tests
Also I'm confused on how we should test List of results for example if we have a method that fetches something and creates result of tests it seems annoying to test.
Also how do we go about testing a third party lib?
In general we should not test other libs as it is expected for them to already have been unit tested that I understand, but what if my logic depends on it
Like Discord bot in C# I would like to test outputs of my commands I would need to mock these
I would be very happy for any additional resource in this thanks.
generally controllers are tested as part of your integration tests, not strict unit tests
you'll want to look into
WebApplicationFactory
https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-7.0 to learn more
why is this annoying to test? you'd set up mocks or a test database with a known dataset so you know exactly how many items should be returned
you then assert that the items returned are the ones you expect.
my number one advice for people learning to write tests is to throw Assert.X
in the trashcan where it belongs and install FluentAssertions
or Shouldly
and use their fluent assertion style which is MUCH nicer to work with and also generates MUCH better error messages when the assertions failI see thank you for the info
I will check it out
What about discord bot example
I use Dapper not sure if there is in memory integration I'll have to check
I would need to create mock implementation of each repository
Not as such, but it doesn't have to be.
sqlite is an excellent database for testing
or use a test container
thats the best solution
Ye some sort of test database
yep
and that way you can use the same database provider and version as you do in production, so you dont get dialect issues
regarding the discord bot, it depends heavily on what bot framework you use and how it works.
It would just need some setup and tear down setup
yes, and there are libraries/tools to help with that
TestContainers being a very common one
Any personal recommendations?
regarding what?
Libs for previously mentioned
https://dotnet.testcontainers.org/
this is excellent.
I'll check it out
Integration looks very close to E2E with some selenium
I guess we do both tests? One for API route and other for web
I have react frontend
Backend is c#
Part of your FE tests could actually run on a complete FE+BE setup and do true E2E testing, sure
Looks bit annoying to http call each route, but I think swagger code generated can help with that
I'm a backend engineer thou, so I wouldn't touch selenium or FE at all
using WebApplicationFactory to test your actual API routes is important, because you want to test the ASP.NET pipeline with any middleware you have attached
and general httpcontext things
Yep
I understand
Also, where should I place tests ? In solution like Tests folder then Unit, Integration, E2E
Do you utilize code gen for http calls ?
Testcontair seems nice to do e2e and integrated I can spawn and run all tests then kill it
Also, what do you think about deployment? Should all types of tests run before. Same for commit protection
commit protection, absolutely not
part of CI? yes
ie, any pull request needs to pass at least UTs before it can be merged
maybe also integration
E2E depends on how heavy your tests are
you might just run that nightly or something
you dont want a 20 minute test period to be initiated for every single commit, as that will
1: be very expensive
2: lower your throughput
Ye
we run a nightly with all bells and whistles, and unittests + convention tests on each CI
and then devs are supposed to locally run whatever tests are related to their work before submitting a PR, but that often gets skipped to be fair
What would be Api and domain tests
If you do not mind explaining
well, it was just random project names
but the idea is that most solutions are way more than 1 actual project
and you want to split your projects/tests in the same way, so you dont have to rebuild the entire app for every tiny change
I split backend and frontend into 2 repository. So test would not be in 1 place
I think I should have some kind of mono repo for it
no but even just the BE is likely split into more than one project
screenshot from workcomputer:
each of these have their own test project too, in the
tests
folder you can barely see at the top
and we have some extra test projects too, like Integration and Convention
our E2E tests are not ran by xunit, so we have them elsewhereI see
Any, how would you approach it
as I said, depends on the framework
if you can easily mock the input and assert on the output, great
just do that
but if not, you might need to have your registered bot commands actually fire of a simpler command or testable method from another class
just so you can test it
this would be nasty, so hopefully your framework of choice has decent testability
Probably something with TestContainer
?
how would that work
iirc you can't set up a fake discord and run E2E tests on a discord bot
or rather, you probably can but its likely quite complicated
We can use test bot though
Testing sharding would probably not happen, though. That sounds too annoying to make
I have projects that scales it but that I can probably fake memory objects and test like that fire fake events and messages
I've only built a fairly basic discord bot, and I didn't bother testing its commands directly, but rather the custom command dispatcher I built into it
this was a few years ago now
The issue I have is that some stuff seems too difficult to properly test.
For example, I built a distributed autoscaler that creates containers
How do you even test that.
My first idea is to create a whole new project to mock discord events I expect.
Use test containers env then fo some kind of integration test
We can have both full as real as possible test and fake memory test where we mock api that returns container
If we only do memory, we can test logic, but expects other mock api to function properly
Not everything is easily or sometimes even at all testable.
Distributed autoscaler is testable, imho, but hard. You'd need a way to simulate load, and have each node it spins up report some information to a test controller of sorts
How far should I go about testing it for example
Should I go as far as really try to replicate nodes
Or only logic testing with memory mocks
$itdepends
super unhelpful answer, but also very true
100% or 99% test coverage is generally speaking a meme
its not attainable in any useful way
test stuff that is complicated, or gets changed frequently
try to find appropriate abstractions
Damn
Yea seems for these systems in a small team tests will cost a lot more
Like not everyone is testing Devision methods
A lot more infrastructure required to test
unittests is a good place to start
they are usually fast and you can test your core logic
if part of your core logic is things like stored procedures etc, you'll need to go a level higher
Yeah, it is better to have something than nothing at all
I think I'll start with only being concerned about logic
It seems quite time-consuming to test anything that is larger that is just maybe not worth it
Idk
I think test env can help with this with information I have so far
yes
I'll test those like so
Ty for your help
Really helped me.
I'll study more on materials you sent
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.