Reputation: 7213
I have a set of Jasmine unit tests which I run on my build server. I have managed to get Karma working nicely so that my tests automatically run on Chrome, Edge and Firefox every time I push to my development branch.
However, I am concerned that my tests are not independent because much of the browser state (such as global JS, the DOM, and local storage) persists between tests. In some instances I find that this allows tests to pass due to the actions of previous tests, which to me feels like bad practice. What I would like to do is force the browser to be restarted in between each test, thus creating a new, independent test environment. Is this possible?
Upvotes: 5
Views: 2183
Reputation: 151561
I don't think Karma supports restarting the browser between tests. There would be multiple hurdles to overcome:
In order to do what you want, Karma would have to save the state of the test runner after one test is done, restart the browser, and then invoke the test runner in the new browser in a way that allows it to know which test is next. AFAIK, Karma does not have the machinery for this. I'm not super familiar with Jasmine but I don't think it supports this either.
It would muck up the semantics of setup and teardown code. If you use a beforeAll
hook, then what should the test runner do when it is running a test in the second instance of the browser?
A. It does not run the beforeAll
again. If it is responsible for initializing the DOM by adding elements, for instance, then this initialization does not get done. That's not viable.
B. It runs the beforeAll
again, which effectively turns it into a beforeEach
. Whether or not this causes issues is dependent on your project. Some code is put into a beforeAll
instead of beforeEach
because it is rather expensive to run, turning beforeAll
into beforeEach
can be very costly.
And there remains the issue that restarting the browser is, in and of itself, a costly operation and would slow down the suite considerably.
I've run into cases where I would have liked a fresh browser. I've worked around the issue by:
Loading the code under test in an iframe
. This creates a new Window
object so you can isolate Window
-specific data. I've used this, for instance, to test code that messes with onerror
or onbeforeunload
.
I've used the API provided by the DOM to clean up between my tests. For instance, I've ensured that tests that test code using localStorage
is not affected by other tests by clearing localStorage
between tests.
I've yet to run into a case where there's no solution other than starting a new browser instance.
Upvotes: 3