Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reset separate backend service when testing frontend

I have an API project running at localhost:8000 connected to a test database, and I have a front-end angular app running at localhost:9000. How do I reset the database after each front-end test case run? I'm using Protractor for my front-end E2E testing. I do not want to mock or stub the whole backend. Although that will make my test run faster, however, every user interaction will result changes to the server states and followed by several more requests to the same server endpoints, stubbing these endpoints with different returns at different points might be too much code than just talking to a real server. I'd rather reset the database to an initial state or flush all the tables.

One potential way to do it is to write my front-end E2E test suite in my API project. Since now it's ran by the backend test runner, it could easily reset the database before each test case. But I'd rather keep my tests in my front-end project, since my api will also serve other clients, not just the browser client. And since my backend is in php and uses Phpunit for testing, while I'm using Protractor to test my front-end, integrating it into the backend seems to be a bit misplaced.

Have you run into this problem and what's your solution? How do you coordinate the two projects in your E2E (or integration?) test?

like image 233
randomor Avatar asked Jan 26 '15 21:01

randomor


2 Answers

I got into the same problem. My solution is to add a "reset" api end point to restore the database to its state before E2E test starts.

We are using ASP.NET WebApi to build the RESTful service. Here is my code structure.

[HttpGet]
[Route("reset")]
public IHttpAction Reset(){
    // check and remove records added in the e2e tests

    // check and restore the records modified in the e2e tests

}

So an api call to this test/reset method helps restore the backend database into its original state. We can place the call inside afterAll() (if you are using JasmineJS). Or you can just do a manual reset by making that GET call from Postman or Fiddler.

Sometimes, I have multiple reset api methods to call. So that I can test and reset by function groups. Like, perform e2d tests on user management functions and reset that part of data, and then move on to the next function.

One thing to mention is that if the primary key on a table is sequenced, the removal of data added in the test will break that sequence. Make sure our tests are not to "expect" on that primary key.

The whole goal is to be able to rerun the e2e tests and get the same result.


And of course, if allowed, another good way out is to backup the database before our e2e test and restore it after the test finishes. Manual, stupid, but sometimes convenient and sufficient to allow our e2e test to rerun.

like image 122
Blaise Avatar answered Nov 15 '22 06:11

Blaise


I went for writing all E2E tests inside the API project after going the client side route unsuccessfully. The trade-offs:

  1. API has all the factories and models that could be used to bootstrap the test cases. If testing just from the client-side, I have to re-create the model relationships and factories to make it work, and have to track all the changes from API models.

  2. I have to manually setup the client-side to talk to the testing api environment every time before running the E2E test. And also manually set the api server to be in testing mode. Because you need to keep the actual API web server running somewhere so client can hit.

  3. At this time it is still hard to figure out a way to move this very customized test setup to the cloud, and thus integrate with a continuous integration server, because client and api are two separate project. But I finally have some client-side E2E testing running on my local machine, which is better than no tests.

like image 22
randomor Avatar answered Nov 15 '22 08:11

randomor