Unit testing - ignoring module run block - angularjs

Is there a way to prevent an application run block from executing during unit tests?
My situation is that I have added some session checking logic to the run block, which redirects to a login page should session checks fail.
Now that I have added this run block in, all my other tests fail since they expect the login page to have been requested as I'm not ensuring the session check returns true before each test.
So is there a way to skip the run block for a unit test, or would it be something like mocking out the module in my tests so it doesn't have the run block included?
I'm probably thinking about this the wrong way, so please enlighten me!
Thanks

No, run block is part of angular app lifecycle.
I would suggest not to have this logic in .run, but transfer all authentication logic into some service. After that its easy to mock it.
If you can be more specific about app architecture, I can suggest more improvements.

Related

Protractor how to run login test script first

I am trying to test an Angular Single Page application with protractor. I need to run the login script first. Only then I can move to other routes since there is a check for token in localStorage on route change.
Is this testing approach correct?. In that case I need to run the login script first. Does protractor allows to control the spec file order.
Or should I run the each script independently by hardcoding the token in localStorage (Should I do login api call independently before each test).
My login script contains the following
it('Login with wrong email', function() {
})
it('Login with correct email', function() {
})
So after running the Login with correct mail I will get the accessToken which will get stored in localStorage and I can continue testing other routes. Is this the correct approach. If not how do I test a single application with login from end to end.
In protractor Style Guide it is mentioned as
Make your tests independent from each other
So should I use beforeAll, beforeEach to get the access token and store in localStorage before each test. In that case please explain me how to do it.
Any help is greatly appreciated.
Thanks.
As highlighted in the Protractor FAQs, you can specify your login code in the onPrepare section of your conf file. Here is an example.
You can also achieve this in beforeAll but that adds unnecessary overhead to your test scripts. Altering the localStorage is possible, but not in the spirit of e2e testing since a lot can go wrong wrt LS, and you will end up wondering if it is your app or your LS modification code that caused this.

Asserting $http request payloads without mocking them

I'm writing Protractor tests to verify the successful creation of reports in our application. A report is created via a series of complex UI interactions within a dialog and saved via an AJAX POST request to a REST API.
I've written tests for the complex UI interactions within the modal, but I'm at a loss for how to test the POST request within the same Protractor tests. Ideally, I'd like to be able to make assertions against the payload of the POST request to verify that the UI is sending the correct data to the API.
It's important to note that I do not want to mock the HTTP call--I need it to go through, since subsequent protractor tests navigate to the report and perform additional checks. My first thought was to somehow hook into the $httpBackend.passThrough() method, but I haven't had any success with that.
Any ideas how to accomplish this?
since subsequent protractor tests navigate to the report and perform additional checks
If you check that the report contains data to that matches which was submitted, you are, albeit indirectly, testing that the POST went through successfully. There is a reasonable argument that this is enough for the E2E test: it tests that the application behaves as he user would want. The user doesn't care how it's achieved: POST, websockets, carrier pigeon ;-)
Keep in mind that the usual aim of such tests is for them to fail if something is broken. If the POST isn't done correctly, then the subsequent tests that verify the displayed report would fail.
The downside is that you would have a bit less information about what has gone wrong than if you managed to test the POST as well. However, unit tests can help. If you have a failing unit test that localises the issue, you write a fix that makes it pass. If you don't have a failing unit test, you can investigate the issue by debugging, add a failing test that highlights the issue, and fix the code so it passes.

Angular Unit/E2E testing with protractor and jasmine

I am writing an angular application, whereby my controller calls an API, that returns live data which I then display on my html doc.
I am using Protractor for my end to end tests, and jasmine for unit testing.
I am mocking my API call, to ensure the API is not called.
My question is whether I should be testing the API call with protractor, and check whether my html doc is updated following the GET request, or whether I should test the API call when conducting my unit tests with jasmine.
I have a feeling that the answer is that I should be testing this API call with both my unit and end to end tests, but am hoping someone on SO can provide clarity.
The main goal of unit testing is to test that your code (be it JavaScrip or otherwise) is doing what it should. Each test should be done against data that static or contrived and should never be run against an API. Static data gives you the control you need. If your code needs to branch when X equals 7, you can purposely set that value and verify that your code does indeed branch. When you run against an API you do not have that control. Even if you are the one that controls the API, doing unit testing against it is a bad habit to get into.
End to end testing is completely different. Here we are not testing that the code works on a granular level (we already did that in our unit tests) we are testing that the application works as a whole. When a specific button is clicked in the application, did the expected things happen? Do all of the expected elements appear on the page? You still need to be testing against known data, and doing that is just as crucial as in unit testing, but here you get to see how your app reacts against when running. Did a particular screen take too long to load? Did a button click not give you what you expected? This kind of testing lets you click through your application as a user would (except much faster.)
You should run both kinds of tests on your app. Unit tests should be run during the build process, and end to end tests should be run once the build completes.

Possible to get unique browser instances in e2e specs written for protractor?

I'm using protractor to run some end-2-end tests for an Angular application, and from what I can tell, all the specs I specify in my config file end up sharing the same instance of protractor's browser.
Normally this wouldn't be a problem, but I am also using http-backend-proxy to set up mock responses to my application's ajax calls. This module uses the browser instance, and it seems that setting up mock responses in one spec pollutes the browser instance for subsequent specs, causing all the specs to use the mock response strategy defined in the first spec.
Obviously this creates some problems for test isolation.
Has anyone dealt with something similar?
[edit]
I did not find a way to create multiple browser instances, but did find a way to deregister http-backend-proxy responses between tests, which accomplishes the test isolation I was looking for. For future reference to anyone that runs into this same problem, I was using:
proxy.onLoad.when()
setups to handle my mock responses. You can deregister these with:
proxy.onLoad.reset()
If you place these in beforeEach() and afterEach() blocks, respectively, you can accomplish isolation both between tests within a given spec, and between separate spec files.

AngularJS e2e tests hang when changing between two separate angular apps

I have a frustrating problem: I want to write end to end tests for a complex angular app. The problem is that the login screen is a separate app. The initial idea was that it would branch out to separate other angular apps in our ecosystem based on the login credentials. It works like a charm. For the tests it is a nightmare though.
The tests work as expected but as soon as correct credentials are entered and the main angular app is loaded the tests just time out. No error message or debug output whatsoever, its just waiting. I can see the page is loading correctly.
Now I thought I would skip this part and test right on the target app but thats not working either since I need to initialize the server with the right credentials first (= go through the login screen).
I tried this with the karma scenario runner and protractor, both show the exact same behavior. Can I tell them to reinitialize after the target page is loaded?
So when protractor times out, the error message shows a link to the faq. Right on top there's the explanation for this problem. Apparently the app sends continuous requests (maybe because I am using socket.io), so Angular is never finished.
This problem has nothing to do with the separate apps.
The issue link was very helpful. Since I am not willing to touch any of the pages code I settled with
browser.ignoreSynchronization = true;
and
browser.sleep( ... );
The tests now work as expected.

Resources