4

I have been looking around for suitable ways to 'clean up' created records after tests are run using Protractor.

As an example, I have a test suite that currently runs tests on create and update screens, but there is currently no delete feature, however there is a delete end point I can hit against the backend API.

So the approach I have taken is to record the id of the created record so that in an afterAll I can then issue a request to perform a delete operation on the record.

For example:

beforeAll(function() {
    loginView.login();
    page.customerNav.click();
    page.customerAddBtn.click();
    page.createCustomer();
});

afterAll(function() {
    helper.buildRequestOptions('DELETE', 'customers/'+createdCustomerId).then(function(options){
        request(options, function(err, response){
            if(response.statusCode === 200) {
                console.log('Successfully deleted customer ID: '+ createdCustomerId);
                loginView.logout();
            } else {
                console.log('A problem occurred when attempting to delete customer ID: '+ createdCustomerId);
                console.log('status code - ' + response.statusCode);
                console.log(err);
            }
        });
    });
});

//it statements below...

Whilst this works, I am unsure whether this is a good or bad approach, and if the latter, what are the alternatives.

I'm doing this in order to prevent a whole load of dummy test records being added over time. I know you could just clear down the database between test runs, e.g. through a script or similar on say a CI server, but it's not something I\we have looked into further. Plus this approach seems on the face of it simpler, but again I am unsure about the practicalities of such an approach directly inside the test spec files.

Can anyone out there provide further comments\solutions?

Thanks

mindparse
  • 6,115
  • 27
  • 90
  • 191

2 Answers2

4

Well, for what it's worth I basically use that exact same approach. We have an endpoint that can reset data for a specific user based on ID, and I hit that in a beforeAll() block as well to reset the data to an expected state before every run (I could have done it afterAll as well, but sometimes people mess with the test accounts so I do beforeAll). So I simply grab the users ID and send the http request.

I can't really speak to the practicality of it, as it was simply a task that I accomplished and it worked perfectly for me so I saw no need for an alternative. Just wanted to let you know you are not alone in that approach :)

I'm curious if other people have alternative solutions.

Gunderson
  • 3,263
  • 2
  • 16
  • 34
1

The more robust solution is to mock your server with $httpBackend so you don't have to do actual calls to your API.

You can then configure server responses from your e2e test specs.

here's a fake server example :

angular.module('myModule')
.config(function($provide,$logProvider) {
    $logProvider.debugEnabled(true);
})
.run(function($httpBackend,$log) {
    var request = new RegExp('\/api\/route\\?some_query_param=([^&]*)');
    $httpBackend.whenGET(request).respond(function(method, url, data) {
        $log.debug(url);
        // see http://stackoverflow.com/questions/24542465/angularjs-how-uri-components-are-encoded/29728653#29728653
        function decode_param(param) {
            return decodeURIComponent(param.
                 replace('@', '%40').
                 replace(':', '%3A').
                 replace('$', '%24').
                 replace(',', '%2C').
                 replace(';', '%3B').
                 replace('+', '%20'));
        }
        var params = url.match(request);
        var some_query_param = decodeURIComponent(params[1]);
        return [200,
            {
                someResponse...
            }, {}];
    });
});

Then load this script in your test environnement and your done.

sylvain
  • 1,951
  • 2
  • 19
  • 34
  • 1
    This will not be a true e2e test. Instead, test the system exactly as it will be in production. – demisx Jul 26 '19 at 04:30