paint-brush
The Ultimate C# .Net Testing Setupby@sstcvetkov
744 reads
744 reads

The Ultimate C# .Net Testing Setup

by Sergei TcvetkovSeptember 17th, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

NSubstitute(https://://github.com/nsubstitute/Nsubstitute) is definitely a good to be used instead of classic Mook. It has way more nicer API, I can't stop recommending it to my friends. Faking data almost every time I write a test I have to fake some data for it. There are a special libraries which can do better). Addressees or people names, phone numbers and more. They cat take that pain work from you.
featured image - The Ultimate C# .Net Testing Setup
Sergei Tcvetkov HackerNoon profile picture

Base testing frameworks

Basically, we need to ability to write test classes and methods and have the base infrastructure for them. I mean some test explorer with run state info. There are 3 classic frameworks:


And most popular nowadays is xUnit, providing a more object-oriented approach. These ones are very similar, so, don't worry, if you experienced one, you'll be able to use any other.

As for me, I can't call non of them perfect. I believe somebody we create a more customizable one.


Assertion

Every base test framework has its assertion methods, but in a usual way: Assert.AssertMethod(DataForAssertion).


If you haven't already tried the inversion of control approach, I definitely recommend you FluentAssertion library, which will allow you to write your assertion like this: DataForAssertion.Assertion() and use tons of extension methods.


Faking data

Almost every time I write a test I have to fake some data for it. If it's a simple-no-matter-string it's probably ok to drop your fingers on the keyboard to write some “bla-bla-bla". Meantime there are special libraries which can do better). Addresses or people's names, phone numbers, and more. They cat take that pain work from you. One such library is Bogus, which can fake almost everything. I recommend you also check out the AutoFixture library, which can automate arrange object construction.


Snapshot tooling

Assertion of complex objects may be complex, there are several tools that can help here. And I use Verify. It can serialize a test object result, store it locally, and compare it on the next execution with the new one. It's a flexible tool, and of course, has to compare settings.


Mocking

When we want to unit test some type that has a dependency, some repository, for example, we need to mock it, to deal with only the code we want. Long time using Moq was the almost only simple way to do that, and I still can recommend using it. But as time goes on, a new library with a more convenient approach came out. So, NSubstitute is definitely good to be used instead of classic Mook. It has a way nicer API, I can't stop recommending it to my friends.


Built-in libraries for API testing

Although they are kinda built in, have to mention these two libraries. WebApplicationFactory type allows you to have an HTTP client for your ASP web app which is best for testing it. You can mock every dependency from IOC and even more. The second library provides a default set of APIs for building an ASP.NET Core application.

Microsoft.AspNetCore.Mvc.Testing Microsoft.AspNetCore.App


Stubbing

Testing an app, especially a microservice, tightly coupled with external services can be hell without stubbing. WireMock.NET provides you with a nice API to do that, providing an ability to return predefined HTTP responses for requests matching criteria.


Acceptance and BDD scenarios

Specflow is a great choice to write acceptance tests and BDD scenarios. It provides core functionality to write automated tests on human-kind language, making them understandable and supportable to all team members.


UI web testing

To test web pages we need to imitate users' actions. Selenium was the only choice for a long time. Providing an API to web browser(all popular ones) UI, allowing making clicks, text input, and so on.


Playwright is a newcomer offering faster speed and some modern interaction - modern choice.


Containers

Testing integration with external big apps, such as a database, may be inconvenient if you are restricted by only one instance of that app. So TestContainers makes it way easier to set up multiple, isolated instances, providing a Docker API.


API Load Testing

It's a huge topic, but let's take a look at one nice instrument, which is developer friendly - Grafana k6. It allows you to write simple JavaScript ES2015/ES6 config for testing do response checks and thresholds.


Coverage

How many code branches do all your tests check? How many they should have? Generic best practices tell us that your test coverage percentage should not decrease from release to release. There is nice lib called Coverlet to collect all data. Although 100% coverage usually sounds like a utopia or needless luxury, it's good to know about the percent tendency. So basically talking - do we help QA or not?


Test testing

If you're not familiar with mutation testing, you should definitely check Stryker.NET. It allows you to test your tests by automatically changing source code, and trying to imitate real code changes. You may be very surprised how dumb your tests may be.


Testing till THE END

No more testing libs from me, just want you to remember that testing has no end) We should chase relevant product quality instead of implementing all kind of tests that was ever invented. Hope these libs help you to do that!