xUnit or NUnit? Picking the Right Testing Library

  Рет қаралды 44,954

Nick Chapsas

Nick Chapsas

Күн бұрын

Check out my courses: dometrain.com
Become a Patreon and get source code access: / nickchapsas
Hello everybody, I'm Nick, and in this video, I will explain why I prefer xUnit to write my tests instead of NUnit.
Workshops: bit.ly/nickworkshops
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasGitHub
Follow me on Twitter: bit.ly/ChapsasTwitter
Connect on LinkedIn: bit.ly/ChapsasLinkedIn
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер: 168
@nickchapsas
@nickchapsas 10 ай бұрын
Ok looks like I need to make a video on MSTest
@alexisfibonacci
@alexisfibonacci 10 ай бұрын
Why you shading MSTest?
@toddosty
@toddosty 10 ай бұрын
@@alexisfibonacci Lots of people think MSTest is still v1, and not the replacement V2 from nearly a decade ago. Doesn't help when prominent community members preach against it for no reason, either.
@b33j4y
@b33j4y 10 ай бұрын
@@toddosty I never heard it mentioned in a negative light until I watched this.. I thought all 3 were identical TBH. They.. run your tests..
@KibbleWhite
@KibbleWhite 10 ай бұрын
Please make a video on MSTest, explaining the pros and cons please. I'm using MSTest, because I feel it is all we need right now. Many thanks Nick, great content as always :)
@kpamafrederic6558
@kpamafrederic6558 10 ай бұрын
Yeah I also shaking to know what's the problem with MS test?! That's my default when it comes to test
@local9
@local9 10 ай бұрын
Wait, you guys have Unit Tests?!
@davidrettenbacher5507
@davidrettenbacher5507 10 ай бұрын
I used NUnit for many years and it served me well. Now, in my current team we switched to xUnit because "it's the unofficial successor of NUnit". The more C#-native syntax is nice and for unit tests it's very handy. Syntax, Async and Shared State... But when you want more than simple unit testing, then it's not so "clean" anymore. If you need async initialization you have a problem, as C# does not support async constructors. So you need IAsyncLifetime (more in a second). If you need async disposal, you would think you can use the C#-native IAsyncDisposable - no, not supported, use IAsyncLifetime, but then you also must implement a InitializeAsync() that you may not need (it's the same the other way round). (An interesting future issue may be that IAsyncLifetime has Task DisposeAsync(), while IAsyncDisposable has ValueTask DisposeAsync()) If you want to setup code that runs before all (or a set) of test classes (eg. shared infrastructure setup), then extra classes, attributes and magic strings are required (keyword: "Collection Fixtures"). So the (for me) primary selling point - lean, C#-native-syntax - quickly comes to its limits and falls back requiring some framework-specific (and not so obvious) procedures to get around that, which are sometimes solved "nicer" elsewhere, IMHO. Leaving Unit Test Territory: Integration Tests One thing, that got me by surprise was that xUnit does not play well with integration tests + limiting parallelism. This was/is discussed in this issue: github.com/xunit/xunit/issues/2003#issuecomment-1426388783 . This issue was closed because "it works as designed" and "xUnit is designed for [real] unit tests" (paraphrased). An DDoS-ed test infrastructure causing random timed out tests may be the result. This I wished I would have known earlier, because I don't want to use more than 1 test framework in a solution - I want one that can handle all kinds of tests and has me officially covered. Visual Studio specific Issues When using slow starting xUnit Collection Fixtures, the test explorer does not count the Collection Fixture startup in the test duration. For example, if an integration test starts up a infrastructure Docker Image (TestContainers), this takes about 10s, but the explorer only shows 0.5s after the run because the actual test method only took 0.5s. This is misleading. Also, the current xUnit Visual Studio (2022) test adapter does not fully support inherited tests (testing 2+ implementations with 1 set of tests to ensure all implementations behave the same). Those tests work and the Test Explorer UI shows them correctly - but double clicking on such a test doesn't open anything (it should open the test-source), which is annoying. Conclusion In new projects I will use NUnit again, because in my experience ... it just works, has good documentation and is well integrated in Visual Studio and the like. PS: Instead of the built-in assertions, in the (many) last years I only ever really used FluentAssertions which is just a joy for writing assertions. And it works for many test frameworks, including xUnit and NUnit.
@collegatore
@collegatore 3 ай бұрын
Thank you for the elaborated overview and knowledge sharing, almost as much value as the video itself.
@szelpe
@szelpe 2 ай бұрын
This comment needs more likes :)
@amirhosseinahmadi3706
@amirhosseinahmadi3706 Ай бұрын
This is a great analysis. NUnit ftw.
@zbaktube
@zbaktube Ай бұрын
Do you know if FluentAssertions will go .net8 or not? Ok, it works in the project, but it looks weird to me that the package is .net6.
@KvapuJanjalia
@KvapuJanjalia 10 ай бұрын
The current iteration of MSTest is not that bad; it looks and feels very much like NUnit.
@DaveMuller
@DaveMuller 10 ай бұрын
MSTests all the way!
@justadude8716
@justadude8716 9 ай бұрын
I use MSTest it's easy to get started with
@TheHejle
@TheHejle 10 ай бұрын
Me using MsTest and making it past 0:33 T_T
@asteinerd
@asteinerd 10 ай бұрын
NUnit, simply because I can hammer units tests out in minutes, whereas XUnit always takes a bit of boiler-plating to get going and doesn't have the best mock injection workflow with it creating a new instance of a class on each test. Ideal for some scenarios but not the ones I employ. My ideal combo: NUnit + Moq + Bogus + AutoBogus Hooks into EFCore nicely via in-memory DB package; I personally prefer a full-fledged ORM versus a wrapper/helper like Dapper; but I'm sure given the flexibility of Dapper unit tests wouldn't be very difficult to setup with extension packages like Moq.Dapper.
@paulecampbell
@paulecampbell 10 ай бұрын
Great content as usual Nick; you should probably do a video explaining why we should not use MSTest
@JVimes
@JVimes 10 ай бұрын
Yep! For most cases it's now splitting hairs, at least from a pragmatic standpoint.
@antonmartyniuk
@antonmartyniuk 10 ай бұрын
MsTest just evolved to NUnit, while xUnit is thousands of kilometres ahead. MsTest is a almost like an Internet Explorer, lol
@Rein______
@Rein______ 10 ай бұрын
​@@antonmartyniukWhy?
@kocot.
@kocot. 10 ай бұрын
@@antonmartyniuk thousends of kilometers ahead in what? I was forced to migrate to xunit from nunit for over two years now and sitll looking back sometimes...
@IliaDock
@IliaDock 10 ай бұрын
Hi Nick. In NUnit you usually would initialize SUT in SetUp method. Then you will get a separate instance per test and TestContext.Out.WriteLine will print different GUIDs.
@AnythingGodamnit
@AnythingGodamnit 10 ай бұрын
He showed that and explained why that's not the point.
@sqlexp
@sqlexp 7 ай бұрын
He's just successfully convinced me to avoid xUnit😊 Why would I want to create a fixture object for each test to slow it down? The sole purpose of the fixture class is to share common data to reduce setup time. One can use the [Setup] method to change the per-test data.
@AntonMelegov
@AntonMelegov 10 ай бұрын
in XUnit also possible to share the context between test classes when writing integration tests that require running containers. In NUnit, you have to recreate the context completely or use dirty hacks to pass it through static classes
@s2ym3k
@s2ym3k 10 ай бұрын
As QA engineer I prefer NUnit. 1. It gives you access to test context i.e. metadata about test (currently executing test class, method etc.), possibility to attach some files (like screenshots, files with logs etc.). 2. It's more flexible in parallel tests execution - xUnit is not able to run tests cases inside class in parallel. 3. Data driven tests are more intuitive and flexible in NUnit - it allows to combine them and generate tests automatically. 4. NUnit has possibility to mark test as inconclusive. 5. NUnit has possibility to order tests. Agree, that maybe in unit tests these features may be not needed, but in integration or E2E tests they are very useful.
@He88dead
@He88dead 10 ай бұрын
I completely agree. I have written thousands of tests for Nunit and find it much more powerful. Comparing two frameworks by how they run is not correct. There was no comparison of writing parameterized tests, the advantage of the Values attribute was not shown, the possibilities of Assert.That (pooling, waiting for the result and other constraints) were not shown. Tests in the real world are much more complicated than comparing two strings, especially when writing tests for legacy code.
@devmarkmonster
@devmarkmonster 10 ай бұрын
Good reminder video of why I used xunit for that many years. Together with Fluent Assertions for asserting, NSubstitute for mocking and AutoData for injecting mocks and data I’m happy writing tests.
@benoitrousseau4137
@benoitrousseau4137 10 ай бұрын
I used MSTest for years, never had a problem with it. Admittedly I would use xUnit on a new project today since I like the feature set better, but there is no return on investment for me to convert all my old tests away from MSTest, it works just fine and it's well supported by Microsoft.
@Kingside88
@Kingside88 10 ай бұрын
Thank you for this video. Everything was new to me. I'm used to using NUnit and am familar with the syntax. However xUnit is also very straight forward.
@OSA413
@OSA413 10 ай бұрын
Thank you for the video comparison, I've been interested in a short description of the differences between these two testing frameworks (all other videos that I found were very long and included a lot of fillers that are perfect for new learners but not great if you are only interested to know the difference between them). I really prefer the NUnit syntax, I think it's more readable. And NUnit has persistence in the entire TestFixture, which I prefer (same as describe in Jest/Vitest). I usually put the Repeat decorator for a test/suite to check that it's persistent and not flaky.
@dahahaka
@dahahaka 10 ай бұрын
What's wrong with MSTest? I'm having basically the same experience as in nunit/xunit?
@frederikja2210
@frederikja2210 10 ай бұрын
I use NUnit mainly because thats what we use at work. However i feel like its actually the best option from this description aswell. Having the classes be singletons makes a lot more sense to me. That way its also cleaner to read what variables are useable for that specific test and what variables are not available. Also if you have some sort of global test setup logic like creating a file, downloading a file etc. Im not sure how you would do that using xunit without having to do said logic multiple times over.
@felixier
@felixier 10 ай бұрын
Btw. NUnit also had a similar interface for tests as XUnit with something like Assert.AreEqual(), but there is this newer fluent API using Assert.That(). I started using FluentAssertions for that. Technically, it is fully redundant, but you can use it with any of these frameworks and you get the same assertions.
@orhanaliyev9774
@orhanaliyev9774 2 ай бұрын
Assert.AreEqual() This is an old spelling, Assert.That() is better to use
@Sahuagin
@Sahuagin 10 ай бұрын
I just use MSTest so far. What you showed with xUnit I achieve by writing a nested class that I instantiate at the start of every test. it's usually disposable and it will have the SUT and any mock dependencies created with options for setting known values and so on. what you did with xUnit is slightly cleaner by basically using the test class itself as the SUT wrapper.
@ViniciusOttoni
@ViniciusOttoni 10 ай бұрын
MSTest2 + Fluent Assertions it's being sufficient to me.
@PeterOeC
@PeterOeC 10 ай бұрын
First of all, love your videos! :) I disagree with your "instantiating the test class for every test is better" argument, cause I would expect a property in my test class to be the same when instantiating it inline and not changing it afterwards. Also you can mark it as readonly (as you do) if its not supposed to be changed by your tests (generally I would avoid global variables to be changed in methods - so for me it allows for a bad pattern, and NUnit will force you to do it right). Also, I like the [Setup], [Teardown], and also [OneTimeSetUp] and [OneTimeTearDown] attributes that exists in NUnit, as to me, it's more explicit than implementing IDisposeable, and using IClassFixture. I clicked on the video to kind of get the "this is why you should pick XUnit in this scenario or this is why you should pick NUnit in that scenario" - instead I got "They can do pretty much the same things in different ways, but XUnit is more popular". I value your points and video though :D I'll keep searching for someone to change my mind about NUnit versus XUnit :) But it also seems there's a good reason both exists, which annoys me a bit :D
@MrIlsonxaxol
@MrIlsonxaxol 10 ай бұрын
Nunit has attribute LifeCycle.InstancePerTestCase Which will help you create an instance per each test.
@quigley61
@quigley61 10 ай бұрын
I start new projects with Nunit. I've never felt that I've been missing something in my test framework. I have hit the issue with state being persistent across tests only 2 weeks ago, but it wasn't that much work to work around. There might be something to be said for in that tests can get quite long, which is definitely true for our Integration tests, but even then it's not too much of an issue.
@surgeon23
@surgeon23 10 ай бұрын
Originally we were using MSTest because it is integrated and didn't need any extensions in visual studio. Today we are still using MSTest because of the mentioned historical reasons, but to be honest, I am not missing anything with MSTest, especially since 3.0. The one instance per class sounds great though, right now I am doing it manually by having a context instance that is created in every test.
@mysteriouslyhandmade
@mysteriouslyhandmade 10 ай бұрын
IIRC MSTest already creates one intances per test, just like xUnit.
@casperhansen826
@casperhansen826 10 ай бұрын
I just use the [TestInitalize] for each class, I think MSTest uses the best attribute names like [TestClass] [TestMethod] etc. But I also like that XUnit doesn't need them, I don't know if the class is created for each test in MSTest, it hasn't been a problem
@David-id6jw
@David-id6jw 10 ай бұрын
I think it only creates the class once, because it also has a [ClassInitialize] attribute. So the stuff Nick talks about with shared elements across tests would naturally be handled in the [ClassInitialize], while stuff that needs to be changed for each test would be in [TestInitialize]. I prefer it to xUnit's approach because it's clear exactly what's happening, rather than needing magic generic templates or whatever.
@woocaschnowak
@woocaschnowak 10 ай бұрын
​@@David-id6jwyeah, but ClassInitialize (AFAIR) is "decorable" only on static methods. I'm almost sure MSTest is instancing test classes the same way as xUnit.
@99MrX99
@99MrX99 10 ай бұрын
@@David-id6jw MSTest uses a new instance for each test. They just added the Testinitialize method so the purpose is more clear, but you can just skip it and use the contstructor for that, that's what I often do, as I can use readonly fields than.
@PascalLaprade
@PascalLaprade 10 ай бұрын
MSTest! Originally mostly because it was developed by MS. Then I quickly started enjoying its simplicity and how easy it is to have up and running (dotnet new mstest && dotnet test, that’s it!) (I guess other frameworks are easier to run nowadays with the dotnet CLI too). And still using it because… there isn’t a day where I feel I’m missing something. No frictions. It’s better than good enough: it just never gets in my way, and does what it says it does. A tool that weighs like a feather. Never makes me think about testing frameworks, and so I never think about switching.
@robadobdob
@robadobdob 10 ай бұрын
We’re using MSTest and it’s been perfectly good. The DataRow attribute saves a lot of repetition.
@PhilAndOr
@PhilAndOr 10 ай бұрын
0:32 "Everyone knows you should not be using MSTest though... like, come on... use something else..." Care to elaborate on that a bit? I've never personally felt it was a problem, and noone on teams I've worked with have raised it as an issue, or suggested we switch to NUnit or xUnit. I've been working on several large corporate c# projects for the last 5 years, predominately unit tests were MSTest only.
@ivanpavlovnorth
@ivanpavlovnorth 10 ай бұрын
4:35 Let me disagree with you on this statement. I consider that initializing fields and using a constructor in a test class is more natural in NUnit because it initializes fields and uses these instances in all test methods as it goes in a usual C# class. And yes, if we need to use a unique instance in each method, we can use the Setup attribute for this. PS: Assertions in NUnit are more pleasant to use and we can avoid using the FluenAssertion library.
@ModernTenshi04
@ModernTenshi04 10 ай бұрын
Do you use any assertion libraries? I've become pretty fond of Fluent Assertions (along with Fluent Validations), but learned about Shoudly today which looks neat but doesn't seem to be as feature rich or as popular as Fluent Assertions. Would love to see a video on these kinds of libraries.
@berry212
@berry212 10 ай бұрын
The reason behind Assert.Pass not being in xunit can possibly be attributed to bad unit tests. There's nothing stopping you from doing an empty try-catch to avoid that exception in xUnit. In QA, if you reach the end of the test and all assertions have passed, the test is a pass.
@jcmorin2007
@jcmorin2007 10 ай бұрын
I'm using MsTest because it was built-in. Regarding the class initialisation it's like xUnit (new instance of every test). I have over 3000 tests so I need a VERY good reason to re-write those! What's wrong with MsTest?
@antonkomyshan1727
@antonkomyshan1727 10 ай бұрын
Thx, Nick. Lets go next FakeItEasy vs Moq vs NSubstitute, pls )
@gustavnyberg
@gustavnyberg 6 ай бұрын
Which is the best way approach on sending a list of test case objects (usually values and expected values, but with the flexibility to design the TestCase class with what ever properties you like) in xUnit? I have used this in NUnit with [TestCaseSource(typeof(TestCases), nameof(TestCases.TestCasesCollection))] and found it to be nice to make a clear representation of what a TestCase is in the given context as well as separating the test data from the actual test and its logic. Great video/content as always and keep up the good work!
@codingbloke
@codingbloke 10 ай бұрын
I use xUnit for exactly that it creates one instance of the test class for each test execution (even for theories). If a system gets a large set of devs banging out stuff it less likely to break due a lack of understanding of instance state. Otherwise all the three main test frameworks are much of a much-ness, but this one behavior of xUnit is the "killer app" that makes it the choice.
@asedtf
@asedtf 10 ай бұрын
xUnit has Assert.Throws for expecting exceptions, but nothing that I'm aware of to just "eyyo pass the test it's all good we're Volkswagen" method
@fakhrulhilal
@fakhrulhilal 10 ай бұрын
Glad to see this video, at least the reason is not following what internal dotnet team uses blindly. I have been using xUnit 2 years, previously I used NUnit more than 6 years. The only reason I uses xUnit is because my team/tech lead wants it. I never use xUnit without FluentAssertion. xUnit's assertion is poor compared to NUnit. One of missing feature in xUnit from NUnit is test session fixture setup. xUnit only allows per test/class level setup. I used it before in NUnit and don't see feature equivalent in xUnit. One of the best feature from FluentAssertion is object graph comparison. I use it a lot in my test projects, it's very flexible and powerful. So my best combination will be NUnit+FluentAssertion. NUnit covers most of the case in my project (assertion helper, setup). I like the new style which is more BDD. It's very flexible, either for single object testing or collection testing. I will use FluentAssertion for object graph testing only. Previously, I have to write my own implementation just to implement this in NUnit.
@penaplaster
@penaplaster 10 ай бұрын
Nick, could you please share your experience of using continuous testing mode in Visual Studio, Rider, NCrunch, etc.
@nsedwards
@nsedwards 10 ай бұрын
Doesn't really matter tbf As long as the unit is being tested fully just use which ever framework is currently in use on the code base you're working on. I also find that running the class through GPT and asking it to provide a skeleton test suite covering all positives, negatives and edge cases makes Unit testing a whole lot faster. If I'm working on my own projects though it's definitely XUnit :)
@StefanoTempesta
@StefanoTempesta 9 ай бұрын
If you want to have separate instances of a class in NUnit, would you not simply create the object inside the test method, instead of a class variable? Class variables are supposed to be reused among all methods.
@ivancavlek4755
@ivancavlek4755 10 ай бұрын
What's your opinion on Fixie, attribute-free testing framework based on conventions?
@ivanp_personal
@ivanp_personal 7 ай бұрын
Nick, yes, please, make a video about the MSTest.
@BananaTie
@BananaTie 10 ай бұрын
I would very much like it if you would talk about the strength and weaknesses when it comes to MSTest and xUnit. I personally love xUnit over anything else when it comes to unit testing, but I recently joined a team that want to stay with MSTest because "that is what we have been doing for a long time now". I suggested we at least would allow for new unit tests to be written in xUnit, but I was dismissed with the argument of "MSTest has more features available". I know MSTest has more annotation commands, but I believe xUnit has a better isolation strategy - however I was not convincing enough. Can your future video on MSTest help me with that?
@pedrosilva1437
@pedrosilva1437 10 ай бұрын
MSTest has the same test isolation as xUnit... an instance of the test class is created for each test that is run.
@nicksteffen8720
@nicksteffen8720 8 ай бұрын
A Side note is that not only is the test case operated on a single class in NUnit, it's operated on that class in PARALLEL by default, which is a recipe for disaster. I would add for the people who don't have the option of switching to XUnit you can achieve the separate class per test functionality in NUnit with some annotations on the class with tests in it. [TestFixture] [Parallelizable(ParallelScope.All)] [FixtureLifeCycle(LifeCycle.InstancePerTestCase)]
@nothingisreal6345
@nothingisreal6345 9 ай бұрын
the arguments are pretty "random". As said in the intro: a matter of taste. Both are available, both have are large community. Essentially you can't go wrong. It is more important to provide good documentation how to solve common testing issues, e.g. how to genrate read-world data to test DB performance read AND write operations. also: how to add failure to in certain layers (with a random chance of occurance) etc. Most tests, acutally test only that a) the compiler works, b) that the specification - which changes all the time - is being fulfilled.
@LorcanODonoghue_DownCastAce
@LorcanODonoghue_DownCastAce 10 ай бұрын
I prefer XUnit. In relation to NUnit's Assert.Pass(). For XUnit when testing and knowing an exception is expected, I've used XUnit's Assert.Throws
@zabustifu
@zabustifu 10 ай бұрын
I assume that in Nick's case, he wanted the test to pass whether it throws an exception or not, ie: two possible positive outcomes. In that case, Assert.Throws would not work. But he could just add a try / catch for that exception, and do nothing or end the test in the catch.
@superpcstation
@superpcstation 10 ай бұрын
I was just watching your integration testing course in the other tab. Came to youtube to procrastinate
@micah.little
@micah.little 10 ай бұрын
IMO, a new instance of the test fixture class per method tested is not only a waste of system resources, (especially when you have a large number of tests) but when you’re testing something like HttpClient operations (where you want to persist the client from the IHttpClientFactory), statics, or singletons, you’re going to get undesired results, no?
@MrDaedra88
@MrDaedra88 10 ай бұрын
Nick, in the “complex” example you showed some shared context and seems like you are using ICollectionFixture for it. We are doing exactly the same but we faced a terrible consequence we don't have a workaround for: tests in the same collection can't be executed in parallel. Did you manage to fix it somehow? I think about switching to NUnit because of it.
@kocot.
@kocot. 10 ай бұрын
It's been a while since I'd moved to xUnit, as that's what the new team had + I wanted to check the hype around it, but I still find nUnit to be more CONSISTENT and CLEAR. You can change from per test to per run setup by simply replacing an annotation and when reading existing code it's very clear what it's going to do without looking into docs. Also nUnit works better with multiple sets of data as you can specify what RETURN RESULT you expect, instead of introducing additional 'expectedValue' input -> much cleaner. Plus no nonsense [fact]/[theory] distinction. Also if you want to use original Asserts I find nUnit ones better and more obvious, plus they support '.That' pattern which is nice. On top of that we've experienced multiple deadlock problems with xUnit, that were terrible to debug, and the author's response to issues in the framework that were pointed out in github wasn't exactly building confidence.
@Mytthewx
@Mytthewx 10 ай бұрын
Awesome video, thank you :)
@robertnull
@robertnull 10 ай бұрын
10:18 What about "catch(ExpectedException ex) { return; }" to pass a test after excetpion in xUnit?
@PeriMCS
@PeriMCS 10 ай бұрын
Nunit allows you to change default behavior of using one class instance for all tests
@DMurdock
@DMurdock 10 ай бұрын
Mstest is good if your CI/CD pipelines use azure devops because of some feature integrations.
@PajakTheBlind
@PajakTheBlind 10 ай бұрын
In xUnit I'm really fond of TheoryAttribute, and using InlineData/ClassData
@jessegador
@jessegador 10 ай бұрын
I was using NUnit way back in 2012 because it was popular at that time. Now I'm using xunit because it is much simpler.
@felixier
@felixier 10 ай бұрын
I started using NUnit very long time ago even before MSTest was available. A couple of years ago I switched to XUnit. I have never used MSTest regularly, but it looks like polished NUnit for me. From my point of view there are 2 bad things about XUnit: missing documentation and that it is relatively slow (in comparison with others). On the other hand, you can easily run tests in parallel using XUnit, so it is better scalable.
@boltyk1
@boltyk1 7 ай бұрын
no. you don't need TestFixture unless you have some setup to put in it. TestCase working fine themselves. The one time init showcase is not representative at all, as we have SetUp for it. NUnit is sequential execution by default, so SetUp works pretty solid for, you guessed it, test run setup. And NUnit being translation of JUnit - we can say it was not designed from scratch in the first place. On the contrary, xUnit was created from scratch when guys realized testing in C# missing a lot with NUnit (say Java) way and it's worth to give C# it's own clean test way. And we don't want to mess with long time living NUnit and make some non-compatible changes - so they decided to create a new testing lib. And they did it the right way so each run is from scratch and test class also from scratch - so your setup not is a constructor - we're good to run all of these in parallel in the most cases. Not sure it's fair to day NUnit tests are flaky. You need to know tools you're working with. For NUnit you know it's not going to create new test class for every test run. For xUnit - you know it will.
@EricKing
@EricKing 10 ай бұрын
I use MSTest mostly, nothing wrong with it. Based on your reasoning here I would actually prefer nUnit over xUnit. To each his own, I guess.
@DeSibyl
@DeSibyl 10 ай бұрын
May I ask your thoughts on using var versus explicit data types? Example: "Guid id = ..." vs "var id = ..." I recently made the switch to using Rider from VS, and I find it odd how Rider always throws warning when I try and use the explicit version, and it recommends I change them all to var.
@alanschmitt9865
@alanschmitt9865 3 ай бұрын
I’m late here but that’s merely Rider/ReSharper’s default code style. I’ve altered my own so that it doesn’t complain if I use the explicit type. You don’t gain anything from either, it’s down to preference and/or convention.
@KONDZiO0102
@KONDZiO0102 10 ай бұрын
I have a problem with xUnit, it is missing some features that exist in NUnit. It doesn't support generic TestFixture. Also, it doesn't have retry/replay attributes (but some nugets add this functionality).
@ozsvartkaroly
@ozsvartkaroly 10 ай бұрын
I only use xUnit nowadays, basically because of the reasons they wrote in the "Why Did we Build xUnit 1.0?" documentation article. But let me name the most important things: better isolation, by default parallel, more natural constructs (as you mentioned too, C# constructs instead of attributes only). And yeah, maybe you need to make a video on why MSTest is/was garbage.
@chrisjohnson7255
@chrisjohnson7255 10 ай бұрын
Lol I literally program around the class initialization problem in nunit all the time. I just add a initialization method on the test initialization attribute, it’s fine.
@noylevi3340
@noylevi3340 10 ай бұрын
What's wrong with MSTest?
@RemcoBeurskens
@RemcoBeurskens Ай бұрын
What's your thoughts about the NUnit contraint model for asserts?
@DonRolling
@DonRolling 10 ай бұрын
I've used xUnit and MSTest. I tend to like MSTest because it is there out of the box. I've never been very impressed by the It.ShouldNotBe(x); syntax. It is fine, but I wouldn't install a library just for that. I'd like to know what drives the scoffing about MSTest. I really haven't seen a huge benefit to the other frameworks. Mostly, I'm just happy if people are writing tests and treat them as a meaningful part of the application.
@laulaurisj
@laulaurisj 10 ай бұрын
Oh yes, when using NUnit after xUnit it's confusing that you need to TearDown class objects so that tests don't clash (usually need to reset mocks in NUnit) I have used both a lot and to me they are equally good. Here are my thoughts: NUnit: - I prefer reading [Test], [TestCase()] over [Fact], [Theory] - [InlineData()], makes more sense to me. - It kind a forces you to think about isolating tests better so that they don't clash - should you really reuse the code or use the same class objects? Tests should be dumb and test only what's needed and not care about other tests. xUnit: - Default behavior that the class is initialized for each test does make it easier to not think about clashing tests, however this can lead to coupled tests, where you could start initializing common test objects in constructor and then tests can grow, when something changes only for few tests. - Less code if default behavior is exactly what you need and if you are aware of it And for all Asserts I like to use global.usings -> FluentAssertions, so doesn't matter which framework is used
@mrmagic_man3027
@mrmagic_man3027 10 ай бұрын
Just one general questions, will the courses on dometrain also be updated?
@nickchapsas
@nickchapsas 10 ай бұрын
Dometrain courses try to stay up to date with LTS .NET versions
@mrmagic_man3027
@mrmagic_man3027 10 ай бұрын
@@nickchapsas thanks for answer!
@W1ese1
@W1ese1 10 ай бұрын
Interesting take on why you use xUnit over nUnit. And personally I agree that xUnit makes more sense in several parts of it's implementation. I just think one of your arguments is kind of a bit flawed. You like xUnit more because it takes C# concepts to represent testing concepts. But on the other hand you also like xUnit that it treats test methods as unrelated to the other test methods in the same class. Isn't it a C#/OOP concept to group related things in the same class? And those related things share the same state that you define. So from this arguments perspective you should like nUnit more since it uses the correct C#/OOP concept. But you don't because some devs tend to not be good with these concepts.
@michaelgraf4612
@michaelgraf4612 10 ай бұрын
xUnit is missing some key features. For example, there's no way in xUnit to perform setup prior to all tests. There are some third party libraries that fill in the gaps, but they don't work seamlessly with things like IMessageSink. xUnit also has no way to run arbitrary code after test failure. This can be incredibly useful when unit testing things like MassTransit consumers where you might want to output the message timeline on test failure.
@MrMelick
@MrMelick 10 ай бұрын
same for me, xUnit is my favorite testing libraby
@proosee
@proosee 10 ай бұрын
I share similar feelings about NUnit and xUnit, about Assert.Pass(): I don't think there is anything wrong to just say Assert.Equal(true, true), but I go for FluentAssertions usually anyway.
@LukeGeorgalas
@LukeGeorgalas 7 ай бұрын
Or just "return;" no?
@proosee
@proosee 7 ай бұрын
@@LukeGeorgalas yeah, sometimes you miss obvious ones, right? Although, Assert is still more descriptive, you see Assert and you know it's to do with testing and it is on purpose.
@2020Mgs
@2020Mgs 4 ай бұрын
Thanks friend
@AntonMelegov
@AntonMelegov 10 ай бұрын
XUnit
@lyrion0815
@lyrion0815 10 ай бұрын
NUnit using the same instance for all Tests in the class hit me hard when working with Unity3D... Also the version used was so old, it didn't support the "instance per test" behavior at all.
@mdzieg
@mdzieg 6 ай бұрын
For simple unit tests I do not care. But NUnit is my option for intergration tests. For exeample when you want to isolate tests with transaction scope to keep database state pristine for other test scenarios, in xunit ClassFixture is initialized on a separate async context thus that scope does not carry over to facts (no, async option on transaction scope is not a solution here). also tests ordering or some global inits are harder in xuinit, require custom code. With NUnit all those issues do not exist.
@Meir017
@Meir017 5 ай бұрын
I mostly use fluentassertions so I don't care too much about the testing framework. The setup of complex dependencies is a one time thing
@PierreH1968
@PierreH1968 Ай бұрын
Which One is preferred for testing MAUI Apps?
@AK-vx4dy
@AK-vx4dy 10 ай бұрын
What happen if you declare _sut static under XUnit ?
@astralpowers
@astralpowers 10 ай бұрын
I wasted so much time on XUnit. It was so painful when I tried to use it in integration tests with a db and web api test fixture and varying configurations. You have to make your own plugins and such to parameterize your tests. Parameterization is built in to nunit and is easy to use. So I ended up using XUnit for unit tests and nunit for integration tests which is not ideal.
@AlexBroitman
@AlexBroitman 7 ай бұрын
I use MSTest V2
@JaySevyLP
@JaySevyLP 10 ай бұрын
Me, who is just getting started with test driven development, completely enchanted by what MSTest can do, and I immediately get to hear its apparently trash :D
@FireNero94
@FireNero94 10 ай бұрын
I favor NUnit every time because xUnit docs are abysmal. I've wanted to start using xUnit for new projects but every time I can't because there are literally zero docs about basic functionality like dynamic input for theories. To find anything about xUnit you have to read probably outdated 3rd party articles which is wild.
@chriswelles1
@chriswelles1 10 ай бұрын
MSTest is so much better. It creates an instance per test, just like XUnit. It can easily do method level parallelization, which is something XUnit can't do. A lot of the async support is more straightforward.
@RajeshAravapalliAZ09
@RajeshAravapalliAZ09 10 ай бұрын
I do not agree your view on MS Test V2. We are happily using in 20 plus micro services and native clients.
@morasiu1
@morasiu1 10 ай бұрын
[TestContext] attribute in NUnit is not required. But overall good video.
@zglmorph
@zglmorph 10 ай бұрын
When C# added nullable reference types, xUnit became the clear winner. If you want to do the normal thing and reinstantiate your SUT in each test, then in xUnit, you can declare a field and assign it either at the field declaration, or in the constructor, and that's it. Whereas in NUnit, if you write the equivalent code (assigning the field in your `[SetUp]`), then you get a compiler warning that your SUT field is declared as non-nullable but isn't initialized in the constructor. You have to declare your SUT field as nullable, or use `#nullable disable` on your test class, or not have a field at all and just duplicate the instantiation in each test, or some other unpleasant workaround. With xUnit, it Just Works.
@KONDZiO0102
@KONDZiO0102 10 ай бұрын
Exactly, xUnit works much better with nullable reference types. I was also creating sut's and mocks in the SetUp method, I was surprised that Nick is doing it in ctor.
@amirhosseinahmadi3706
@amirhosseinahmadi3706 Ай бұрын
Except that as soon as you need asynchronous setup and teardown methods you'll have to resort to `IAsyncLifeTime` which suffers from the exact same downside.
@andreybiryulin7207
@andreybiryulin7207 10 ай бұрын
I use MSTest.
@IronTeddyBear
@IronTeddyBear 10 ай бұрын
I use NUnit because I'm an old fart and I haven't found a need to switch to xUnit yet. But I'd be happy to use xUnit if I'm put on a project that already uses it.
@HowDidThisHappenNow
@HowDidThisHappenNow 10 ай бұрын
xUnit - I like it and its nice that if i do Java i can use xUnit there too
@HoangNguyen85
@HoangNguyen85 10 ай бұрын
I'm an automation QA, I prefer using Nunit than xUnit, mostly reason is simple, easy to use.
@sergeybenzenko6629
@sergeybenzenko6629 10 ай бұрын
MSTest!)))
@Dhaiky
@Dhaiky 10 ай бұрын
Seems NUnit does it a lot better in my opinion, syntax seems better, more understandable, asserts easier to write.
@taojia4350
@taojia4350 11 күн бұрын
In VS Code, the xUnit ITestOutputHelper does NOT write anything out unless I failed test. This "feature" is VERY annoying and make me think switch back to NUnit.
@Irotallic
@Irotallic 10 ай бұрын
I like the default of xUnit as well. But NUnit has a FixtureLifeCycle attribute. With LifeCycle.InstancePerTestCase you can ensure your classes will be instantiated the same way as in xUnit, with the constructor and IDisposable. You can also mark your assembly to use this for all the classes. Very handy when running test in full parallel, because SetUp is not 100% safe.
@Meligy
@Meligy 10 ай бұрын
I came to the video looking for why you'd be using NUnit not xUnit 😁 A lot of people use xUnit because it's getting Microsoft's 1st class support (in docs and examples, etc.) since the creator joined the company.
@phizc
@phizc 10 ай бұрын
For Assert.Pass in xUnit, can't you just return? The test will be success if no asserts fail, so by returning it would be success. Assert.Pass shows intent better though.
@nickchapsas
@nickchapsas 10 ай бұрын
It's not as simple. Assert.Pass will work from any method or nesting level. return needs to be specially handled to be top level in xunit. It's possible, but you have to compromise with how you write the test
@phizc
@phizc 10 ай бұрын
@@nickchapsas ah, yeah, I didn't think about Assert.Pass in a method other than the test method.
@davidpine7
@davidpine7 10 ай бұрын
Hi Nick, great video as always. You mentioned not being familiar with Assert.Pass for xUnit, I'm curious if this would do the trick? Assert.True(true) - PS: xUnit is my favorite too, I really like all of their analyzers.
@RafiXWPT
@RafiXWPT 10 ай бұрын
Im still using nunit because of only one frature - testing internal classes and interfaces without exposing them. For those who saying you should test only public things, I dont agree
@tunawithmayo
@tunawithmayo 10 ай бұрын
That's a hint that you(or whoever) didn't write testable code. The defect is in the code being tested, not the lack of features in the test runner.
@Denominus
@Denominus 10 ай бұрын
@@tunawithmayo Perfectly normal to have internals that you unit test when creating a library. If its in application code then its very questionable. That said, I use xUnit for this and just `InternalsVisibleTo` the test assembly.
@RafiXWPT
@RafiXWPT 10 ай бұрын
@@Denominus Well, that doesnt work if you have some kind of component test wrapper where you put tested interface in generic base class. That setup requires you to have internal test class (because you cannot have public class and inheriting from internal, even in generic argument). Unfortunatelly xunit cannot handle it. Nunit works perfectly well with testfixture attribute
@minnesotasteve
@minnesotasteve 10 ай бұрын
Every job I've had for like forever... we're using MSTest and I don't know why. Nobody seems to know why. We just use it.
@mikicerise6250
@mikicerise6250 3 ай бұрын
Same. 😅 Until now... now we have no unit tests. I'm about to create the first ones, so here I am. 🤣 I'm leaning towards NUnit, though it could be I'm just more used to the syntax, even with all the inconveniences...
@antonmartyniuk
@antonmartyniuk 10 ай бұрын
Once I tried xUnit 5 years ago, I couldn't return to NUnit. It's like when you buy a new and much better car
@tunawithmayo
@tunawithmayo 10 ай бұрын
I feel like everything discussed here is about features of the test runners that are intended to make writing tests that have complicated setup and finalize easier. However, I am strongly in the camp of, if your tests are hard to write, you have done something wrong. For one, it means you wrote the code first, which is a big no-no in TTD. Second, it tells you that you didn't write testable code which you wouldn't have done had you written the tests first. Write your tests first, and your tests become so simple that you don't need to worry about these extra features of the test runner. The fix is not to use the complex pieces of the test runner. The fix is to refactor the code to be testable.
Why We ALL Use xUnit over NUnit or MSTest?
17:51
Gui Ferreira
Рет қаралды 6 М.
Getting Started with Event Sourcing in .NET
37:07
Nick Chapsas
Рет қаралды 9 М.
когда одна дома // EVA mash
00:51
EVA mash
Рет қаралды 12 МЛН
ISSEI funny story😂😂😂Strange World | Pink with inoCat
00:36
ISSEI / いっせい
Рет қаралды 30 МЛН
The New Way of Parsing ANY Type in .NET
13:03
Nick Chapsas
Рет қаралды 66 М.
Thoughts About Unit Testing | Prime Reacts
11:21
ThePrimeTime
Рет қаралды 202 М.
Background Tasks Are Finally Fixed in .NET 8
10:29
Nick Chapsas
Рет қаралды 95 М.
The 3 Biggest Mistakes of Object Mapping in .NET
11:33
Nick Chapsas
Рет қаралды 62 М.
Writing robust integration tests in .NET with WireMock.NET
17:54
Nick Chapsas
Рет қаралды 35 М.
Testing WITHOUT Mocks or Interfaces!
12:27
CodeOpinion
Рет қаралды 24 М.
Swagger is Going Away in .NET 9!
10:48
Nick Chapsas
Рет қаралды 61 М.
How to unit test Minimal APIs in .NET 6 (and why it's hard)
17:31
Nick Chapsas
Рет қаралды 38 М.
Why You Might Not Need Interfaces in C# 12
12:43
Nick Chapsas
Рет қаралды 66 М.
когда одна дома // EVA mash
00:51
EVA mash
Рет қаралды 12 МЛН