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?
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.
@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
@@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.
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.
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.
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
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.
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.
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.
@@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.
@@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.
@@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.
@@daanvandenakker7140 Sure, you can also try Cypress Component Testing. Might be a good start and could already have everything you need for integration tests.
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.
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.
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.
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.
@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?
@@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.
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
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.
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
@@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.
@@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 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ф 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?
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?
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.
@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
@@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.
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.
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.
Great explanation about the concepts of testing on a Angular application!
Thanks!
Happy you liked it and you're very welcome.
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
Hey Dhaval, good to hear and yes, you summarized my arguments perfectly. 👍
Thank your for this great content.
Waiting for the next video :)
Thanks, the next one will be an updated version of Change Detection including zoneless
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.
Yup, and I think protected will be recommended in the upcoming style guide.
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.
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.
@@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.
@@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.
@@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.
@@daanvandenakker7140 Sure, you can also try Cypress Component Testing. Might be a good start and could already have everything you need for integration tests.
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.
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.
Out of scope but why the #prefix for httpClient when using the inject method?
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.
Im excited to see tests with Jest and Web Test Runners in Angular
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.
@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?
@@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.
I have pop-corns @home... so, I'm prepared for this!!!
Good idea 🍿
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
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.
Btw, thanks for the detailed comment.
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
@@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.
Definitely this is gold information in testing knowledge, thank you Rainer!
@@ryzott thanks a lot. Happy you liked it
I'm looking forward to learning more about testing with TestbedMan! :)🎉
Oh, you can already comment on that. Didn't know. Thanks Danny! I guess I'd have to put some description here...
Great video! Very informative and incredibly helpful. Thanks so much for sharing!
You are very welcome Andrés. What is our opinion on that topic? Does it make sense, or do you see it differently?
@@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 :)
@@Arias9306 Yes, a balanced mix is always good. In practice, things are not always that easy as the examples you see in videos ;)
@@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. :(
this is unreadable horrible code for geeks
Which part exactly?
@@RainerHahnekamp integration test with testBed + testing-library + and mocks. it is really hard and useless in most cases
@@КонстантинХ-у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?