From 5efece49164cd2f44f5e2771872c36cdd9225f73 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Sat, 12 Sep 2020 16:15:43 +0200 Subject: [PATCH] Add more realistic examples of inline snapshot testing --- .../apm_api_integration/basic/tests/index.ts | 5 +- .../basic/tests/traces/top_traces.ts | 330 +++--------------- .../common/match_snapshot.ts | 54 +-- 3 files changed, 72 insertions(+), 317 deletions(-) diff --git a/x-pack/test/apm_api_integration/basic/tests/index.ts b/x-pack/test/apm_api_integration/basic/tests/index.ts index 878b17e64bd92..bae94d89e7457 100644 --- a/x-pack/test/apm_api_integration/basic/tests/index.ts +++ b/x-pack/test/apm_api_integration/basic/tests/index.ts @@ -4,12 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ import { FtrProviderContext } from '../../common/ftr_provider_context'; -import * as matchSnapshot from '../../common/match_snapshot'; +import { registerMochaHooksForSnapshots } from '../../common/match_snapshot'; export default function apmApiIntegrationTests({ loadTestFile }: FtrProviderContext) { describe('APM specs (basic)', function () { - beforeEach(matchSnapshot.init); - afterEach(matchSnapshot.teardown); + registerMochaHooksForSnapshots(); this.tags('ciGroup1'); diff --git a/x-pack/test/apm_api_integration/basic/tests/traces/top_traces.ts b/x-pack/test/apm_api_integration/basic/tests/traces/top_traces.ts index 989c798f32bd4..c198d686aba16 100644 --- a/x-pack/test/apm_api_integration/basic/tests/traces/top_traces.ts +++ b/x-pack/test/apm_api_integration/basic/tests/traces/top_traces.ts @@ -44,7 +44,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns the correct number of buckets', async () => { - expect(response.body.items.length).to.be(33); + expectSnapshot(response.body.items.length).toMatchInline(`33`); }); it('returns the correct buckets', async () => { @@ -53,304 +53,56 @@ export default function ApiTest({ getService }: FtrProviderContext) { 'impact' ); - expectSnapshot(responseWithoutSamples).toMatchInline(` + const firstItem = responseWithoutSamples[0]; + const lastItem = responseWithoutSamples[responseWithoutSamples.length - 1]; + + const groups = responseWithoutSamples.map((item) => item.key).slice(0, 5); + + expectSnapshot(firstItem).toMatchInline(` + Object { + "averageResponseTime": 2577, + "impact": 0, + "key": Object { + "service.name": "opbeans-node", + "transaction.name": "GET /throw-error", + }, + "transactionsPerMinute": 0.5, + } + `); + + expectSnapshot(lastItem).toMatchInline(` + Object { + "averageResponseTime": 1745009, + "impact": 100, + "key": Object { + "service.name": "opbeans-node", + "transaction.name": "Process payment", + }, + "transactionsPerMinute": 0.25, + } + `); + + expectSnapshot(groups).toMatchInline(` Array [ Object { - "averageResponseTime": 2577, - "impact": 0, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /throw-error", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 3147, - "impact": 0.06552270160444405, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#orders", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 3392.5, - "impact": 0.09374344413758617, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#order", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 4713.5, - "impact": 0.24559517890858723, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#product", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 4757, - "impact": 0.25059559560997896, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/products/:id/customers", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 6787, - "impact": 0.4839483750082622, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#products", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 4749.666666666667, - "impact": 0.5227447114845778, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/orders/:id", - }, - "transactionsPerMinute": 0.75, - }, - Object { - "averageResponseTime": 7624.5, - "impact": 0.5802207655235637, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/orders", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 5098, - "impact": 0.582807187955318, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/stats", - }, - "transactionsPerMinute": 0.75, - }, - Object { - "averageResponseTime": 8181, - "impact": 0.6441916136689552, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/types/:id", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 20011, - "impact": 0.853921734857215, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "POST /api", - }, - "transactionsPerMinute": 0.25, - }, - Object { - "averageResponseTime": 6583, - "impact": 1.2172278724376455, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/products", - }, - "transactionsPerMinute": 1, - }, - Object { - "averageResponseTime": 33097, - "impact": 1.6060533780113861, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/products/top", - }, - "transactionsPerMinute": 0.25, - }, - Object { - "averageResponseTime": 4825, - "impact": 1.6450221426498186, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#topProducts", - }, - "transactionsPerMinute": 1.75, - }, - Object { - "averageResponseTime": 35846, - "impact": 1.7640550505645587, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /log-error", - }, - "transactionsPerMinute": 0.25, - }, - Object { - "averageResponseTime": 3742.153846153846, - "impact": 2.4998634943716573, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#customerWhoBought", - }, - "transactionsPerMinute": 3.25, - }, - Object { - "averageResponseTime": 3492.9285714285716, - "impact": 2.5144049360435208, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET static file", - }, - "transactionsPerMinute": 3.5, - }, - Object { - "averageResponseTime": 26992.5, - "impact": 2.8066131947777255, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/types", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 13516.5, - "impact": 2.8112687551548836, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/products/:id", - }, - "transactionsPerMinute": 1, - }, - Object { - "averageResponseTime": 20092, - "impact": 3.168195050736987, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api/customers", - }, - "transactionsPerMinute": 0.75, - }, - Object { - "averageResponseTime": 15535, - "impact": 3.275330415465657, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#stats", - }, - "transactionsPerMinute": 1, - }, - Object { - "averageResponseTime": 32667.5, - "impact": 3.458966408120217, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /log-message", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 16690.75, - "impact": 3.541042213287889, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#customers", - }, - "transactionsPerMinute": 1, - }, - Object { - "averageResponseTime": 33500, - "impact": 3.5546640380951287, - "key": Object { - "service.name": "client", - "transaction.name": "/customers", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 77000, - "impact": 4.129424578484989, - "key": Object { - "service.name": "client", - "transaction.name": "/products", - }, - "transactionsPerMinute": 0.25, - }, - Object { - "averageResponseTime": 19370.6, - "impact": 5.270496679320978, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "APIRestController#customer", - }, - "transactionsPerMinute": 1.25, - }, - Object { - "averageResponseTime": 81500, - "impact": 9.072365225837785, - "key": Object { - "service.name": "client", - "transaction.name": "/orders", - }, - "transactionsPerMinute": 0.5, - }, - Object { - "averageResponseTime": 14419.42857142857, - "impact": 11.30657439844125, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "ResourceHttpRequestHandler", - }, - "transactionsPerMinute": 3.5, - }, - Object { - "averageResponseTime": 270684, - "impact": 15.261616628971955, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "POST /api/orders", - }, - "transactionsPerMinute": 0.25, + "service.name": "opbeans-node", + "transaction.name": "GET /throw-error", }, Object { - "averageResponseTime": 36010.53846153846, - "impact": 26.61043592713186, - "key": Object { - "service.name": "opbeans-java", - "transaction.name": "DispatcherServlet#doGet", - }, - "transactionsPerMinute": 3.25, + "service.name": "opbeans-java", + "transaction.name": "APIRestController#orders", }, Object { - "averageResponseTime": 208000, - "impact": 35.56882613781033, - "key": Object { - "service.name": "client", - "transaction.name": "/dashboard", - }, - "transactionsPerMinute": 0.75, + "service.name": "opbeans-java", + "transaction.name": "APIRestController#order", }, Object { - "averageResponseTime": 49816.15625, - "impact": 91.32732325394932, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "GET /api", - }, - "transactionsPerMinute": 8, + "service.name": "opbeans-java", + "transaction.name": "APIRestController#product", }, Object { - "averageResponseTime": 1745009, - "impact": 100, - "key": Object { - "service.name": "opbeans-node", - "transaction.name": "Process payment", - }, - "transactionsPerMinute": 0.25, + "service.name": "opbeans-node", + "transaction.name": "GET /api/products/:id/customers", }, ] `); diff --git a/x-pack/test/apm_api_integration/common/match_snapshot.ts b/x-pack/test/apm_api_integration/common/match_snapshot.ts index efd9814023001..72f1b1d24635e 100644 --- a/x-pack/test/apm_api_integration/common/match_snapshot.ts +++ b/x-pack/test/apm_api_integration/common/match_snapshot.ts @@ -6,36 +6,42 @@ import { SnapshotState, toMatchSnapshot, toMatchInlineSnapshot } from 'jest-snapshot'; import path from 'path'; -import { Context } from 'mocha'; import expect from '@kbn/expect'; // @ts-expect-error import prettier from 'prettier'; +import { once } from 'lodash'; // @ts-expect-error import babelTraverse from '@babel/traverse'; -let testContext: { file: string; testTitle: string } | null = null; +let testContext: { + file: string; + testTitle: string; + getSnapshotContext: () => SnapshotContext; +} | null = null; interface SnapshotContext { snapshotState: InstanceType; } -export function init() { - // @ts-expect-error - const mochaContext = this as Context; - const file = mochaContext.currentTest?.file; - const testTitle = mochaContext.currentTest?.fullTitle(); +export function registerMochaHooksForSnapshots() { + beforeEach(function () { + const mochaContext = this; + const file = mochaContext.currentTest?.file; + const testTitle = mochaContext.currentTest?.fullTitle(); - if (!file || !testTitle) { - throw new Error(`file or fullTitle not found in Mocha test context`); - } + if (!file || !testTitle) { + throw new Error(`file or fullTitle not found in Mocha test context`); + } - testContext = { - file, - testTitle, - }; -} + testContext = { + file, + testTitle, + getSnapshotContext: once(() => getSnapshotContextOrThrow({ file, testTitle })), + }; + }); -export function teardown() { - testContext = null; + afterEach(() => { + testContext = null; + }); } const originalPrepareStackTrace = Error.prepareStackTrace; @@ -53,13 +59,7 @@ Error.prepareStackTrace = (error, structuredStackTrace) => { } }; -function getSnapshotContextOrThrow() { - if (!testContext) { - throw new Error('A current Mocha context is needed to match snapshots'); - } - - const { file, testTitle } = testContext; - +function getSnapshotContextOrThrow({ file, testTitle }: { file: string; testTitle: string }) { const dirname = path.dirname(file); const filename = path.basename(file); @@ -79,7 +79,11 @@ function getSnapshotContextOrThrow() { } export function expectSnapshot(received: any) { - const snapshotContext = getSnapshotContextOrThrow(); + if (!testContext) { + throw new Error('A current Mocha context is needed to match snapshots'); + } + + const snapshotContext = testContext.getSnapshotContext(); return { toMatch: expectToMatchSnapshot.bind(snapshotContext, received),