简体   繁体   中英

How to do Integration Testing for (Angularjs) Web Apps

I'm developing an Webapp. It consists of 2 parts. A node rest server and an angularjs client.

The app is structured this way: Rest Server <--> Api Module <--> Angular App

The server is currently well tested. I have Unit Tests and Integration Tests. The Integration Tests are accessing a real database and calling the rest api over http. I think this is as high level as it can get for the server testing. The integration tests run fast, too. I'm pretty confident that the way I tested the server is sufficient for my use case and I'm happy with the results.

However I'm struggling how to test the angularjs app. I have unit tests for the relevant directives and modules. Writing these wasn't an issue.

I would like to write integration tests that cover user scenarios. Something like a signup scenario: The user visits the website, goes to the signup form, and submits the form with the data.

The angularjs team is moving from ng-scenarios to protractor . Protractor is using Selenium to run the tests. Therefore there are two scopes: The app scope and the test scope.

Now I can think of three different abstractions I could use. And I'm not sure which one suites me best.

  • Mock the Api Module
  • Mock the Rest Server
  • Use the full server

Mock the Api Module

In this case I would need not to setup a server. All Interactions are running in the browser

Advantage:

  • No server is needed

Disadvantage:

  • The api is in the browser scope and I have to tamper with this.

I really like this solution, but I find it difficult to mock the Api. The Api needs to be modified in the browsers scope. Therefore I need to send the modification from the test to the browser. This can be done , however I don't see how I could run assertions like mockedApi.method.wasCalledOnce() in the tests scope

Mock the Rest Server

Advantage:

  • Client would be unchanged
  • Only one scope to deal with

Disadvantage:

  • One has to setup the Rest Routes

I could create a complete Mock Rest Server in nodejs. Protractor Tests are written in nodejs, thus the control of the server can be done in the test. Before I run the test I can tell the server how to respond. Something like this: server.onRequest({method: 'GET', url: '/'}).respondWith('hello world')

Then I could do assertions like wasCalledOnce

Use the full Server with Database

Each test is running with a complete server and can add elements to the database. After each test one can look at the expected elements in the database

Advantage:

  • Can be pretty sure, that if these tests are running the app is functional in the tested use case

Disadvantage:

  • I already made a fairly intense integration test with the rest server. This feels like doing the same again.
  • Setup depends on the full server

Current Conclusion

  • Mocking the Api would separate the server and the client completely.
  • Using a Mock Api would be a higher level test, but would require a fake server
  • Doing a full integration test would give the best reliability, but this is also highly dependant on the server code

What should I pick? What would you do?

I think I answered this same question in the Protractor google group. I am much of the same mind as you about wanting no server but wanting all of my test code in one place (in Protractor) and not split between Protractor and the browser. To enable this, I took matters into my own hand and developed a proxy for the $httpBackend service which runs within Protractor. It allows one to configure the $httpBackend service as if it were running in Protractor. I have been working on it for a while now and its reasonably full featured at this point. It would be great if you could take a look and let me know if I am missing anything important.

https://github.com/kbaltrinic/http-backend-proxy

It is an excellent question, which has nothing to do with a particular tool. I had to face the same problem on a big "greenfield" (ie started from scratch) project.

There is a problem of vocabulary here : the word "mock" is used everywhere, and what you called "integration test" are more "full end-to-end automated functional testing". No offence here, it's just that a clear wording will help to solve the problem.

You actually suggested the correct answer yourself : #2 stub the rest server. #1 is feseable but will be soon too hard to develop and maintain, #3 is an excellent idea but has nothing to do with UI testing and UI validation.

To achieve a high reliability of your front-end, independently of your backend, just stub the rest server, ie develop a stupid simple REST server that will idempotent, ie will ALWAYS answer the same thing to one http request. Keeping the idempotence principle will make development and test, very, very easier than any other option.

Then for one test, you only check what is displayed on the screen (test the top) and what is send to the server (test the bottom), so that the full UI stack is tested only once.

The full answer to the question should deserve an entire blog article, but I hope you can feel what to do from what I suggest.

Best regards

Here is an approach for writing integration tests for your Angular code. The key concept is to structure your code in a way that lets you invoke the various functions in a way very similar to how it's consumed by the UI. Properly decoupling your code is important to be successful at this though:

More here: http://www.syntaxsuccess.com/viewarticle/angular-integration-tests

This is a great question. This is how I would do it:

As you already have the angular unit tests for the relevant directives and modules this is perfect.

The other thing that is perfect is that your server Integration Tests are accessing a real database and are also making sure the rest api over http works.

So why not just add some high level integration tests that include angular and your server at the same time.

If you can avoid mocking, why not save the work to maintain the extra code, if possible.

Also a good read: http://blog.ericbmerritt.com/2014/03/25/mocking-is-evil.html

Mocking the REST server is the best, cleaner option in my opinion. Try Mountebank ( http://www.mbtest.org ). An amazing Virtualization Service tool.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM