Beyond Unit Tests: Modern Testing in Angular

แชร์
ฝัง
  • เผยแพร่เมื่อ 12 ม.ค. 2025

ความคิดเห็น • 50

  • @dhavalv
    @dhavalv หลายเดือนก่อน

    Really changed my perception of testing. Integration test at the container component level should be the first go to testing. It saves time, more value for your tests and most importantly refactor as you said. Really grateful for this video Rainer Hahnekamp

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Hey Dhaval, good to hear and yes, you summarized my arguments perfectly. 👍

  • @brampeirsful
    @brampeirsful หลายเดือนก่อน +2

    Rule of thumb: make all methods that are used by template protected. This will force you to write clean tests that interact with the template since the methods will not be directly accessible from within the test.

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Yup, and I think protected will be recommended in the upcoming style guide.

  • @sand4rt
    @sand4rt 21 วันที่ผ่านมา

    Great work as always! I very much agree with your emphasis on prioritizing integration testing. It’s great to see Angular is catching up with practices other frameworks have embraced for quite some time:)
    I'd like to highlight another approach to integration testing that isn’t often discussed, but is one i find particularly valuable. This involves mocking the backend using tooling like MSW, `npm start` the frontend, and running tests with commands like `await page.goto('/dashboard')`, `await page.getByRole('button').click()` to test a single page from a user perspective. These full-blown integration tests is usually where i focus on most. I still use the other test types, including component tests though.

    • @RainerHahnekamp
      @RainerHahnekamp  21 วันที่ผ่านมา +1

      Hello Sander, thanks a lot for your feedback. If you use await page.goto, I guess you are talking about Playwright (what else ;)).
      Tim has written a good article a few years ago timdeschryver.dev/blog/using-msw-in-an-angular-project.
      Unfortunately, I've never tried it out for my own projects but I have recently seen it in action at another company. I guess I have to start using it more often.

  • @raymondmouthaan6335
    @raymondmouthaan6335 หลายเดือนก่อน

    Great explanation about the concepts of testing on a Angular application!
    Thanks!

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน +1

      Happy you liked it and you're very welcome.

  • @ralfkretzschmar8131
    @ralfkretzschmar8131 หลายเดือนก่อน

    Vielen Dank Rainer!
    As usual very interesting content.
    What went through my mind while watching: Unit tests will still have a place for libraries, that just provide functionality to other code. So if a library provides some calculation or transformation of data unit tests will be valuable. Also because with unit tests you can exercise your library code in very diverse scenarios (like all those edge cases you mentioned).
    If a library provides components it will be a different story of course.
    But if I develop an app, I do not create code to be used by other code. I create code to be used by a user (most of the time - or all of the time when I am using angular to write the app). So integration tests will be much more fitting.
    And I find the argument that tests my actually survive a refactoring very convincing. In my experience that rarely happens when I go with unit tests.
    Also when I need to make a change to an application because of a changed requirement or a bug that was discovered, it is very difficult to translate that requirement down into all the stuff that is going on below the surface of the app. So to set up an integration test that can be used to verify the change or bug fix is much easier.
    So I am about to make a change to an app that uses a ngrx component store now and should use a signal store when I am done with the change. Now the forst thing I will do is to write integration tests to capture the current behavior (and rip out most of the unit test (or rather first comment them out)). Only then I will start to migrate to the signla store. Let's see how this will work out.

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Hi Ralf,
      yes I think we understand each other.
      Unit tests will have their place. Not just in libraries but in any application with more logic OR for shared parts in larger applications.
      As you said, the more generic, I don't know how the thing is going to be used. So I need to focus more on unit tests, because integration tests usually also include the context.
      Yup, and if you had integration tests for NgRx and you want to switch to the SignalStore, you don't have to change so much in your integration tests. If you have only unit tests for your comonent store...well, that's going to be tricky.

  • @adamplaskota8742
    @adamplaskota8742 หลายเดือนก่อน

    Thanks for the video!
    Actually, for long time I've been thinking about unit test not as something that is coupled to a given snippet of code but rather to a given functionality, so that's why my tests look like integration tests you mentioned.

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      You’re welcome! I don’t think I mentioned it in the video, but if you’re an experienced developer and your instinct is already hinting that something might be off, it’s worth paying attention-it could lead you in the right direction.

  • @jasper7072
    @jasper7072 หลายเดือนก่อน

    At around 28:30 you talk about the type of application, where there is not much complexity in the typescript. Do you think this is still the best aproach for applications where there is a lot of typescsript complexity?

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      I'd write the same integration but I won't be able to cover all possible scenarios. So I'd focus on the most important ones first.
      For the rest, I'll go with classic unit tests. It is also important that you manage to extract the logic from components and put them into services. Services are much easier to test than components because they lack the UI.

    • @jasper7072
      @jasper7072 หลายเดือนก่อน

      @RainerHahnekamp would you then mock those services in the integration tests? We are already moving as much as we can to services, I'm just investigating where to draw the line

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      @@jasper7072 Drawing the line which services to mock and which not is more of an art. As Jeremy put it as long as it is practical, don't try to mock them. In general, with integration tests you have a tendency to avoid mocking and in unit tests everything is mocked. That being said integration tests - especially in large application - will have to mock much more than just the HttpClient.

  • @JoseLuisMonteagudo
    @JoseLuisMonteagudo หลายเดือนก่อน

    Thank your for this great content.
    Waiting for the next video :)

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Thanks, the next one will be an updated version of Change Detection including zoneless

  • @noah.correa
    @noah.correa หลายเดือนก่อน

    Im excited to see tests with Jest and Web Test Runners in Angular

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน +1

      Yes, but honestly speaking, I don't expect so much. Web Test Runner is a modernization. Yes, but it is still Jasmine code for us. Jest is also not really a revolution in terms of developer experience but I hope that with the official support, the build time of Jest tests in Angular becomes a significant performance boost.
      What I hope for the future, is that we see more tools like Cypress Component Testing. That one was really a big leap forward. It is not perfect (huge amount of resources, slow build), but the a step into the right direction.

    • @noah.correa
      @noah.correa หลายเดือนก่อน +1

      @RainerHahnekamp I'm working on a project that doesn't have any tests. If I were to start adding tests now, should I use Jasmine and Karma as angular supports right now or wait for Jest and Web Test Runner fully support?

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน +2

      @@noah.correa If you have an existing application without any tests, then you probably need to refactor your application to make the code testable. Since you don't want to introduce new bugs while refactoring, create first some E2E tests that cover the main features.
      Only then start with the "lower level" testing. If you use the Angular CLI, then go with Jasmine/Karma. If you use Nx, it is going to be Jest by default. If you are running into performance issues with Jest, you might have to revert in Nx to Jasmine/Karma manually. Be aware that Nx has deprecated the support for Karma. That's why I meant some manual changes are required.

  • @daanvandenakker7140
    @daanvandenakker7140 หลายเดือนก่อน

    What about using Cypress/Playwright E2E testing with every external API call mocked as a replacement for integration testing with Jasmine? No worries about testdata in databases or slow backends, but still covers a lot of the Angular application with just a few tests.
    Playwright recently rejecting the merge for the Angular component testing made me really doubt the future of component/integration tests in Angular. And neither does Angular being so slow to replace the deprecated Karma help.

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Yeah, so the primary focus of this video was really about the testing types, not the tooling. If you remember I mentioned Cypress Component Testing quite often and also said that I'd like to come up with a separate videos about the testing tools.
      Angular's replacement of Karma isn't prioritized, because Karma works, and the Web Test Runner will not be a performance boost or something like this.
      Playwright's decision was not just about Angular. They are questioning the whole component testing feature. It will have an impact on React, Vue, Svelte, etc. as well.

    • @daanvandenakker7140
      @daanvandenakker7140 หลายเดือนก่อน

      @@RainerHahnekampthe tooling doesn't matter indeed. I'm just wondering if using the E2E part of any of those frameworks without any real traffic to other applications or databases makes any sense as a replacement for the integration tests as shown in your video. In my opinion they're easier to write and easier to use mockdata with by just copy/pasting a real json response.
      So they're not true E2E tests, but also not really integration tests, but something weird in between I guess.

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      @@daanvandenakker7140 I see, E2E will take much longer because you have to do the navigation (often under-estimated) and you don't have the possibility to replace services or components. At the moment, I'd say now, maybe that changes in the future but if you have a different experience I'd be happy to hear about it.

    • @daanvandenakker7140
      @daanvandenakker7140 หลายเดือนก่อน

      @@RainerHahnekamp valid point about the navigation. Maybe I've been too blindsided by the various tooling and all their pro's and cons. I'll definitely try the integration tests from the video.

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      @@daanvandenakker7140 Sure, you can also try Cypress Component Testing. Might be a good start and could already have everything you need for integration tests.

  • @alexandreroy5934
    @alexandreroy5934 หลายเดือนก่อน

    Out of scope but why the #prefix for httpClient when using the inject method?

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      That is JavaScript alternative of the private key in TypeScript. # makes the variable private during the runtime where TypeScript private is only during the compilation.

  • @ngSamurai
    @ngSamurai หลายเดือนก่อน

    I have pop-corns @home... so, I'm prepared for this!!!

  • @ryzott
    @ryzott หลายเดือนก่อน

    Definitely this is gold information in testing knowledge, thank you Rainer!

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      @@ryzott thanks a lot. Happy you liked it

  • @danywalls
    @danywalls หลายเดือนก่อน +2

    I'm looking forward to learning more about testing with TestbedMan! :)🎉

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน +1

      Oh, you can already comment on that. Didn't know. Thanks Danny! I guess I'd have to put some description here...

  • @jacqueskloster4085
    @jacqueskloster4085 หลายเดือนก่อน

    I don't think that there is one right answer to what kind of tests you should write in which stage of your development. Sure, you showed the efficiency of the integration test, as it provides a lot of coverage since it.. well... uses an integrated environment.
    But there may be situations where multiple developers develop pieces of the software and then we don't have something to integrate with and in that situation, as a developer, you still want to commit with a reassurance, which you then get from your unit tests. In such a situation, the integration test, when written when everything is done, would detect issues in a later development stage, making it harder to pinpoint issues in certain situations. You confirmed that your integrated environment is rather simple and it is written by you alone, I guess. In that setup, I agree, unit tests are a ridiculous overhead.
    But, you know, you can now use chatgpt to write them without understanding them, then everything is green and you simply commit. /s

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Well, I mean, if I write just one class, then sure, it’s going to be a unit test. But that’s not such a common scenario. Usually, you’re working on a feature that integrates into the app or creating a shared component used multiple times. In both cases, your feature or component might span multiple files, and you’d probably want to test them as a whole, not file by file.
      Also, I find writing tests with ChatGPT can be a double-edged sword. It’s incredibly easy to generate unit tests, but it’s easy to overlook the maintenance costs.
      Sometimes, the opposite approach might work better: write a few decent tests and let ChatGPT handle the implementation. In other words, you write the specifications.

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Btw, thanks for the detailed comment.

    • @jacqueskloster4085
      @jacqueskloster4085 หลายเดือนก่อน

      Yeah the chatgpt comment was sarcasm based on my observations, hence I added the /s flag, which you may have missed since it's more of a reddit thing 😂
      I'm with you, but what is a common scenario heavily depends on where you are in a project. E. G. I am writing a complex nodejs backend currently where I need to setup a lot of baseline architecture.
      I couldn't imagine writing all that stuff without unit tests, despite the effort needed. The amount of trust they generate, at least in my opinion, outweigh their additional development time especially in foundational code.
      In angular, of course most of the "foundation" comes from angular itself and I agree that component unit tests are in many cases a complete waste of time, especially when you follow a paradigm of "keep components dumb, keep components reusable"
      Especially now with angular introducing signals, simple components are a joy to create. input.require is probably the best bullshit eliminating piece of code that was ever introduced to the framework. Design time component usage validation. F*ck yes

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      @@jacqueskloster4085 Ohhh, I though /s was a typo. Well, guess I've just learned something new 😅
      So I hope that I didn't give the impression, that you should never right unit tests. As a matter of fact, there is this one tool Sheriff where I am working on, and there unit tests are the majority. But - as you said - we are talking here about testing Angular applications.

  • @Arias9306
    @Arias9306 หลายเดือนก่อน

    Great video! Very informative and incredibly helpful. Thanks so much for sharing!

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      You are very welcome Andrés. What is our opinion on that topic? Does it make sense, or do you see it differently?

    • @Arias9306
      @Arias9306 หลายเดือนก่อน +1

      @@RainerHahnekamp I agree that focusing on integration tests makes sense because they cover more of the app and are not tied to specific code. Unit tests are still helpful for complex logic, but integration tests often provide better value with less effort. A balanced mix of both, is the best approach :)

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      @@Arias9306 Yes, a balanced mix is always good. In practice, things are not always that easy as the examples you see in videos ;)

    • @Arias9306
      @Arias9306 หลายเดือนก่อน +1

      @@RainerHahnekamp Yes, that's totally true! In my job, we often create more unit tests to meet the minimum coverage. But when there is a big change in a component, we end up having to update a lot of tests. :(

  • @КонстантинХ-у4ф
    @КонстантинХ-у4ф หลายเดือนก่อน

    this is unreadable horrible code for geeks

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      Which part exactly?

    • @КонстантинХ-у4ф
      @КонстантинХ-у4ф หลายเดือนก่อน

      ​@@RainerHahnekamp integration test with testBed + testing-library + and mocks. it is really hard and useless in most cases

    • @RainerHahnekamp
      @RainerHahnekamp  หลายเดือนก่อน

      @@КонстантинХ-у4ф Testing is not easy, yes. But useless? What's the alternative? Not testing is not really an option and if you look at the unit tests, you can't say they bring more value?