@xano/developer-mcp 1.0.36 → 1.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/xanoscript.js +9 -4
- package/dist/xanoscript.test.js +3 -2
- package/dist/xanoscript_docs/README.md +5 -1
- package/dist/xanoscript_docs/docs_index.json +10 -5
- package/dist/xanoscript_docs/tables.md +9 -0
- package/dist/xanoscript_docs/{testing.md → unit-testing.md} +15 -3
- package/dist/xanoscript_docs/workflow-tests.md +333 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -346,7 +346,8 @@ Retrieves XanoScript programming language documentation with context-aware suppo
|
|
|
346
346
|
| `agents` | AI agent configuration with LLM providers and tools |
|
|
347
347
|
| `tools` | AI tools for agents and MCP servers |
|
|
348
348
|
| `mcp-servers` | MCP server definitions exposing tools |
|
|
349
|
-
| `testing` | Unit tests, mocks, and assertions |
|
|
349
|
+
| `unit-testing` | Unit tests, mocks, and assertions within functions, APIs, and middleware |
|
|
350
|
+
| `workflow-tests` | End-to-end workflow tests with data sources and tags |
|
|
350
351
|
| `integrations` | External service integrations index |
|
|
351
352
|
| `integrations/cloud-storage` | AWS S3, Azure Blob, and GCP Storage |
|
|
352
353
|
| `integrations/search` | Elasticsearch, OpenSearch, and Algolia |
|
|
@@ -542,7 +543,8 @@ The server also exposes XanoScript documentation as MCP resources for direct acc
|
|
|
542
543
|
| `xanoscript://docs/agents` | AI agent configuration |
|
|
543
544
|
| `xanoscript://docs/tools` | AI tools for agents |
|
|
544
545
|
| `xanoscript://docs/mcp-servers` | MCP server definitions |
|
|
545
|
-
| `xanoscript://docs/testing` | Unit tests and mocks |
|
|
546
|
+
| `xanoscript://docs/unit-testing` | Unit tests and mocks |
|
|
547
|
+
| `xanoscript://docs/workflow-tests` | End-to-end workflow tests |
|
|
546
548
|
| `xanoscript://docs/integrations` | External service integrations index |
|
|
547
549
|
| `xanoscript://docs/integrations/cloud-storage` | AWS S3, Azure Blob, GCP Storage |
|
|
548
550
|
| `xanoscript://docs/integrations/search` | Elasticsearch, OpenSearch, Algolia |
|
package/dist/xanoscript.js
CHANGED
|
@@ -81,10 +81,15 @@ export const XANOSCRIPT_DOCS_V2 = {
|
|
|
81
81
|
applyTo: ["mcp_servers/**/*.xs"],
|
|
82
82
|
description: "MCP server definitions exposing tools",
|
|
83
83
|
},
|
|
84
|
-
testing: {
|
|
85
|
-
file: "testing.md",
|
|
86
|
-
applyTo: ["functions/**/*.xs", "apis/**/*.xs"],
|
|
87
|
-
description: "Unit tests, mocks, and assertions",
|
|
84
|
+
"unit-testing": {
|
|
85
|
+
file: "unit-testing.md",
|
|
86
|
+
applyTo: ["functions/**/*.xs", "apis/**/*.xs", "middleware/**/*.xs"],
|
|
87
|
+
description: "Unit tests, mocks, and assertions within functions, APIs, and middleware",
|
|
88
|
+
},
|
|
89
|
+
"workflow-tests": {
|
|
90
|
+
file: "workflow-tests.md",
|
|
91
|
+
applyTo: ["workflow_test/**/*.xs"],
|
|
92
|
+
description: "End-to-end workflow tests with data source selection and tags",
|
|
88
93
|
},
|
|
89
94
|
integrations: {
|
|
90
95
|
file: "integrations.md",
|
package/dist/xanoscript.test.js
CHANGED
|
@@ -23,7 +23,8 @@ describe("xanoscript module", () => {
|
|
|
23
23
|
"agents",
|
|
24
24
|
"tools",
|
|
25
25
|
"mcp-servers",
|
|
26
|
-
"testing",
|
|
26
|
+
"unit-testing",
|
|
27
|
+
"workflow-tests",
|
|
27
28
|
"integrations",
|
|
28
29
|
"integrations/cloud-storage",
|
|
29
30
|
"integrations/search",
|
|
@@ -68,7 +69,7 @@ describe("xanoscript module", () => {
|
|
|
68
69
|
expect(result).toContain("apis");
|
|
69
70
|
expect(result).toContain("types");
|
|
70
71
|
expect(result).toContain("database");
|
|
71
|
-
expect(result).toContain("testing");
|
|
72
|
+
expect(result).toContain("unit-testing");
|
|
72
73
|
expect(result).toContain("addons");
|
|
73
74
|
});
|
|
74
75
|
it("should match functions files", () => {
|
|
@@ -19,6 +19,7 @@ XanoScript is the declarative scripting language for [Xano](https://xano.com), a
|
|
|
19
19
|
| `tool` | `tool/{name}.xs` | Tools for AI agents |
|
|
20
20
|
| `mcp_server` | `mcp_server/{name}.xs` | MCP server definitions |
|
|
21
21
|
| `mcp_server_trigger`| `mcp_server/trigger/{name}.xs` | MCP server event handlers |
|
|
22
|
+
| `workflow_test` | `workflow_test/{name}.xs` | End-to-end workflow tests |
|
|
22
23
|
| `addon` | `addon/{name}.xs` | Subqueries for related data |
|
|
23
24
|
| `middleware` | `middleware/{name}.xs` | Request/response interceptors |
|
|
24
25
|
| `branch` | `branch.xs` | Branch-level configuration |
|
|
@@ -65,6 +66,8 @@ project/
|
|
|
65
66
|
│ ├── my_server.xs # MCP server definitions
|
|
66
67
|
│ └── trigger/
|
|
67
68
|
│ └── on_connect.xs # MCP server triggers
|
|
69
|
+
├── workflow_test/
|
|
70
|
+
│ └── checkout_flow.xs # End-to-end workflow tests
|
|
68
71
|
├── middleware/
|
|
69
72
|
│ └── auth_check.xs # Request/response interceptors
|
|
70
73
|
├── addon/
|
|
@@ -229,7 +232,8 @@ Use `xanoscript_docs({ topic: "<topic>" })` to retrieve documentation.
|
|
|
229
232
|
|
|
230
233
|
| Topic | Description | Key Sections |
|
|
231
234
|
| ----------- | ---------------------------------------------------------- | ------------ |
|
|
232
|
-
| `testing`
|
|
235
|
+
| `unit-testing` | Unit tests, mocks, and assertions within functions, APIs, and middleware | Test Syntax, Assertions, Mocking |
|
|
236
|
+
| `workflow-tests` | End-to-end workflow tests with data sources and tags | Data Sources, Tags, Common Patterns |
|
|
233
237
|
| `debugging` | Logging, inspecting, and debugging XanoScript execution | debug.log, Inspection |
|
|
234
238
|
| `frontend` | Static frontend development and deployment | File Structure |
|
|
235
239
|
| `run` | Run job and service configurations for the Xano Job Runner | Jobs, Services |
|
|
@@ -128,10 +128,15 @@
|
|
|
128
128
|
"purpose": "Request interceptors",
|
|
129
129
|
"aliases": ["interceptors", "hooks"]
|
|
130
130
|
},
|
|
131
|
-
"testing": {
|
|
132
|
-
"file": "testing.md",
|
|
133
|
-
"purpose": "Unit
|
|
134
|
-
"aliases": ["tests", "unit-tests"]
|
|
131
|
+
"unit-testing": {
|
|
132
|
+
"file": "unit-testing.md",
|
|
133
|
+
"purpose": "Unit tests, mocks, and assertions",
|
|
134
|
+
"aliases": ["tests", "unit-tests", "mocks", "assertions"]
|
|
135
|
+
},
|
|
136
|
+
"workflow-tests": {
|
|
137
|
+
"file": "workflow-tests.md",
|
|
138
|
+
"purpose": "End-to-end workflow tests",
|
|
139
|
+
"aliases": ["e2e", "workflow", "integration-tests"]
|
|
135
140
|
},
|
|
136
141
|
"debugging": {
|
|
137
142
|
"file": "debugging.md",
|
|
@@ -185,7 +190,7 @@
|
|
|
185
190
|
|
|
186
191
|
"constructs": {
|
|
187
192
|
"table": { "file": "tables.md", "triggers": "triggers.md" },
|
|
188
|
-
"function": { "file": "functions.md", "testing": "testing.md" },
|
|
193
|
+
"function": { "file": "functions.md", "testing": "unit-testing.md" },
|
|
189
194
|
"query": { "file": "apis.md", "auth": "security.md" },
|
|
190
195
|
"api_group": { "file": "apis.md" },
|
|
191
196
|
"task": { "file": "tasks.md" },
|
|
@@ -166,6 +166,15 @@ The `size` parameter specifies the vector dimensions (must match your embedding
|
|
|
166
166
|
|
|
167
167
|
## Indexes
|
|
168
168
|
|
|
169
|
+
Each index field supports an optional `op` property to control sort order or operator class:
|
|
170
|
+
|
|
171
|
+
| Index Type | `op` Values | Default | Description |
|
|
172
|
+
|------------|-------------|---------|-------------|
|
|
173
|
+
| `btree` | `asc`, `desc` | `asc` | Sort direction |
|
|
174
|
+
| `gin` | `jsonb_path_op` | — | Operator class for JSON containment queries |
|
|
175
|
+
| `search` | `A`, `B`, `C`, `D` | — | Weight category (A = highest relevance) |
|
|
176
|
+
| `vector` | `vector_cosine_ops` | — | Distance function for similarity search |
|
|
177
|
+
|
|
169
178
|
### Primary Key
|
|
170
179
|
|
|
171
180
|
```xs
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
applyTo: "function/**/*.xs, api/**/*.xs"
|
|
2
|
+
applyTo: "function/**/*.xs, api/**/*.xs, middleware/**/*.xs"
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# Testing
|
|
5
|
+
# Unit Testing
|
|
6
6
|
|
|
7
|
-
Unit tests and
|
|
7
|
+
Unit tests, mocks, and assertions defined inline within functions, API endpoints, and middleware. Unit tests validate individual construct behavior in isolation — for end-to-end workflow testing across multiple constructs, see `workflow-tests`.
|
|
8
8
|
|
|
9
9
|
## Quick Reference
|
|
10
10
|
|
|
@@ -330,3 +330,15 @@ function "calculate_discount" {
|
|
|
330
330
|
3. **Descriptive test names** - Explain what's being tested
|
|
331
331
|
4. **One assertion focus** - Each test verifies one behavior
|
|
332
332
|
5. **Keep tests independent** - No shared state between tests
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Related Topics
|
|
337
|
+
|
|
338
|
+
| Topic | Description |
|
|
339
|
+
| ----------------- | -------------------------------------------------- |
|
|
340
|
+
| `workflow-tests` | End-to-end workflow tests across multiple constructs |
|
|
341
|
+
| `functions` | Reusable function stacks (where unit tests live) |
|
|
342
|
+
| `apis` | API endpoints (where unit tests live) |
|
|
343
|
+
| `middleware` | Request/response interceptors (where unit tests live) |
|
|
344
|
+
| `debugging` | Logging and debugging test execution |
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "workflow_test/**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Workflow Tests
|
|
6
|
+
|
|
7
|
+
End-to-end workflow tests that call Xano constructs (APIs, functions, tasks, etc.) and validate results with assertions. The `stack` block supports all standard XanoScript statements (variables, conditionals, loops, database operations, etc.) in addition to the call functions and assertions documented below.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
```xs
|
|
12
|
+
workflow_test "<name>" {
|
|
13
|
+
datasource = "live"
|
|
14
|
+
stack { ... }
|
|
15
|
+
tags = ["tag1", "tag2"]
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| Property | Required | Default | Description |
|
|
20
|
+
| ------------ | -------- | ------- | ------------------------------------------------ |
|
|
21
|
+
| `datasource` | No | (empty) | Data source to run against: custom name or `"live"` (not recommended — clones entire datasource) |
|
|
22
|
+
| `stack` | Yes | — | Test execution logic using call functions and assertions |
|
|
23
|
+
| `tags` | No | `[]` | Tags for organizing and filtering workflow tests |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Call Functions
|
|
28
|
+
|
|
29
|
+
Call functions invoke Xano constructs and capture their results. Each returns a result that can be stored with `as $variable`.
|
|
30
|
+
|
|
31
|
+
| Call Function | Description | Required Properties |
|
|
32
|
+
| ----------------- | ------------------------------ | ------------------------------------ |
|
|
33
|
+
| `api.call` | Call an API endpoint | `api_group`, `verb` (on call), optional `headers` |
|
|
34
|
+
| `addon.call` | Call an addon | — |
|
|
35
|
+
| `function.call` | Call a function | optional `input` |
|
|
36
|
+
| `middleware.call` | Call a middleware | `input` with `vars` and `type` |
|
|
37
|
+
| `task.call` | Call a task | — |
|
|
38
|
+
| `tool.call` | Call a tool | — |
|
|
39
|
+
| `trigger.call` | Call a trigger | `input` with `new`, `old`, `action`, `datasource` |
|
|
40
|
+
|
|
41
|
+
### api.call
|
|
42
|
+
|
|
43
|
+
```xs
|
|
44
|
+
api.call "<endpoint_name>" verb=GET {
|
|
45
|
+
api_group = "<group_name>"
|
|
46
|
+
headers = '["Content-Type: application/json"]'
|
|
47
|
+
} as $result
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### addon.call
|
|
51
|
+
|
|
52
|
+
```xs
|
|
53
|
+
addon.call "<addon_name>" as $result
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### function.call
|
|
57
|
+
|
|
58
|
+
```xs
|
|
59
|
+
function.call "<function_name>" {
|
|
60
|
+
input = { key: "value" }
|
|
61
|
+
} as $result
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### middleware.call
|
|
65
|
+
|
|
66
|
+
```xs
|
|
67
|
+
middleware.call "<middleware_name>" {
|
|
68
|
+
input = {vars: {}, type: "pre"}
|
|
69
|
+
} as $result
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### task.call
|
|
73
|
+
|
|
74
|
+
```xs
|
|
75
|
+
task.call "<task_name>" as $result
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### tool.call
|
|
79
|
+
|
|
80
|
+
```xs
|
|
81
|
+
tool.call "<tool_name>" as $result
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### trigger.call
|
|
85
|
+
|
|
86
|
+
```xs
|
|
87
|
+
trigger.call "<trigger_name>" {
|
|
88
|
+
input = {new: {}, old: {}, action: "", datasource: ""}
|
|
89
|
+
} as $result
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Assertions
|
|
95
|
+
|
|
96
|
+
Assertions validate results within the workflow test stack. Each takes a variable reference as the target.
|
|
97
|
+
|
|
98
|
+
### Quick Reference
|
|
99
|
+
|
|
100
|
+
| Assertion | Purpose | Properties |
|
|
101
|
+
| -------------------------- | ----------------------- | ------------------- |
|
|
102
|
+
| `expect.to_be_defined` | Value is defined | — |
|
|
103
|
+
| `expect.to_not_be_defined` | Value is not defined | — |
|
|
104
|
+
| `expect.to_be_empty` | Value is empty | — |
|
|
105
|
+
| `expect.to_be_true` | Value is true | — |
|
|
106
|
+
| `expect.to_be_false` | Value is false | — |
|
|
107
|
+
| `expect.to_be_null` | Value is null | — |
|
|
108
|
+
| `expect.to_not_be_null` | Value is not null | — |
|
|
109
|
+
| `expect.to_be_in_the_past` | Timestamp is in the past| — |
|
|
110
|
+
| `expect.to_be_in_the_future`| Timestamp is in the future| — |
|
|
111
|
+
| `expect.to_equal` | Exact match | `value` |
|
|
112
|
+
| `expect.to_not_equal` | Not equal | `value` |
|
|
113
|
+
| `expect.to_be_greater_than`| Greater than | `value` |
|
|
114
|
+
| `expect.to_be_less_than` | Less than | `value` |
|
|
115
|
+
| `expect.to_be_within` | Within range | `min`, `max` |
|
|
116
|
+
| `expect.to_contain` | Contains value | `value` |
|
|
117
|
+
| `expect.to_start_with` | Starts with string | `value` |
|
|
118
|
+
| `expect.to_end_with` | Ends with string | `value` |
|
|
119
|
+
| `expect.to_match` | Regex match | `value` (pattern) |
|
|
120
|
+
| `expect.to_throw` | Stack throws error | `stack`, `exception` |
|
|
121
|
+
|
|
122
|
+
### No-Property Assertions
|
|
123
|
+
|
|
124
|
+
These take only the target variable:
|
|
125
|
+
|
|
126
|
+
```xs
|
|
127
|
+
expect.to_be_defined ($var)
|
|
128
|
+
expect.to_not_be_defined ($var)
|
|
129
|
+
expect.to_be_empty ($var)
|
|
130
|
+
expect.to_be_true ($var)
|
|
131
|
+
expect.to_be_false ($var)
|
|
132
|
+
expect.to_be_null ($var)
|
|
133
|
+
expect.to_not_be_null ($var)
|
|
134
|
+
expect.to_be_in_the_past ($var)
|
|
135
|
+
expect.to_be_in_the_future ($var)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Value Assertions
|
|
139
|
+
|
|
140
|
+
These take a `value` property for comparison. The value can be a literal or a variable reference:
|
|
141
|
+
|
|
142
|
+
```xs
|
|
143
|
+
expect.to_equal ($var) { value = "expected" }
|
|
144
|
+
expect.to_not_equal ($var) { value = $other_var }
|
|
145
|
+
expect.to_be_greater_than ($var) { value = 3 }
|
|
146
|
+
expect.to_be_less_than ($var) { value = $other_var }
|
|
147
|
+
expect.to_contain ($var) { value = "substring" }
|
|
148
|
+
expect.to_start_with ($var) { value = "prefix" }
|
|
149
|
+
expect.to_end_with ($var) { value = "suffix" }
|
|
150
|
+
|
|
151
|
+
// Regex pattern
|
|
152
|
+
expect.to_match ($var) { value = "^\\d+$" }
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Range Assertion
|
|
156
|
+
|
|
157
|
+
```xs
|
|
158
|
+
expect.to_be_within ($var) {
|
|
159
|
+
min = 1
|
|
160
|
+
max = 100
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Error Assertion
|
|
165
|
+
|
|
166
|
+
`expect.to_throw` wraps a `stack` block and checks that it throws a matching exception:
|
|
167
|
+
|
|
168
|
+
```xs
|
|
169
|
+
expect.to_throw {
|
|
170
|
+
stack {
|
|
171
|
+
security.create_uuid as $x1
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
exception = "error"
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Data Sources
|
|
181
|
+
|
|
182
|
+
The `datasource` property controls which data source the test runs against.
|
|
183
|
+
|
|
184
|
+
**Avoid using `datasource = "live"`.** When a workflow test runs, the entire datasource is cloned so that real data is not modified. This cloning step can be slow, especially for large datasources. Prefer running without a datasource or using a smaller custom datasource instead.
|
|
185
|
+
|
|
186
|
+
### Default (No Data Source) — Recommended
|
|
187
|
+
|
|
188
|
+
```xs
|
|
189
|
+
workflow_test "basic_check" {
|
|
190
|
+
stack {
|
|
191
|
+
function.call "health_check" as $result
|
|
192
|
+
expect.to_be_defined ($result)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Custom Data Source
|
|
198
|
+
|
|
199
|
+
```xs
|
|
200
|
+
workflow_test "staging_data_check" {
|
|
201
|
+
datasource = "staging"
|
|
202
|
+
stack {
|
|
203
|
+
function.call "get_products" as $products
|
|
204
|
+
expect.to_be_defined ($products)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Live Data Source (Not Recommended)
|
|
210
|
+
|
|
211
|
+
Using `datasource = "live"` clones the entire live datasource before running the test. Only use this when you specifically need to validate against production data.
|
|
212
|
+
|
|
213
|
+
```xs
|
|
214
|
+
workflow_test "live_data_check" {
|
|
215
|
+
datasource = "live"
|
|
216
|
+
stack {
|
|
217
|
+
function.call "get_active_users" as $users
|
|
218
|
+
expect.to_be_defined ($users)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Tags
|
|
226
|
+
|
|
227
|
+
Use tags to organize and filter workflow tests:
|
|
228
|
+
|
|
229
|
+
```xs
|
|
230
|
+
workflow_test "checkout_flow" {
|
|
231
|
+
tags = ["checkout", "critical", "e2e"]
|
|
232
|
+
stack {
|
|
233
|
+
function.call "create_cart" as $cart
|
|
234
|
+
expect.to_be_defined ($cart)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Complete Example
|
|
242
|
+
|
|
243
|
+
This example demonstrates all call functions and all assertion types:
|
|
244
|
+
|
|
245
|
+
```xs
|
|
246
|
+
workflow_test "comprehensive_test" {
|
|
247
|
+
datasource = "live"
|
|
248
|
+
|
|
249
|
+
stack {
|
|
250
|
+
// Call functions
|
|
251
|
+
api.call "test" verb=GET {
|
|
252
|
+
api_group = "test"
|
|
253
|
+
headers = '["Content-Type: application/json"]'
|
|
254
|
+
} as $endpoint1
|
|
255
|
+
|
|
256
|
+
addon.call "my_addon" as $addon1
|
|
257
|
+
function.call "my_function" {
|
|
258
|
+
input = {name: "Justin"}
|
|
259
|
+
} as $function1
|
|
260
|
+
|
|
261
|
+
middleware.call "my_middleware" {
|
|
262
|
+
input = {vars: {}, type: "pre"}
|
|
263
|
+
} as $middleware1
|
|
264
|
+
|
|
265
|
+
task.call "my_task" as $task1
|
|
266
|
+
tool.call "my_tool" as $tool1
|
|
267
|
+
trigger.call "my_trigger" {
|
|
268
|
+
input = {new: {}, old: {}, action: "", datasource: ""}
|
|
269
|
+
} as $trigger1
|
|
270
|
+
|
|
271
|
+
// No-property assertions
|
|
272
|
+
expect.to_be_defined ($endpoint1)
|
|
273
|
+
expect.to_be_empty ($addon1)
|
|
274
|
+
expect.to_be_false ($endpoint1)
|
|
275
|
+
expect.to_be_true ($addon1)
|
|
276
|
+
expect.to_be_null ($middleware1)
|
|
277
|
+
expect.to_not_be_null ($endpoint1)
|
|
278
|
+
expect.to_not_be_defined ($function1)
|
|
279
|
+
expect.to_be_in_the_past ($endpoint1)
|
|
280
|
+
expect.to_be_in_the_future ($endpoint1)
|
|
281
|
+
|
|
282
|
+
// Value assertions
|
|
283
|
+
expect.to_equal ($endpoint1) { value = $endpoint1 }
|
|
284
|
+
expect.to_not_equal ($endpoint1) { value = $addon1 }
|
|
285
|
+
expect.to_be_greater_than ($endpoint1) { value = 3 }
|
|
286
|
+
expect.to_be_less_than ($addon1) { value = $task1 }
|
|
287
|
+
expect.to_contain ($endpoint1) { value = "asdf" }
|
|
288
|
+
expect.to_start_with ($addon1) { value = "f" }
|
|
289
|
+
expect.to_end_with ($addon1) { value = "asdf" }
|
|
290
|
+
|
|
291
|
+
// Regex pattern
|
|
292
|
+
expect.to_match ($endpoint1) { value = ".*" }
|
|
293
|
+
|
|
294
|
+
// Range assertion
|
|
295
|
+
expect.to_be_within ($endpoint1) {
|
|
296
|
+
min = 1
|
|
297
|
+
max = 4
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Error assertion
|
|
301
|
+
expect.to_throw {
|
|
302
|
+
stack {
|
|
303
|
+
security.create_uuid as $x1
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
exception = "error"
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
tags = ["a", "b"]
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Best Practices
|
|
317
|
+
|
|
318
|
+
1. **Use descriptive names** — Name tests after the workflow being tested: `user_signup_flow`, `checkout_process`
|
|
319
|
+
2. **Tag for filtering** — Use tags like `critical`, `e2e`, `smoke` to organize test suites
|
|
320
|
+
3. **Avoid `datasource = "live"`** — The entire datasource is cloned before each test run, which can be slow. Use no datasource or a smaller custom datasource instead
|
|
321
|
+
4. **Keep tests independent** — Each workflow test should be self-contained and not depend on other tests
|
|
322
|
+
5. **Use assertions over preconditions** — Prefer `expect.*` assertions for clearer test intent
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Related Topics
|
|
327
|
+
|
|
328
|
+
| Topic | Description |
|
|
329
|
+
| -------------- | ------------------------------------------ |
|
|
330
|
+
| `unit-testing` | Unit tests and assertions within functions |
|
|
331
|
+
| `functions` | Reusable function stacks called in tests |
|
|
332
|
+
| `database` | Database operations used in test stacks |
|
|
333
|
+
| `debugging` | Logging and debugging test execution |
|
package/package.json
CHANGED