We've just started developing a web app with AngularJS and we're having some problems with testing it properly so we could use some advice.
Generally, there are the following components to test:
How does one test all of this with minimal effort and no, if possible, overlap?
For any database-centric application, complete integration testing (i.e. with a live server, connected to a database loaded with data) would be particularly messy because there would have to be a process that generates sufficient data for all tests and resets the DB and tests would have to be careful not to modify each other's data. (if I'm missing something here please let me know)
Given the above point, I'm assuming it is best to sever the link between server and client and run the Angular tests using mock data only.
Also, I'm assuming that if E2E testing takes care of all possible scenarios, unit testing controllers is redundant as their values are bound to the model (and would thus be testing all of 2, 3 and 4 above). Unit testing would only be helpful in very complex controllers or to test services and directives.
However, we could not find any information on how to mock stuff with $httpBackend
on a per-test basis like you would do in unit tests, using expect*()
. Angular docs seem to suggest using when*()
plus the occasional passthrough()
when necessary.
But, this poses the aforementioned problem of creating test data for all scenarios and you'd probably need to reset the in-memory DB before each test to be sure the tests are not affected. Also, you're losing the safety of using $httpBackEnd.expect*()
which checks that there are no missing or redundant calls to the server - This would suggest to me that it would also require unit testing controllers to check this.
Can someone provide a detailed testing strategy for AngularJS apps that addresses the testing of the 4 components above as well as the concerns written above?
While both add value to the development process, they are different in many ways. End-to-end testing is a testing process in which the tester tests a software application from the user's perspective. Unit testing is a testing process where the developer verifies that individual units of source code work correctly.
In case you want to perform an end-to-end testing, then you shouldn't mock any database or API call. The exception here is a third-party API that is not under your control.
Mocking is a process used in unit testing when the unit being tested has external dependencies. The purpose of mocking is to isolate and focus on the code being tested and not on the behavior or state of external dependencies.
In this case, integration tests work like a health check that identifies pain points to address. As for E2E testing, it is a testing type that automatically simulates user experience when working with the tool relying on the so-called user stories.
Not sure - since your angular app is theoretically decoupled from your backend, there's no particular reason that angular tests and backend tests need to be commingled. I would test them separately, with each test suite assuming that the other component works fine. (So when testing angular, you assume that the server will work as expected.)
Unit tests - they provide more depth than E2E tests. It's easier to verify specific conditions the code will face. It's also easy to mock out all dependencies as necessary and test just the component the unit tests is interested in. Unit tests don't concern themselves with how the UI works, or that the right data is bound correctly, but rather than the business logic of the app is correct.
(and 4) E2E tests - less granularity, focusing on making sure the UI looks as expected from an end user perspective. You are right that it's messy to test against a live database (although some people enjoy the safety provided by a full end-to-end integration test), and so you should use $httpBackend to mock out the server.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With