Of course it is possible to test a "fat" server that does view and presentation logic, but it is much easier and more efficient to test a thin server and have a separate suite of tests for the client side app.
Of course it is possible to test a "fat" server that does view and presentation logic, but it is much easier and more efficient to test a thin server and have a separate suite of tests for the client side app.
Anyone with experience care to enlighten me?
http://doc.akka.io/docs/akka/2.2.1/dev/multi-node-testing.ht...
For the most part we only spin up multiple JVMs on the same machine but it's not a huge leap to use multiple machines. We don't do so regularly because, as you said, Vagrant takes forever to spin up a new VM. Our Jenkins server does spin up multiple JVMs for our integration tests though.
It's not a true end-to-end test, which would require all your services to be up, but it is an integration test since it tests the entire workings of the consumer. The assumption is that other test suites would test each of the services, and maybe a ping test to test the availability of the services themselves.
For instance, method A might call another class's method B. If you're writing a unit test for method A, you don't also want to test method B. (Other unit tests would test B in isolation, instead.) So in A's test, you make A call a mock B rather than the real B, and you ensure B returns a particular kind of response. In other words, you want to make sure method A behaves correctly when it gets certain responses from B.
So in english, a test is basically saying, "When B gives this type of response (which I'm forcing it to respond with), make sure A behaves as I expect", and a second test says, "When B gives this other type of response (which I'm forcing it to respond with), make sure A behaves as I expect.
So when you write a unit test for A, you mock B by making it send back a canned response and make A use it. Then you call A with some parameters, and then you make sure that A's return type is as you expect.
One advantage of this is that if a future code enhancement breaks one of the methods deep in the code, then the failing unit test will tell you exactly where the problem is. Without mocking, a failed unit test will make you have to examine several layers of stack trace to find the bug.
They are not a substitute for end to end tests though, as you cannot tell if some other assumption is broken.
(But generally I prefer the Mock method anyway)
I guess I need to add an explanation or something?
Docker allows very quick startup of containers (and for testing purposes the distinctions between containers and VM aren't important. Additionally, the easy command line and app ecosystem Docker gives you over just using Linux containers is a big advantage here.).
I prefer the Mock method for two reasons:
1) It's extremely fast - much faster than even docker would be.
2) The data you use for mocks can form part of your documentation (if done properly).
At the moment, we don't use VMs, we just fire up multiple servers on the same box. They use different ports, so it's no big deal. The tests are framed as being for one particular application in the system (eg a test that asserts that the front-end server displays the right profit and loss is a test for the front-end server, even though it uses the price server and the calculation server). Tests for a given application will use the current checkout of that application's code, and obtain packaged versions of the other applications from our internal artifact store. Tests always uses the latest versions of those available; the assumption is that the latest version will have been deployed by the time the code under test is deployed.
There are plenty of things that the multiple-apps-on-one-box approach doesn't test, mostly around networking, so we are trying to get our VM tooling up to speed to run multiple VMs instead. We already use the tooling to deploy VMs for apps in production, but it needs some tweaking to work well on desktops and in CI. It's not clear that this approach will completely replace the multiple-apps-on-one-box approach, because of the overhead in starting the VMs. We'll play it by ear.
Some of the dreadfulness of this approach comes from mismatches between test and production around versioning and networking. Most of it comes from the fact that in practice, it is much harder to track down the source of an error than when testing a single monolithic application.
Now, it could be the case that this pain, and the other pain resulting from splitting a system into multiple small applications, is worth it, because that splitting brings other advantages. I don't have a parallel version of our system implemented as a monolith, so i can't tell you if that's true. I have serious doubts about it, though.