This is a sample project that shows how to write truly end-to-end tests in Scala. It accompanies a talk I gave at Scalapeno 2014 titled "True End-to-End Testing in Scala".
This project uses:
- Sbt for the build and the test harness
- Vagrant for running the tests in
- Ansible for deployment and automation
- Maven repository for artifact publishing and distribution
The app itself is a finatra-based "micro-service" (choosing finatra was an arbitrary decision, it could just as easily be another server framework/library, like Play, plain finagle, spray, etc.).
The simple example app is a notes-taking web service, which allows storing, retrieving, searching for and translating notes, and is named memento
. It exposes a REST API and returns JSON.
The app is composed of two modules: core
and finatra
. The core contains as much of the code as possible, and includes unit and integration tests. The finatra module is the server aspect, and only contains the controller/http layer. It's modeled so we can later on easily replace the server module and use a different library/framework as our http server (or something else completely). Our end-to-end tests reside in this module.
The architecture includes:
- Ubuntu for the operating system
- HAProxy as a load balancer
- Nginx as an http server in front of the finatra app server (reverse proxy)
- Elasticsearch as the datastore
The scala app and ansible playbooks are joined here in the same git repository mainly for brevity and ease-of-use. It is suggested that real projects separate them into two repositories (or more if you have more then one deployable) to allow more flexibility, but this is up to you.
To run the tests the following should be installed on your dev machine:
- Sbt
- Vagrant
- Vagrant-cachier plugin:
$ vagrant plugin install vagrant-cachier
(optional but recommended) - Ansible
There are 3 testing modes:
test
for running unit testsit:test
for running integration testse2e:test
for running end-to-end tests
To run all tests together:
$ cd ./memento
$ sbt test-all
If you want to test only the ansible code, run:
$ ansible-playbook -i ansible/inventories/vagrant ansible/site.yml