0
# Testing Framework
1
2
Built-in testing utilities for validating CDKTF applications and infrastructure configurations, providing synthesis testing, construct tree validation, and Jest matcher integration.
3
4
## Capabilities
5
6
### Testing Class
7
8
Core testing utilities for CDKTF applications, providing synthesis and validation capabilities.
9
10
```typescript { .api }
11
/**
12
* Testing utilities for CDKTF applications
13
*/
14
class Testing {
15
/**
16
* Create a test app with sensible defaults
17
* @param options - Optional app configuration
18
* @returns App instance configured for testing
19
*/
20
static app(options?: TestingAppConfig): App;
21
22
/**
23
* Synthesize a stack for testing purposes
24
* @param stack - Stack to synthesize
25
* @param runValidations - Whether to run validations
26
* @returns JSON string of synthesized configuration
27
*/
28
static synth(stack: TerraformStack, runValidations?: boolean): string;
29
30
/**
31
* Synthesize a stack to HCL format for testing
32
* @param stack - Stack to synthesize
33
* @param runValidations - Whether to run validations
34
* @param returnMetadata - Whether to include metadata
35
* @returns HCL string of synthesized configuration
36
*/
37
static synthHcl(stack: TerraformStack, runValidations?: boolean, returnMetadata?: boolean): string;
38
39
/**
40
* Synthesize within a callback scope
41
* @param fn - Callback function that creates constructs
42
* @returns JSON string of synthesized configuration
43
*/
44
static synthScope(fn: IScopeCallback): string;
45
46
/**
47
* Perform full synthesis including all metadata
48
* @param stack - Stack to synthesize
49
* @returns Complete synthesized output
50
*/
51
static fullSynth(stack: TerraformStack): string;
52
53
/**
54
* Render the construct tree structure
55
* @param construct - Root construct to render
56
* @returns String representation of the tree
57
*/
58
static renderConstructTree(construct: IConstruct): string;
59
60
/**
61
* Stub the CDKTF version for consistent testing
62
* @param app - App to stub version for
63
* @returns Modified app with stubbed version
64
*/
65
static stubVersion(app: App): App;
66
67
/**
68
* Enable future flags for testing new features
69
* @param app - App to enable flags for
70
* @returns Modified app with future flags
71
*/
72
static enableFutureFlags(app: App): App;
73
74
/**
75
* Set up fake cdktf.json path for testing
76
* @param app - App to configure
77
* @returns Modified app with fake path
78
*/
79
static fakeCdktfJsonPath(app: App): App;
80
81
/**
82
* Setup Jest matchers for CDKTF testing
83
*/
84
static setupJest(): void;
85
86
// Testing Matcher Methods
87
static toHaveDataSourceWithProperties(received: string, resourceType: string, properties?: Record<string, any>): boolean;
88
static toHaveDataSource(received: string, resourceType: string): boolean;
89
static toHaveResourceWithProperties(received: string, resourceType: string, properties?: Record<string, any>): boolean;
90
static toHaveResource(received: string, resourceType: string): boolean;
91
static toHaveProviderWithProperties(received: string, resourceType: string, properties?: Record<string, any>): boolean;
92
static toHaveProvider(received: string, resourceType: string): boolean;
93
static toBeValidTerraform(received: string): boolean;
94
}
95
```
96
97
**Usage Examples:**
98
99
```typescript
100
import { Testing, TerraformStack } from "cdktf";
101
import { Construct } from "constructs";
102
import { AwsInstance } from "../.gen/providers/aws/instance";
103
104
describe("Infrastructure Tests", () => {
105
let app: App;
106
let stack: TerraformStack;
107
108
beforeEach(() => {
109
app = Testing.app();
110
stack = new TerraformStack(app, "test-stack");
111
});
112
113
test("synthesizes valid terraform", () => {
114
// Create resources in the stack
115
new AwsInstance(stack, "instance", {
116
ami: "ami-12345678",
117
instanceType: "t2.micro"
118
});
119
120
// Synthesize and validate
121
const synthesized = Testing.synth(stack);
122
expect(synthesized).toMatchSnapshot();
123
});
124
125
test("generates correct HCL", () => {
126
new AwsInstance(stack, "instance", {
127
ami: "ami-12345678",
128
instanceType: "t2.micro"
129
});
130
131
const hcl = Testing.synthHcl(stack);
132
expect(hcl).toContain('resource "aws_instance" "instance"');
133
});
134
});
135
```
136
137
### Jest Matchers
138
139
CDKTF-specific Jest matchers for testing synthesized infrastructure configurations.
140
141
```typescript { .api }
142
/**
143
* Jest matcher to check if synthesized config contains a resource
144
* @param received - Synthesized JSON string
145
* @param resourceType - Terraform resource type
146
* @returns Matcher result
147
*/
148
function toHaveResource(received: string, resourceType: string): boolean;
149
150
/**
151
* Jest matcher to check if synthesized config contains a resource with specific properties
152
* @param received - Synthesized JSON string
153
* @param resourceType - Terraform resource type
154
* @param properties - Expected properties object
155
* @returns Matcher result
156
*/
157
function toHaveResourceWithProperties(
158
received: string,
159
resourceType: string,
160
properties: Record<string, any>
161
): boolean;
162
163
/**
164
* Jest matcher to check if synthesized config contains a data source
165
* @param received - Synthesized JSON string
166
* @param dataSourceType - Terraform data source type
167
* @returns Matcher result
168
*/
169
function toHaveDataSource(received: string, dataSourceType: string): boolean;
170
171
/**
172
* Jest matcher to check if synthesized config contains a data source with specific properties
173
* @param received - Synthesized JSON string
174
* @param dataSourceType - Terraform data source type
175
* @param properties - Expected properties object
176
* @returns Matcher result
177
*/
178
function toHaveDataSourceWithProperties(
179
received: string,
180
dataSourceType: string,
181
properties: Record<string, any>
182
): boolean;
183
184
/**
185
* Jest matcher to check if synthesized config contains a provider
186
* @param received - Synthesized JSON string
187
* @param providerType - Terraform provider type
188
* @returns Matcher result
189
*/
190
function toHaveProvider(received: string, providerType: string): boolean;
191
192
/**
193
* Jest matcher to check if synthesized config contains a provider with specific properties
194
* @param received - Synthesized JSON string
195
* @param providerType - Terraform provider type
196
* @param properties - Expected properties object
197
* @returns Matcher result
198
*/
199
function toHaveProviderWithProperties(
200
received: string,
201
providerType: string,
202
properties: Record<string, any>
203
): boolean;
204
205
/**
206
* Jest matcher to validate that the synthesized config is valid Terraform
207
* @param received - Synthesized JSON string
208
* @returns Matcher result
209
*/
210
function toBeValidTerraform(received: string): boolean;
211
```
212
213
**Usage Examples:**
214
215
```typescript
216
import { Testing, TerraformStack } from "cdktf";
217
import { AwsProvider } from "../.gen/providers/aws/provider";
218
import { AwsInstance } from "../.gen/providers/aws/instance";
219
import { DataAwsAmi } from "../.gen/providers/aws/data-aws-ami";
220
221
// Setup Jest matchers
222
Testing.setupJest();
223
224
describe("Resource Testing", () => {
225
test("creates correct resources", () => {
226
const app = Testing.app();
227
const stack = new TerraformStack(app, "test");
228
229
new AwsProvider(stack, "aws", {
230
region: "us-west-2"
231
});
232
233
new AwsInstance(stack, "web", {
234
ami: "ami-12345678",
235
instanceType: "t2.micro",
236
tags: {
237
Name: "web-server"
238
}
239
});
240
241
const synthesized = Testing.synth(stack);
242
243
// Test using CDKTF matchers
244
expect(synthesized).toHaveProvider("aws");
245
expect(synthesized).toHaveProviderWithProperties("aws", {
246
region: "us-west-2"
247
});
248
249
expect(synthesized).toHaveResource("aws_instance");
250
expect(synthesized).toHaveResourceWithProperties("aws_instance", {
251
instance_type: "t2.micro",
252
tags: {
253
Name: "web-server"
254
}
255
});
256
257
expect(synthesized).toBeValidTerraform();
258
});
259
260
test("includes data sources", () => {
261
const app = Testing.app();
262
const stack = new TerraformStack(app, "test");
263
264
new DataAwsAmi(stack, "ubuntu", {
265
mostRecent: true,
266
owners: ["099720109477"]
267
});
268
269
const synthesized = Testing.synth(stack);
270
expect(synthesized).toHaveDataSource("aws_ami");
271
});
272
});
273
```
274
275
### Test Utilities
276
277
Additional utilities for testing complex CDKTF applications.
278
279
```typescript { .api }
280
/**
281
* Callback function for scope-based synthesis
282
*/
283
interface IScopeCallback {
284
(scope: Construct): void;
285
}
286
287
/**
288
* Configuration for test apps
289
*/
290
interface TestingAppConfig extends AppConfig {
291
/**
292
* Whether to enable stack traces in test mode
293
* @default false
294
*/
295
readonly enableStackTrace?: boolean;
296
297
/**
298
* Fake values to use for context
299
*/
300
readonly fakeContext?: {[key: string]: any};
301
}
302
303
/**
304
* Assertion helpers for construct tree testing
305
*/
306
class ConstructTreeAssertion {
307
/**
308
* Assert that a construct exists in the tree
309
* @param tree - Construct tree string
310
* @param path - Path to the construct
311
*/
312
static hasConstruct(tree: string, path: string): boolean;
313
314
/**
315
* Assert construct count at a specific level
316
* @param tree - Construct tree string
317
* @param level - Tree level to check
318
* @param count - Expected count
319
*/
320
static hasConstructCount(tree: string, level: number, count: number): boolean;
321
}
322
```
323
324
**Usage Examples:**
325
326
```typescript
327
import { Testing, ConstructTreeAssertion } from "cdktf";
328
329
test("construct tree structure", () => {
330
const app = Testing.app();
331
const stack = new TerraformStack(app, "test");
332
333
// Add some constructs
334
new AwsInstance(stack, "web1", { /* config */ });
335
new AwsInstance(stack, "web2", { /* config */ });
336
337
const tree = Testing.renderConstructTree(app);
338
339
expect(ConstructTreeAssertion.hasConstruct(tree, "test/web1")).toBe(true);
340
expect(ConstructTreeAssertion.hasConstruct(tree, "test/web2")).toBe(true);
341
expect(ConstructTreeAssertion.hasConstructCount(tree, 2, 2)).toBe(true);
342
});
343
344
test("synthesis with callback", () => {
345
const synthesized = Testing.synthScope((scope) => {
346
new TerraformOutput(scope, "test-output", {
347
value: "test-value"
348
});
349
});
350
351
expect(synthesized).toContain('"test-output"');
352
expect(synthesized).toContain('"test-value"');
353
});
354
```