The complete guide to unit testing structure best practices

Поделиться
HTML-код
  • Опубликовано: 28 июн 2024
  • Get the source code: / amantinband .
    In today's video, we'll break down everything you need to know to set up your unit testing structure to strive!
    Link to the full playlist: • ASP.NET 6 REST API Fol...
    Connect with me on 'em socials:
    Twitter: / amantinband
    LinkedIn: / amantinband
    GitHub: github.com/amantinband
    00:00. Intro
    01:48. Root folder structure & creating test projects
    05:08. The source code we'll write the test for
    05:52. Test file naming and folder structure
    07:40. Test naming - T1_T2_T3
    10:48. Other common approaches
    13:47. Importance of test naming
    15:17. Unit test implementation part 1 - Arrange, Act, Assert
    16:11. Test utilities part 1 - Building a mini-test framework
    19:37. Test constants part 1 - Modules
    23:13. Test utilities part 2
    25:03. Test constants part 2 - Constant, yet different?
    26:27. Test utilities part 3
    28:09. Unit test implementation part 2
    30:29. Validation utilities - Modular extension methods?
    33:31. Creating multiple valid objects
    35:14. Test utilities part 4 - Mini-test framework grand finale
    40:40. Running and debugging the test
    42:33. Recap
    43:44. Patrons ♥️
  • НаукаНаука

Комментарии • 65

  • @stylem8132
    @stylem8132 Год назад +5

    This is the holy grail of unit testing in C#. I have been looking for months for such a detailed and real world oriented video. Thanks a lot!

  • @MrAndyTruman
    @MrAndyTruman Год назад +5

    Finally, the long waited episode. LOVE it!

  • @pureconstant7756
    @pureconstant7756 Год назад +1

    Hi! I've been looking around some videos on clean architecture and good software engineering and your channel is one of the best! Great content, perfect speed and you go straight to what's important with good explanations on why you do things in a certain way. Keep it up and thanks for taking the time to do these videos.

  • @num1nex337
    @num1nex337 Год назад

    This is the best video about unit testing I've ever seen, Thank you for that!

  • @dmytronoskov
    @dmytronoskov Год назад

    Thank you, Amichai. Looks comprehensive and great!💪

  • @blendzhegrova7106
    @blendzhegrova7106 Год назад +2

    Thank you brother, all this content for free is amazing

  • @IcedCupcakes
    @IcedCupcakes 8 месяцев назад

    This is literally the best series ever for .NET beginners. Thank you!

  • @saracamilalauramanzaneda2776
    @saracamilalauramanzaneda2776 Год назад

    I have been dreaming this so long. Thanks!

  • @cheekycunt-ou6ot
    @cheekycunt-ou6ot Год назад

    Finally, thank you the effort you put in for this amazing content

  • @sushilb7994
    @sushilb7994 3 месяца назад

    This is best video ever on unit testing. thank you so much Amichai 👏

  • @reshiefaisal1477
    @reshiefaisal1477 Год назад +4

    Thank you sir very much ppreciated. Just asked this in the last video. Thank you sir.

  • @narekhovhannisyan6362
    @narekhovhannisyan6362 Год назад

    yeah, I was waiting for this!

  • @PhanTomCow666
    @PhanTomCow666 Год назад +5

    I am using similar approach. The only difference is that i'm keeping my tests as close to the tested project as possible (without the "tests" folder).

  • @yoel.taylor
    @yoel.taylor Год назад

    Great video, extremely well explained and showcased!
    I'm quite surprised I've been working almost exactly the same way with my testing infrastructure (although your example is a bit more graceful than my actual projects).
    The one thing that gave me a lightbulb moment was splitting the constants into partial classes in separate files, genius.
    I wish I had partial classes in my current Java project...

  • @thisisnabi
    @thisisnabi Год назад +2

    thanks Amichai, great

  • @codingbloke
    @codingbloke 8 месяцев назад

    Nice video. This is the sort of pattern I use especially when it comes to naming and creating common fixture data that doesn't clutter the test. However, when it comes to creating the Sections and the items I would use a delegate that returns a list rather than an instance of a list. So for example where in the final test there were a set of sections that each referenced the same list of items, we can provide a different list of items to each section.

  • @billymartin6497
    @billymartin6497 3 месяца назад

    Great video! Would love to see a tutorial of this in action doing TDD!

  • @dan73402
    @dan73402 Год назад

    Thanks Amichai, for all your vidéos, You were going to make another video showing how to handle invariants and domain errors. I'm really looking forward to that one. Thanks.

  • @bobek8030
    @bobek8030 Год назад +15

    Can you show us how to write integration tests efficently?

  • @LoZioIAR
    @LoZioIAR Год назад

    Good job! Waiting for Integration test

  • @chimanwadike698
    @chimanwadike698 Год назад

    Great video
    Indeed testing is alot of effort

  • @wralith
    @wralith Год назад

    Amazing content, it seems like lots of ceremony though

  • @nouchance
    @nouchance Год назад

    THANK YOU SIR

  • @dipjyotisikder
    @dipjyotisikder Год назад

    Awesome video brother! Really learning so many methodologies from you.
    And one thing, the sound seems a bit lower. Please try to increase in next videos. Wish you best of luck!

    • @amantinband
      @amantinband  Год назад

      I'll double-check next time, thanks!

  • @jimiscott
    @jimiscott Год назад

    We have arrived at a similar state with our tests. I tend however to move the constants to inside a static object/model if it's common or variable inside the test method.
    If I need to assert on one of the properties of the model that's when I tend to have that defined as a method level constant (defined at the top of the method...screaming at me, in CAPITALS).

  • @Hassanlou
    @Hassanlou 10 месяцев назад

    Thank you for the great and informative series. I followed all parts and have a question regarding UOW. In a scenario where changes are made to two different aggregates/entities and want to apply it in the database, how would you handle it as one transaction?

  • @evgeniysir4220
    @evgeniysir4220 10 месяцев назад

    Great video! Thank you! Maybe not exactly on the topic of the video, but I have a problem that I don't know how to solve yet using the existing architecture. Namely: I add a function to the repository to search for an entity by identifier, I pass an identifier object to the function as a parameter (HostId hostId hostId as an example), inside the function I use FindAsync(hostId). When executed, the exception "System.ArgumentException: The key value at position 0 of the call to 'DbSet.Find' was of type 'HostId', which does not match the property type of 'AggregateRootId'" occurs. Considering that AggregateRootId is an abstract class, how to solve this problem? I would be grateful for a hint.

  • @MustafizurRohman-zq2qz
    @MustafizurRohman-zq2qz 10 месяцев назад

    Thanks for the very detailed and informative video. Appreciate it a lot. How about using AutoFixture to generate the models for us because in most cases we do not care about the contents of the objects generated using the Utility Classes?

  • @felixarjuna9908
    @felixarjuna9908 Год назад +2

    How can you debug the unittest inside of vscode? I assume, you use the "debug test" from Dotnet Test Explorer Extension. But it did not work for me. Would be great, if you can elaborate more on that. :) Great video, by the way.

  • @RadiationKing9119
    @RadiationKing9119 9 месяцев назад +1

    How did you manage to debug the Unit-test project. I am not able to see how you attached the projects to the debugger.

  • @josersleal
    @josersleal 4 месяца назад

    Why not use fixture or other to generate data instead of creating static classes by hand?

  • @farzadmf
    @farzadmf Год назад +1

    Great video, thank you. Question: what tool do you use to annotate the screen in "real time"?

    • @amantinband
      @amantinband  Год назад +2

      Thanks! I use presentify on MacOS (this video), and ZoomIt on Windows

    • @farzadmf
      @farzadmf Год назад

      Thank you for letting me know. ZoomIt seems to be free, but I guess pressentify isn't, right?

    • @amantinband
      @amantinband  Год назад +1

      Right

  • @smliwhcirdeirf
    @smliwhcirdeirf 11 месяцев назад +1

    Hey Amichai, will you continue this series?

  • @brunojoaquimtech
    @brunojoaquimtech Год назад

    Great video, did you consider AutoFixture to generate random data in each test?

    • @amantinband
      @amantinband  Год назад +1

      Thanks! I think AutoFixture is a great way for creating mock objects for testing, but I don’t have experience working with it in large projects to confidently suggest it as a go to solution

    • @pilotboba
      @pilotboba Год назад +1

      Autofixture and bogus together ftw.

  • @PeriMCS
    @PeriMCS 10 месяцев назад +1

    I don't like your test naming convention for a few reasons.
    Like you said once SUT is renamed you need to rename tests. Sooner or later, you will forget to do it. Reviewers of your PR will see change only in SUT source file and will need to check if there are any tests to remind you to rename them. They will most likely not want to spend time searching for tests so they will not do it and it will slip in in every PR. Some of your tests will have wrong names after some time. I don't understand why the name of class containing those tests is not enough? When you see the test failing you see that this test is in SUTTests class so you know exactly what failed.
    Should - this is so common and I don't like it. What does it mean "Should"? Should, but doesn't have to? No, it must do what it says. When you have test with "Should" in it and it fails is it good or bad? Why bad? The test says it only "should". Plus, it adds to test name length so often they don't fit on screen especially if you split screen to see both SUT and its tests. I use XUnit which uses [Fact] attribute instead of NUnit's [Test]. I like the name "Fact". My tests, when passing state facts about the system. If they fail, this means that Fact is not true. When Test with Should fails it doesn't mean anything to me. So, if I said I state facts about system your test which verifies Handling create menu command would be - ValidRequest_CreatesAndReturnsMenu. Others could be: InvalidRequest_IsRejected. Short and to the point. When you see list of tests passed you can even export them and show business people what has been implemented, they will understand it.

  • @DrHeinzDoofenshmirtz
    @DrHeinzDoofenshmirtz Год назад

    Hey Amichai. What is your presentation tool called? The one you use to draw on the screen. I have found ZoomIt, which looks like it can do much of the same, but the styling is different, so you are using something different :)

    • @Vreth6
      @Vreth6 Год назад

      Looks like he is using ScreenBrush, it is macos only I believe

  • @kenjiobara
    @kenjiobara 11 месяцев назад

    what is the name of this to you use to make arrows during the record?

  • @01110100011101110110
    @01110100011101110110 Год назад

    Good overview. I'd personally use fluent interface if possible instead of default params for creating custom test objects. Like: CreateCommand().WithSections(sections).

    • @amantinband
      @amantinband  Год назад

      I used to love the builder pattern, but nowadays, I almost always default to optional parameters instead - same behavior, less code

    • @01110100011101110110
      @01110100011101110110 Год назад

      @Amichai Mantinband, I guess you also would hurt discoverability (using builder pattern). I have seen test methods with A LOT of default params or params that are unclear. I guess it's the matter of composition and code review. You have to hold your test code to the same code quality standards as regular code.

    • @amantinband
      @amantinband  Год назад

      Same. That’s why I think it’s important to limit the parameters to constructing the top level object, otherwise it’s a slippery slope. Regarding code review, I have yet to see big projects where tests are reviewed thoroughly. At some point, the threshold becomes lower than production code

    • @peterfranzmayr3962
      @peterfranzmayr3962 Год назад

      A function named CreateCommandWithSections(sections) is just as descriptive as the builder class function but without the effort. In addition i can easily change the name (i mean the first part) without affecting other functions.

    • @01110100011101110110
      @01110100011101110110 Год назад

      ​@@peterfranzmayr3962 Yeah, but naming is one of the hardest parts of programming (imho), especially when you have a lot of different params. Personally, I have troubles with overly descriptive names (and names that expose implementation details). I would probably use data generators in case of complex objects to improve maintainability and readability. But than again having a standard naming convention for your tests and tests helpers improves the situation quite a bit.

  • @atifsaeedkhan9207
    @atifsaeedkhan9207 Год назад

    Do u have any video on cache implementation?

  • @OrgesKreka
    @OrgesKreka Год назад

    Very helpful template!
    Can you continue the project by adding code coverage and github actions ?

    • @amantinband
      @amantinband  Год назад

      You mean how to set up a GitHub action that checks code coverage?

    • @OrgesKreka
      @OrgesKreka Год назад

      @@amantinband yes please.

  • @ghevisartor6005
    @ghevisartor6005 Год назад +1

    my lazy brain goes to wonder if there is a way to make a source generator or chat gpt to write all this test code lol
    anyway this video is very useful, i was sort of ending up going a similar direction recently even tho less rigorous and more messy.
    I might not know to write this stuff correctly, but i truly feel bothered when i write messy tests or code in general to just make it "work".
    20:46 why did you make the constants class partial?

    • @amantinband
      @amantinband  Год назад +1

      Hey Ghevi. Partial allows splitting a class’s implementation across files. This way we can have two files that have the constants static class (Constants.Menu and Constants.Host in our case)

    • @ghevisartor6005
      @ghevisartor6005 Год назад

      ​​​@@amantinband have one more question, when trying the convention for naming tests...i understand i should consider my context but in ur opinion...
      If i have a class called MyService that have many methods instead of mediatr handlers for each operations, should i name a test like "MyService_WhenCreatingProductWithNewId_ShouldReturnSomething" or "CreateProduct_WhenNewId_ShouldReturnSomething"?
      It seems like in the first case the middle part gets very long.

  • @reshiefaisal1477
    @reshiefaisal1477 Год назад

    Hello Amichai! Hope you're doing well. This isn't related to unit testing, but can you please share your key binding of vs code. That'll very much appreciated.

    • @Vreth6
      @Vreth6 Год назад +1

      Looks like he is using the VsVim extension to get Vim mode in VsCode