robotframework-mock 0.3.0__tar.gz → 0.4.0__tar.gz
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.
- robotframework_mock-0.4.0/PKG-INFO +389 -0
- robotframework_mock-0.4.0/README.md +365 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/setup.cfg +8 -2
- robotframework_mock-0.4.0/src/MockCoverage/__init__.py +735 -0
- robotframework_mock-0.4.0/src/robotframework_mock.egg-info/PKG-INFO +389 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/src/robotframework_mock.egg-info/SOURCES.txt +1 -0
- robotframework_mock-0.4.0/src/robotframework_mock.egg-info/requires.txt +4 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/src/robotframework_mock.egg-info/top_level.txt +1 -0
- robotframework_mock-0.3.0/PKG-INFO +0 -209
- robotframework_mock-0.3.0/README.md +0 -191
- robotframework_mock-0.3.0/src/robotframework_mock.egg-info/PKG-INFO +0 -209
- robotframework_mock-0.3.0/src/robotframework_mock.egg-info/requires.txt +0 -1
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/LICENSE +0 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/MANIFEST.in +0 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/pyproject.toml +0 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/setup.py +0 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/src/MockLibrary/__init__.py +0 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/src/MockResource/__init__.py +0 -0
- {robotframework_mock-0.3.0 → robotframework_mock-0.4.0}/src/robotframework_mock.egg-info/dependency_links.txt +0 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: robotframework-mock
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: A Robot Framework library for mocking keywords in unit tests
|
|
5
|
+
Home-page: https://github.com/olesz/robotframework-mock
|
|
6
|
+
Author: Lajos Olah
|
|
7
|
+
Author-email: lajos.olah.jr@gmail.com
|
|
8
|
+
License: Apache-2.0
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Framework :: Robot Framework
|
|
17
|
+
Classifier: Framework :: Robot Framework :: Library
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: robotframework>=7.0
|
|
22
|
+
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# robotframework-mock
|
|
26
|
+
|
|
27
|
+
A Robot Framework library for mocking keywords in unit tests.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
### Requirements
|
|
32
|
+
|
|
33
|
+
- Python 3.10 – 3.14
|
|
34
|
+
- Robot Framework 7.0 – 7.5
|
|
35
|
+
|
|
36
|
+
### From PyPI (once published)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install robotframework-mock
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### From source
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/yourusername/robotframework-mock.git
|
|
46
|
+
cd robotframework-mock
|
|
47
|
+
pip install .
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### For development
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install -e .
|
|
54
|
+
pip install -r requirements-dev.txt
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- Mock keywords from any Robot Framework library
|
|
60
|
+
- Mock keywords from Robot Framework resource files
|
|
61
|
+
- Mock Robot Framework's BuiltIn keywords
|
|
62
|
+
- Support for keywords with custom names via @keyword decorator
|
|
63
|
+
- Verify keyword calls and call counts
|
|
64
|
+
- Measure resource-file keyword coverage with configurable thresholds
|
|
65
|
+
- Simple API with three main keywords
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
### Mock Library Keywords
|
|
70
|
+
|
|
71
|
+
Import the library you want to mock, then create a MockLibrary instance for it:
|
|
72
|
+
|
|
73
|
+
```robot
|
|
74
|
+
*** Settings ***
|
|
75
|
+
Library DatabaseLibrary
|
|
76
|
+
Library MockLibrary DatabaseLibrary WITH NAME MockDB
|
|
77
|
+
|
|
78
|
+
*** Test Cases ***
|
|
79
|
+
Test With Mocked Keyword
|
|
80
|
+
MockDB.Mock Keyword query return_value=test_data
|
|
81
|
+
${result}= DatabaseLibrary.Query SELECT * FROM users
|
|
82
|
+
Should Be Equal ${result} test_data
|
|
83
|
+
MockDB.Reset Mocks
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Verify Calls
|
|
87
|
+
|
|
88
|
+
Verify that a keyword was called and optionally check the call count:
|
|
89
|
+
|
|
90
|
+
```robot
|
|
91
|
+
*** Test Cases ***
|
|
92
|
+
Test Keyword Was Called
|
|
93
|
+
MockDB.Mock Keyword execute_sql return_value=${None}
|
|
94
|
+
Process User Registration
|
|
95
|
+
MockDB.Verify Keyword Called execute_sql times=1
|
|
96
|
+
MockDB.Reset Mocks
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Mock BuiltIn Keywords
|
|
100
|
+
|
|
101
|
+
Mock Robot Framework's built-in keywords using the same MockLibrary with "BuiltIn" as the library name:
|
|
102
|
+
|
|
103
|
+
```robot
|
|
104
|
+
*** Settings ***
|
|
105
|
+
Library MockLibrary BuiltIn WITH NAME MockBin
|
|
106
|
+
|
|
107
|
+
*** Test Cases ***
|
|
108
|
+
Test BuiltIn Mock
|
|
109
|
+
MockBin.Mock Keyword Convert To Binary return_value=test_data
|
|
110
|
+
${result}= Convert To Binary aaa
|
|
111
|
+
Should Be Equal ${result} test_data
|
|
112
|
+
MockBin.Reset Mocks
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Mock Multiple Libraries
|
|
116
|
+
|
|
117
|
+
You can mock multiple libraries in the same test:
|
|
118
|
+
|
|
119
|
+
```robot
|
|
120
|
+
*** Settings ***
|
|
121
|
+
Library DatabaseLibrary
|
|
122
|
+
Library RequestsLibrary
|
|
123
|
+
Library MockLibrary DatabaseLibrary WITH NAME MockDB
|
|
124
|
+
Library MockLibrary RequestsLibrary WITH NAME MockReq
|
|
125
|
+
|
|
126
|
+
*** Test Cases ***
|
|
127
|
+
Test Multiple Mocks
|
|
128
|
+
MockDB.Mock Keyword query return_value=user_data
|
|
129
|
+
MockReq.Mock Keyword get return_value=api_response
|
|
130
|
+
# Your test code here
|
|
131
|
+
MockDB.Reset Mocks
|
|
132
|
+
MockReq.Reset Mocks
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Mock Resource Keywords
|
|
136
|
+
|
|
137
|
+
Mock keywords from Robot Framework resource files:
|
|
138
|
+
|
|
139
|
+
```robot
|
|
140
|
+
*** Settings ***
|
|
141
|
+
Resource my_resource.robot
|
|
142
|
+
Library MockResource my_resource.robot WITH NAME MockRes
|
|
143
|
+
|
|
144
|
+
*** Test Cases ***
|
|
145
|
+
Test Resource Keyword Mock
|
|
146
|
+
MockRes.Mock Keyword My Custom Keyword return_value=mocked_value
|
|
147
|
+
${result}= My Custom Keyword
|
|
148
|
+
Should Be Equal ${result} mocked_value
|
|
149
|
+
MockRes.Reset Mocks
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Keyword Coverage Measurement
|
|
153
|
+
|
|
154
|
+
`MockCoverage` measures how many of the keywords **defined** in your resource
|
|
155
|
+
files were actually **executed** by your tests — the Robot Framework analogue of
|
|
156
|
+
JaCoCo or coverage.py. Coverage requirements live in a TOML config file, and the
|
|
157
|
+
run fails if coverage falls below the configured threshold, so it can gate a CI
|
|
158
|
+
build.
|
|
159
|
+
|
|
160
|
+
Resource files are found by **recursively scanning directories** you list, so a
|
|
161
|
+
newly added resource file is measured automatically and cannot silently escape
|
|
162
|
+
the gate.
|
|
163
|
+
|
|
164
|
+
### Coverage model
|
|
165
|
+
|
|
166
|
+
Coverage uses the same aggregate model as standard coverage tools: a keyword
|
|
167
|
+
counts as covered if it is executed **at any point during the run**, regardless
|
|
168
|
+
of which test triggered it. This includes keywords reached indirectly through
|
|
169
|
+
other keywords.
|
|
170
|
+
|
|
171
|
+
A discovered resource file whose keywords are never executed reports
|
|
172
|
+
**0% coverage** by design.
|
|
173
|
+
|
|
174
|
+
Keyword names are read from the resource files themselves; the config only
|
|
175
|
+
selects *which files* participate.
|
|
176
|
+
|
|
177
|
+
### Configuration
|
|
178
|
+
|
|
179
|
+
Create a config file (e.g. `mock-coverage.toml`):
|
|
180
|
+
|
|
181
|
+
```toml
|
|
182
|
+
[coverage]
|
|
183
|
+
# Global minimum coverage percentage across all discovered resources
|
|
184
|
+
fail_under = 80.0
|
|
185
|
+
|
|
186
|
+
# Directories scanned recursively for resource files
|
|
187
|
+
paths = [
|
|
188
|
+
"tests/core-common/resources",
|
|
189
|
+
"tests/core-ui/resources",
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
# Which files to collect within those paths (default: ["*.resource"])
|
|
193
|
+
patterns = ["*.resource"]
|
|
194
|
+
|
|
195
|
+
# Optional exclusions, matched against the reported (relative) path
|
|
196
|
+
exclude = ["*deprecated*", "*/experimental/*"]
|
|
197
|
+
|
|
198
|
+
# Optional: stricter threshold for an individual file
|
|
199
|
+
[coverage.resources."tests/core-common/resources/vertica.resource"]
|
|
200
|
+
fail_under = 95.0
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
| Key | Default | Description |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `fail_under` | `0.0` | Minimum overall coverage percentage |
|
|
206
|
+
| `paths` | *(none)* | Directories scanned recursively |
|
|
207
|
+
| `patterns` | `["*.resource"]` | Filename patterns to collect |
|
|
208
|
+
| `exclude` | `[]` | Patterns to skip |
|
|
209
|
+
| `[coverage.resources."<file>"]` | — | Per-file threshold override |
|
|
210
|
+
|
|
211
|
+
Both the global total and each individual resource must meet its threshold for
|
|
212
|
+
the run to pass.
|
|
213
|
+
|
|
214
|
+
All paths are resolved **relative to the config file's own directory**, so the
|
|
215
|
+
same config works no matter which directory you invoke `robot` from. Absolute
|
|
216
|
+
paths are used as-is. A file listed explicitly under `[coverage.resources]` is
|
|
217
|
+
always measured, even if it lies outside `paths`.
|
|
218
|
+
|
|
219
|
+
### Running
|
|
220
|
+
|
|
221
|
+
Enable it as a listener:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
robot --listener MockCoverage:config=mock-coverage.toml tests/
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Listener options are `name=value` pairs separated by colons:
|
|
228
|
+
|
|
229
|
+
| Option | Default | Description |
|
|
230
|
+
|---|---|---|
|
|
231
|
+
| `config` | `mock-coverage.toml` | Path to the TOML configuration file |
|
|
232
|
+
| `output` | `coverage.json` | JSON report path (directories are created) |
|
|
233
|
+
| `enforce` | `true` | Whether to fail the run when below threshold |
|
|
234
|
+
| `console` | `failing` | `failing` lists only breaches; `all` lists every resource |
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Full table, reporting only (no build failure)
|
|
238
|
+
robot --listener MockCoverage:config=cov.toml:output=build/coverage.json:enforce=false:console=all tests/
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Output
|
|
242
|
+
|
|
243
|
+
By default the console report lists only the resources that are below their
|
|
244
|
+
threshold, which keeps output readable across large resource trees:
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
Resource Keyword Coverage
|
|
248
|
+
Resources below threshold (1):
|
|
249
|
+
res/brand-new.resource 0/2 0.00% FAIL (>=50.0)
|
|
250
|
+
TOTAL 3/8 37.50% FAIL (>=50.0) [4 resources]
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
With `console=all`, every measured resource is listed:
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
Resource Keyword Coverage
|
|
257
|
+
res/deep/nested/util.resource 1/2 50.00% PASS (>=50.0)
|
|
258
|
+
res/x/common.resource 1/2 50.00% PASS (>=50.0)
|
|
259
|
+
res/y/common.resource 1/2 50.00% PASS (>=50.0)
|
|
260
|
+
TOTAL 3/6 50.00% PASS (>=50.0) [3 resources]
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
When coverage is below threshold and `enforce` is enabled, the process exits with
|
|
264
|
+
a non-zero status **even if all tests passed**, failing the build.
|
|
265
|
+
|
|
266
|
+
A machine-readable JSON report is always written with the full per-file detail,
|
|
267
|
+
naming exactly which keywords were covered and which were missed:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"total": {
|
|
272
|
+
"resources": 1,
|
|
273
|
+
"defined": 4,
|
|
274
|
+
"covered": 3,
|
|
275
|
+
"percent": 75.0,
|
|
276
|
+
"fail_under": 75.0,
|
|
277
|
+
"passed": true
|
|
278
|
+
},
|
|
279
|
+
"resources": [
|
|
280
|
+
{
|
|
281
|
+
"path": "resources/coverage-demo.resource",
|
|
282
|
+
"defined": 4,
|
|
283
|
+
"covered": 3,
|
|
284
|
+
"percent": 75.0,
|
|
285
|
+
"fail_under": 75.0,
|
|
286
|
+
"passed": true,
|
|
287
|
+
"covered_keywords": ["Covered Keyword One", "Covered Keyword Three", "Covered Keyword Two"],
|
|
288
|
+
"missed_keywords": ["Uncovered Keyword"]
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Notes and limitations
|
|
295
|
+
|
|
296
|
+
- Executed keywords are attributed to their **real source file**, resolved
|
|
297
|
+
through Robot Framework's namespace at call time. Resource files sharing the
|
|
298
|
+
same base name in different directories are measured independently.
|
|
299
|
+
- Coverage is measured at **keyword granularity** (was this keyword executed?),
|
|
300
|
+
not at line or branch level.
|
|
301
|
+
- Python library keywords are not measured — use `pytest` with `coverage.py` for
|
|
302
|
+
those.
|
|
303
|
+
- TOML parsing uses the stdlib `tomllib` on Python 3.11+; on older versions the
|
|
304
|
+
`tomli` backport is installed automatically as a dependency.
|
|
305
|
+
|
|
306
|
+
## Keywords
|
|
307
|
+
|
|
308
|
+
### Mock Keyword
|
|
309
|
+
|
|
310
|
+
Mock a keyword with a return value or side effect.
|
|
311
|
+
|
|
312
|
+
**Arguments:**
|
|
313
|
+
- `keyword_name` - Name of the keyword to mock
|
|
314
|
+
- `return_value` - Value to return when called (optional)
|
|
315
|
+
- `side_effect` - Callable to execute instead (optional)
|
|
316
|
+
|
|
317
|
+
**Example:**
|
|
318
|
+
```robot
|
|
319
|
+
MockDB.Mock Keyword query return_value=test_data
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Reset Mocks
|
|
323
|
+
|
|
324
|
+
Restore all mocked keywords to their original implementations.
|
|
325
|
+
|
|
326
|
+
**Example:**
|
|
327
|
+
```robot
|
|
328
|
+
MockDB.Reset Mocks
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Verify Keyword Called
|
|
332
|
+
|
|
333
|
+
Verify a keyword was called, optionally checking call count.
|
|
334
|
+
|
|
335
|
+
**Arguments:**
|
|
336
|
+
- `keyword_name` - Name of the keyword to verify
|
|
337
|
+
- `times` - Expected number of calls (optional)
|
|
338
|
+
|
|
339
|
+
**Example:**
|
|
340
|
+
```robot
|
|
341
|
+
MockDB.Verify Keyword Called execute_sql times=1
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## How It Works
|
|
345
|
+
|
|
346
|
+
### MockLibrary
|
|
347
|
+
|
|
348
|
+
MockLibrary dynamically replaces keyword implementations:
|
|
349
|
+
1. Wraps the target library instance
|
|
350
|
+
2. Resolves keyword names to function names (handles @keyword decorator)
|
|
351
|
+
3. Stores original methods before mocking
|
|
352
|
+
4. Replaces methods with mock implementations using Python's unittest.mock.Mock
|
|
353
|
+
5. Returns mocked values or executes side effects
|
|
354
|
+
6. Tracks call counts for verification
|
|
355
|
+
7. Raises AttributeError if attempting to mock a non-existent keyword
|
|
356
|
+
|
|
357
|
+
### MockResource
|
|
358
|
+
|
|
359
|
+
MockResource patches Robot Framework's keyword execution:
|
|
360
|
+
1. Patches the Namespace.get_runner method
|
|
361
|
+
2. Intercepts keyword execution for the specified resource file
|
|
362
|
+
3. Replaces keyword body with Return statement containing mocked value
|
|
363
|
+
4. Tracks call counts for verification
|
|
364
|
+
5. Restores original keyword body on reset
|
|
365
|
+
|
|
366
|
+
### MockCoverage
|
|
367
|
+
|
|
368
|
+
MockCoverage measures resource keyword coverage as a listener:
|
|
369
|
+
1. Reads thresholds and scan paths from the TOML config file
|
|
370
|
+
2. Recursively discovers resource files under those paths
|
|
371
|
+
3. Parses each one with Robot Framework's own parsing API to enumerate the
|
|
372
|
+
keywords it defines
|
|
373
|
+
4. Records executed keywords via the `start_keyword` listener event, resolving
|
|
374
|
+
each keyword's real source file through Robot's namespace so same-named
|
|
375
|
+
resources stay distinct
|
|
376
|
+
5. Computes per-resource and total coverage percentages at the end of the run
|
|
377
|
+
6. Writes a JSON report and prints a summary table
|
|
378
|
+
7. Exits non-zero if any threshold is unmet and enforcement is enabled
|
|
379
|
+
|
|
380
|
+
## Notes
|
|
381
|
+
|
|
382
|
+
- Both libraries use `ROBOT_LIBRARY_SCOPE = 'GLOBAL'` to maintain state across test cases
|
|
383
|
+
- Built on Python's unittest.mock.Mock for robust mocking capabilities
|
|
384
|
+
- MockLibrary supports any Robot Framework library, including BuiltIn
|
|
385
|
+
- MockResource works with resource files by patching the keyword execution pipeline
|
|
386
|
+
|
|
387
|
+
## License
|
|
388
|
+
|
|
389
|
+
See LICENSE file for details.
|