Skip to content

Commit 232964c

Browse files
authored
ref(tests): Add TestEnv class to Node integration tests. (#5633)
Refactored Node integration test helpers, to use a `TestEnv` instance for each test. This will help avoid explicitly passing `server` and `url` back and forth. Remix server-side tests also extend the `TestEnv` class to implement Remix-specific initialization logic.
1 parent b57e8af commit 232964c

File tree

49 files changed

+398
-441
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+398
-441
lines changed

packages/node-integration-tests/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ A custom server configuration can be used, supplying a script that exports a val
3333

3434
`utils/` contains helpers and Sentry-specific assertions that can be used in (`test.ts`).
3535

36-
`runServer` utility function returns an object containing `url` and [`http.Server`](https://nodejs.org/dist/latest-v16.x/docs/api/http.html#class-httpserver) instance for the created server. The `url` property is the base URL for the server. The `http.Server` instance is used to finish the server eventually.
36+
`TestEnv` class contains methods to create and execute requests on a test server instance. `TestEnv.init()` which starts a test server and returns a `TestEnv` instance must be called by each test. The test server is automatically shut down after each test, if a data collection helper method such as `getEnvelopeRequest` and `getAPIResponse` is used. Tests that do not use those helper methods will need to end the server manually.
3737

38-
The responsibility of ending the server is delegated to the test case. Data collection helpers such as `getEnvelopeRequest` and `getAPIResponse` expect the server instance to be available and finish it before their resolution. Tests that do not use those helpers will need to end the server manually.
38+
`TestEnv` instance has two public properties: `url` and `server`. The `url` property is the base URL for the server. The `http.Server` instance is used to finish the server eventually.
3939

4040
Nock interceptors are internally used to capture envelope requests by `getEnvelopeRequest` and `getMultipleEnvelopeRequest` helpers. After capturing required requests, the interceptors are removed. Nock can manually be used inside the test cases to intercept requests but should be removed before the test ends, as not to cause flakiness.
4141

packages/node-integration-tests/suites/express/handle-error/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../utils/index';
1+
import { assertSentryEvent, TestEnv } from '../../../utils/index';
22

33
test('should capture and send Express controller error.', async () => {
4-
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
5-
const event = await getEnvelopeRequest({ url: `${url}/express`, server });
4+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
5+
const event = await env.getEnvelopeRequest({ url: `${env.url}/express` });
66

77
expect((event[2] as any).exception.values[0].stacktrace.frames.length).toBeGreaterThan(0);
88

packages/node-integration-tests/suites/express/sentry-trace/baggage-header-assign/test.ts

+25-41
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
import * as path from 'path';
22

3-
import { getAPIResponse, runServer } from '../../../../utils/index';
3+
import { TestEnv } from '../../../../utils/index';
44
import { TestAPIResponse } from '../server';
55

66
test('Should not overwrite baggage if the incoming request already has Sentry baggage data.', async () => {
7-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
8-
9-
const response = (await getAPIResponse(
10-
{ url: `${url}/express`, server },
11-
{
12-
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
13-
},
14-
)) as TestAPIResponse;
7+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
8+
const response = (await env.getAPIResponse(`${env.url}/express`, {
9+
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
10+
})) as TestAPIResponse;
1511

1612
expect(response).toBeDefined();
1713
expect(response).toMatchObject({
@@ -23,15 +19,12 @@ test('Should not overwrite baggage if the incoming request already has Sentry ba
2319
});
2420

2521
test('Should propagate sentry trace baggage data from an incoming to an outgoing request.', async () => {
26-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
22+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
2723

28-
const response = (await getAPIResponse(
29-
{ url: `${url}/express`, server },
30-
{
31-
'sentry-trace': '',
32-
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv,dogs=great',
33-
},
34-
)) as TestAPIResponse;
24+
const response = (await env.getAPIResponse(`${env.url}/express`, {
25+
'sentry-trace': '',
26+
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv,dogs=great',
27+
})) as TestAPIResponse;
3528

3629
expect(response).toBeDefined();
3730
expect(response).toMatchObject({
@@ -43,14 +36,11 @@ test('Should propagate sentry trace baggage data from an incoming to an outgoing
4336
});
4437

4538
test('Should propagate empty baggage if sentry-trace header is present in incoming request but no baggage header', async () => {
46-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
39+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
4740

48-
const response = (await getAPIResponse(
49-
{ url: `${url}/express`, server },
50-
{
51-
'sentry-trace': '',
52-
},
53-
)) as TestAPIResponse;
41+
const response = (await env.getAPIResponse(`${env.url}/express`, {
42+
'sentry-trace': '',
43+
})) as TestAPIResponse;
5444

5545
expect(response).toBeDefined();
5646
expect(response).toMatchObject({
@@ -62,15 +52,12 @@ test('Should propagate empty baggage if sentry-trace header is present in incomi
6252
});
6353

6454
test('Should propagate empty sentry and ignore original 3rd party baggage entries if sentry-trace header is present', async () => {
65-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
55+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
6656

67-
const response = (await getAPIResponse(
68-
{ url: `${url}/express`, server },
69-
{
70-
'sentry-trace': '',
71-
baggage: 'foo=bar',
72-
},
73-
)) as TestAPIResponse;
57+
const response = (await env.getAPIResponse(`${env.url}/express`, {
58+
'sentry-trace': '',
59+
baggage: 'foo=bar',
60+
})) as TestAPIResponse;
7461

7562
expect(response).toBeDefined();
7663
expect(response).toMatchObject({
@@ -82,9 +69,9 @@ test('Should propagate empty sentry and ignore original 3rd party baggage entrie
8269
});
8370

8471
test('Should populate and propagate sentry baggage if sentry-trace header does not exist', async () => {
85-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
72+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
8673

87-
const response = (await getAPIResponse({ url: `${url}/express`, server }, {})) as TestAPIResponse;
74+
const response = (await env.getAPIResponse(`${env.url}/express`, {})) as TestAPIResponse;
8875

8976
expect(response).toBeDefined();
9077
expect(response).toMatchObject({
@@ -99,14 +86,11 @@ test('Should populate and propagate sentry baggage if sentry-trace header does n
9986
});
10087

10188
test('Should populate Sentry and ignore 3rd party content if sentry-trace header does not exist', async () => {
102-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
89+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
10390

104-
const response = (await getAPIResponse(
105-
{ url: `${url}/express`, server },
106-
{
107-
baggage: 'foo=bar,bar=baz',
108-
},
109-
)) as TestAPIResponse;
91+
const response = (await env.getAPIResponse(`${env.url}/express`, {
92+
baggage: 'foo=bar,bar=baz',
93+
})) as TestAPIResponse;
11094

11195
expect(response).toBeDefined();
11296
expect(response).toMatchObject({

packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out-bad-tx-name/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as path from 'path';
22

3-
import { getAPIResponse, runServer } from '../../../../utils/index';
3+
import { TestEnv } from '../../../../utils/index';
44
import { TestAPIResponse } from '../server';
55

66
test('Does not include transaction name if transaction source is not set', async () => {
7-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
7+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
88

9-
const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
9+
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;
1010
const baggageString = response.test_data.baggage;
1111

1212
expect(response).toBeDefined();

packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as path from 'path';
22

3-
import { getAPIResponse, runServer } from '../../../../utils/index';
3+
import { TestEnv } from '../../../../utils/index';
44
import { TestAPIResponse } from '../server';
55

66
test('should attach a `baggage` header to an outgoing request.', async () => {
7-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
7+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
88

9-
const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
9+
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;
1010

1111
expect(response).toBeDefined();
1212
expect(response).toMatchObject({

packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/test.ts

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
import * as path from 'path';
22

3-
import { getAPIResponse, runServer } from '../../../../utils/index';
3+
import { TestEnv } from '../../../../utils/index';
44
import { TestAPIResponse } from '../server';
55

66
test('should ignore sentry-values in `baggage` header of a third party vendor and overwrite them with incoming DSC', async () => {
7-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
7+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
88

9-
const response = (await getAPIResponse(
10-
{ url: `${url}/express`, server },
11-
{
12-
'sentry-trace': '',
13-
baggage: 'sentry-release=2.1.0,sentry-environment=myEnv',
14-
},
15-
)) as TestAPIResponse;
9+
const response = (await env.getAPIResponse(`${env.url}/express`, {
10+
'sentry-trace': '',
11+
baggage: 'sentry-release=2.1.0,sentry-environment=myEnv',
12+
})) as TestAPIResponse;
1613

1714
expect(response).toBeDefined();
1815
expect(response).toMatchObject({
@@ -24,9 +21,9 @@ test('should ignore sentry-values in `baggage` header of a third party vendor an
2421
});
2522

2623
test('should ignore sentry-values in `baggage` header of a third party vendor and overwrite them with new DSC', async () => {
27-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
24+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
2825

29-
const response = (await getAPIResponse({ url: `${url}/express`, server }, {})) as TestAPIResponse;
26+
const response = (await env.getAPIResponse(`${env.url}/express`, {})) as TestAPIResponse;
3027

3128
expect(response).toBeDefined();
3229
expect(response).toMatchObject({

packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/test.ts

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
import * as path from 'path';
22

3-
import { getAPIResponse, runServer } from '../../../../utils/index';
3+
import { TestEnv } from '../../../../utils/index';
44
import { TestAPIResponse } from '../server';
55

66
test('should merge `baggage` header of a third party vendor with the Sentry DSC baggage items', async () => {
7-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
7+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
88

9-
const response = (await getAPIResponse(
10-
{ url: `${url}/express`, server },
11-
{
12-
'sentry-trace': '',
13-
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
14-
},
15-
)) as TestAPIResponse;
9+
const response = (await env.getAPIResponse(`${env.url}/express`, {
10+
'sentry-trace': '',
11+
baggage: 'sentry-release=2.0.0,sentry-environment=myEnv',
12+
})) as TestAPIResponse;
1613

1714
expect(response).toBeDefined();
1815
expect(response).toMatchObject({

packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as path from 'path';
22

3-
import { getAPIResponse, runServer } from '../../../../utils/index';
3+
import { TestEnv } from '../../../../utils/index';
44
import { TestAPIResponse } from '../server';
55

66
test('Includes transaction in baggage if the transaction name is parameterized', async () => {
7-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
7+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '.')}/server.ts`);
88

9-
const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
9+
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;
1010

1111
expect(response).toBeDefined();
1212
expect(response).toMatchObject({

packages/node-integration-tests/suites/express/sentry-trace/trace-header-assign/test.ts

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
import { TRACEPARENT_REGEXP } from '@sentry/utils';
22
import * as path from 'path';
33

4-
import { getAPIResponse, runServer } from '../../../../utils/index';
4+
import { TestEnv } from '../../../../utils/index';
55
import { TestAPIResponse } from '../server';
66

77
test('Should assign `sentry-trace` header which sets parent trace id of an outgoing request.', async () => {
8-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
8+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
99

10-
const response = (await getAPIResponse(
11-
{ url: `${url}/express`, server },
12-
{
13-
'sentry-trace': '12312012123120121231201212312012-1121201211212012-0',
14-
},
15-
)) as TestAPIResponse;
10+
const response = (await env.getAPIResponse(`${env.url}/express`, {
11+
'sentry-trace': '12312012123120121231201212312012-1121201211212012-0',
12+
})) as TestAPIResponse;
1613

1714
expect(response).toBeDefined();
1815
expect(response).toMatchObject({

packages/node-integration-tests/suites/express/sentry-trace/trace-header-out/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { TRACEPARENT_REGEXP } from '@sentry/utils';
22
import * as path from 'path';
33

4-
import { getAPIResponse, runServer } from '../../../../utils/index';
4+
import { TestEnv } from '../../../../utils/index';
55
import { TestAPIResponse } from '../server';
66

77
test('should attach a `sentry-trace` header to an outgoing request.', async () => {
8-
const { url, server } = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
8+
const env = await TestEnv.init(__dirname, `${path.resolve(__dirname, '..')}/server.ts`);
99

10-
const response = (await getAPIResponse({ url: `${url}/express`, server })) as TestAPIResponse;
10+
const response = (await env.getAPIResponse(`${env.url}/express`)) as TestAPIResponse;
1111

1212
expect(response).toBeDefined();
1313
expect(response).toMatchObject({

packages/node-integration-tests/suites/express/tracing/test.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { assertSentryTransaction, getEnvelopeRequest, runServer } from '../../../utils/index';
1+
import { assertSentryTransaction, TestEnv } from '../../../utils/index';
22

33
test('should create and send transactions for Express routes and spans for middlewares.', async () => {
4-
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
5-
const envelope = await getEnvelopeRequest({ url: `${url}/express`, server }, { envelopeType: 'transaction' });
4+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
5+
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/express`, envelopeType: 'transaction' });
66

77
expect(envelope).toHaveLength(3);
88

@@ -29,8 +29,8 @@ test('should create and send transactions for Express routes and spans for middl
2929
});
3030

3131
test('should set a correct transaction name for routes specified in RegEx', async () => {
32-
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
33-
const envelope = await getEnvelopeRequest({ url: `${url}/regex`, server }, { envelopeType: 'transaction' });
32+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
33+
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/regex`, envelopeType: 'transaction' });
3434

3535
expect(envelope).toHaveLength(3);
3636

@@ -57,8 +57,8 @@ test('should set a correct transaction name for routes specified in RegEx', asyn
5757
test.each([['array1'], ['array5']])(
5858
'should set a correct transaction name for routes consisting of arrays of routes',
5959
async segment => {
60-
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
61-
const envelope = await getEnvelopeRequest({ url: `${url}/${segment}`, server }, { envelopeType: 'transaction' });
60+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
61+
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/${segment}`, envelopeType: 'transaction' });
6262

6363
expect(envelope).toHaveLength(3);
6464

@@ -93,8 +93,8 @@ test.each([
9393
['arr/requiredPath/optionalPath/'],
9494
['arr/requiredPath/optionalPath/lastParam'],
9595
])('should handle more complex regexes in route arrays correctly', async segment => {
96-
const { url, server } = await runServer(__dirname, `${__dirname}/server.ts`);
97-
const envelope = await getEnvelopeRequest({ url: `${url}/${segment}`, server }, { envelopeType: 'transaction' });
96+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
97+
const envelope = await env.getEnvelopeRequest({ url: `${env.url}/${segment}`, envelopeType: 'transaction' });
9898

9999
expect(envelope).toHaveLength(3);
100100

packages/node-integration-tests/suites/public-api/addBreadcrumb/empty-obj/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../../utils';
1+
import { assertSentryEvent, TestEnv } from '../../../../utils';
22

33
test('should add an empty breadcrumb, when an empty object is given', async () => {
4-
const config = await runServer(__dirname);
5-
const envelope = await getEnvelopeRequest(config);
4+
const env = await TestEnv.init(__dirname);
5+
const envelope = await env.getEnvelopeRequest();
66

77
expect(envelope).toHaveLength(3);
88

packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../../utils';
1+
import { assertSentryEvent, TestEnv } from '../../../../utils';
22

33
test('should add multiple breadcrumbs', async () => {
4-
const config = await runServer(__dirname);
5-
const events = await getEnvelopeRequest(config);
4+
const env = await TestEnv.init(__dirname);
5+
const events = await env.getEnvelopeRequest();
66

77
assertSentryEvent(events[2], {
88
message: 'test_multi_breadcrumbs',

packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../../utils';
1+
import { assertSentryEvent, TestEnv } from '../../../../utils';
22

33
test('should add a simple breadcrumb', async () => {
4-
const config = await runServer(__dirname);
5-
const event = await getEnvelopeRequest(config);
4+
const env = await TestEnv.init(__dirname);
5+
const event = await env.getEnvelopeRequest();
66

77
assertSentryEvent(event[2], {
88
message: 'test_simple',

packages/node-integration-tests/suites/public-api/captureException/catched-error/test.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils';
1+
import { assertSentryEvent, TestEnv } from '../../../../utils';
22

33
test('should work inside catch block', async () => {
4-
const config = await runServer(__dirname);
5-
const events = await getMultipleEnvelopeRequest(config, { count: 1 });
4+
const env = await TestEnv.init(__dirname);
5+
const event = await env.getEnvelopeRequest();
66

7-
assertSentryEvent(events[0][2], {
7+
assertSentryEvent(event[2], {
88
exception: {
99
values: [
1010
{

0 commit comments

Comments
 (0)