diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..d430b8ac --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +14.15.0 \ No newline at end of file diff --git a/example-application/data-access/order-repository.js b/example-application/data-access/order-repository.js index 94e515b6..c7b1daac 100644 --- a/example-application/data-access/order-repository.js +++ b/example-application/data-access/order-repository.js @@ -28,7 +28,6 @@ module.exports = class OrderReposiroty { } async addOrder(orderDetails) { - return await orderModel.create(orderDetails); } }; diff --git a/example-application/test/docker-compose.yml b/example-application/test/docker-compose.yml index a0b6e939..aed4d877 100644 --- a/example-application/test/docker-compose.yml +++ b/example-application/test/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3" +version: "3.6" services: db: image: postgres:11 @@ -10,10 +10,4 @@ services: container_name: "postgres-for-testing" ports: - "54320:5432" - volumes: - - data:/var/lib/postgresql/data -volumes: - data: - driver_opts: - type: tmpfs - device: tmpfs + tmpfs: /var/lib/postgresql/data \ No newline at end of file diff --git a/various-receipes/performance/readme.md b/various-receipes/performance/readme.md new file mode 100644 index 00000000..5fc22832 --- /dev/null +++ b/various-receipes/performance/readme.md @@ -0,0 +1,15 @@ +# Tests Performance + +## In-Memory DB +TL;DR: don't bother + +A common time-consuming operation on a typical server is database query, and slow tests are bad. +Database queries are expensive, also because the data resides on the drive, which is very slowly relative to other parts of the computer. +One method to speed up the database for testing and local-development is to run the database on RAM, which is way faster than the drive. + +But is it worth it? Probably not, and this is why: +1. SSD is pretty much a standard now, and they are blazingly fast compared to the old HHD. +2. It's preferred and easier to configure your database for non-durable settings to reduce database-related I/O drastically. +3. Usually, test scenarios don't involve much data, so the DB's I/O-speed becomes secondary. +4. The performance between in-memory and regular database with the correct settings is neglectable (if any). +Detailed benchmarks and results can be found [here](https://github.com/testjavascript/integration-tests-a-z/issues/9#issuecomment-710674437). \ No newline at end of file diff --git a/various-receipes/performance/test/orders-data-for-paramterized-test.json b/various-receipes/performance/test/orders-data-for-paramterized-test.json new file mode 100644 index 00000000..5edf0864 --- /dev/null +++ b/various-receipes/performance/test/orders-data-for-paramterized-test.json @@ -0,0 +1,702 @@ +[ + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ], + [ + { + "userId": 1, + "productId": 2, + "mode": "draft" + } + ] +] \ No newline at end of file diff --git a/various-receipes/performance/test/performance.test.js b/various-receipes/performance/test/performance.test.js new file mode 100644 index 00000000..1b67513d --- /dev/null +++ b/various-receipes/performance/test/performance.test.js @@ -0,0 +1,54 @@ +const request = require("supertest"); +const sinon = require("sinon"); +const nock = require("nock"); +const { + initializeWebServer, + stopWebServer +} = require('../../../example-application/api-under-test'); +const ordersData = require('./orders-data-for-paramterized-test.json'); + +let expressApp; +let sinonSandbox; + +beforeAll(async (done) => { + nock("http://localhost/user/").get(`/1`).reply(200, { + id: 1, + name: "John", + }).persist(); + + // ️️️✅ Best Practice: Place the backend under test within the same process + expressApp = await initializeWebServer(); + + // ️️️✅ Best Practice: use a sandbox for test doubles for proper clean-up between tests + sinonSandbox = sinon.createSandbox(); + + done(); +}); + +afterAll(async (done) => { + // ️️️✅ Best Practice: Clean-up resources after each run + await stopWebServer(); + done(); +}); + +beforeEach(() => { + if (sinonSandbox) { + sinonSandbox.restore(); + } +}); + +// ️️️✅ Best Practice: Structure tests +describe("/api", () => { + describe("POST /orders", () => { + test.each(ordersData)("When adding a new valid order, Then should get back 200 response", async (orderToAdd) => { + //Act + const receivedAPIResponse = await request(expressApp).post("/order").send(orderToAdd); + //Assert + const { + status, + } = receivedAPIResponse; + + expect(status).toBe(200); + }); + }); +});