1
1
pytest-html
2
2
===========
3
3
4
- pytest-html is a plugin for `pytest <http://pytest.org >`_ that generates a
5
- HTML report for the test results.
4
+ pytest-html is a plugin for `pytest <http://pytest.org >`_ that generates a HTML report for test results.
6
5
7
6
.. image :: https://img.shields.io/badge/license-MPL%202.0-blue.svg
8
7
:target: https://github.com/pytest-dev/pytest-html/blob/master/LICENSE
@@ -23,300 +22,24 @@ HTML report for the test results.
23
22
:target: https://codecov.io/gh/pytest-dev/pytest-html
24
23
:alt: Codecov
25
24
26
- Requirements
27
- ------------
28
-
29
- You will need the following prerequisites in order to use pytest-html:
25
+ Resources
26
+ ---------
30
27
31
- - Python 3.6+ or PyPy3
28
+ - `Documentation <https://pytest-html.readthedocs.io/en/latest/ >`_
29
+ - `Release Notes <http://github.com/pytest-dev/pytest-html/blob/master/CHANGES.rst >`_
30
+ - `Issue Tracker <http://github.com/pytest-dev/pytest-html/issues >`_
31
+ - `Code <http://github.com/pytest-dev/pytest-html/ >`_
32
32
33
- Installation
33
+ Contributing
34
34
------------
35
35
36
- To install pytest-html:
37
-
38
- .. code-block :: bash
39
-
40
- $ pip install pytest-html
41
-
42
- Then run your tests with:
43
-
44
- .. code-block :: bash
45
-
46
- $ pytest --html=report.html
47
-
48
- ANSI codes
49
- ----------
50
-
51
- Note that ANSI code support depends on the
52
- `ansi2html <https://pypi.python.org/pypi/ansi2html/ >`_ package. Due to the use
53
- of a less permissive license, this package is not included as a dependency. If
54
- you have this package installed, then ANSI codes will be converted to HTML in
55
- your report.
56
-
57
- Creating a self-contained report
58
- --------------------------------
59
-
60
- In order to respect the `Content Security Policy (CSP)
61
- <https://developer.mozilla.org/docs/Web/Security/CSP> `_,
62
- several assets such as CSS and images are stored separately by default.
63
- You can alternatively create a self-contained report, which can be more
64
- convenient when sharing your results. This can be done in the following way:
65
-
66
- .. code-block :: bash
67
-
68
- $ pytest --html=report.html --self-contained-html
69
-
70
- Images added as files or links are going to be linked as external resources,
71
- meaning that the standalone report HTML-file may not display these images
72
- as expected.
73
-
74
- The plugin will issue a warning when adding files or links to the standalone report.
75
-
76
- Enhancing reports
77
- -----------------
78
-
79
- Appearance
80
- ~~~~~~~~~~
81
-
82
- Custom CSS (Cascasding Style Sheets) can be passed on the command line using
83
- the :code: `--css ` option. These will be applied in the order specified, and can
84
- be used to change the appearance of the report.
85
-
86
- .. code-block :: bash
87
-
88
- $ pytest --html=report.html --css=highcontrast.css --css=accessible.css
89
-
90
- Report Title
91
- ~~~~~~~~~~~~
92
-
93
- By default report title will be the filename of the report, you can edit it by using the :code: `pytest_html_report_title ` hook:
94
-
95
- .. code-block :: python
96
-
97
- def pytest_html_report_title (report ):
98
- report.title = " My very own title!"
99
-
100
- Environment
101
- ~~~~~~~~~~~
102
-
103
- The *Environment * section is provided by the `pytest-metadata
104
- <https://pypi.python.org/pypi/pytest-metadata/> `_ plugin, and can be accessed
105
- via the :code: `pytest_configure ` hook:
106
-
107
- .. code-block :: python
108
-
109
- def pytest_configure (config ):
110
- config._metadata[" foo" ] = " bar"
111
-
112
- The generated table will be sorted alphabetically unless the metadata is a
113
- :code: `collections.OrderedDict `.
114
-
115
- Additional summary information
116
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117
-
118
- You can edit the *Summary * section by using the :code: `pytest_html_results_summary ` hook:
119
-
120
- .. code-block :: python
121
-
122
- from py.xml import html
123
-
124
-
125
- def pytest_html_results_summary (prefix , summary , postfix ):
126
- prefix.extend([html.p(" foo: bar" )])
127
-
128
- Extra content
129
- ~~~~~~~~~~~~~
130
-
131
- You can add details to the HTML reports by creating an 'extra' list on the
132
- report object. Here are the types of extra content that can be added:
133
-
134
- ========== ============================================
135
- Type Example
136
- ========== ============================================
137
- Raw HTML ``extra.html('<div>Additional HTML</div>') ``
138
- `JSON `_ ``extra.json({'name': 'pytest'}) ``
139
- Plain text ``extra.text('Add some simple Text') ``
140
- URL ``extra.url('http://www.example.com/') ``
141
- Image ``extra.image(image, mime_type='image/gif', extension='gif') ``
142
- Image ``extra.image('/path/to/file.png') ``
143
- Image ``extra.image('http://some_image.png') ``
144
- ========== ============================================
145
-
146
- **Note **: When adding an image from file, the path can be either absolute
147
- or relative.
148
-
149
- **Note **: When using ``--self-contained-html ``, images added as files or links
150
- may not work as expected, see section `Creating a self-contained report `_ for
151
- more info.
152
-
153
- There are also convenient types for several image formats:
154
-
155
- ============ ====================
156
- Image format Example
157
- ============ ====================
158
- PNG ``extra.png(image) ``
159
- JPEG ``extra.jpg(image) ``
160
- SVG ``extra.svg(image) ``
161
- ============ ====================
162
-
163
- The following example adds the various types of extras using a
164
- :code: `pytest_runtest_makereport ` hook, which can be implemented in a plugin or
165
- conftest.py file:
166
-
167
- .. code-block :: python
168
-
169
- import pytest
170
-
171
-
172
- @pytest.hookimpl (hookwrapper = True )
173
- def pytest_runtest_makereport (item , call ):
174
- pytest_html = item.config.pluginmanager.getplugin(" html" )
175
- outcome = yield
176
- report = outcome.get_result()
177
- extra = getattr (report, " extra" , [])
178
- if report.when == " call" :
179
- # always add url to report
180
- extra.append(pytest_html.extras.url(" http://www.example.com/" ))
181
- xfail = hasattr (report, " wasxfail" )
182
- if (report.skipped and xfail) or (report.failed and not xfail):
183
- # only add additional html on failure
184
- extra.append(pytest_html.extras.html(" <div>Additional HTML</div>" ))
185
- report.extra = extra
186
-
187
- You can also specify the :code: `name ` argument for all types other than :code: `html ` which will change the title of the
188
- created hyper link:
189
-
190
- .. code-block :: python
191
-
192
- extra.append(pytest_html.extras.text(" some string" , name = " Different title" ))
193
-
194
- It is also possible to use the fixture :code: `extra ` to add content directly
195
- in a test function without implementing hooks. These will generally end up
196
- before any extras added by plugins.
197
-
198
- .. code-block :: python
199
-
200
- from pytest_html import extras
201
-
202
-
203
- def test_extra (extra ):
204
- extra.append(extras.text(" some string" ))
205
-
206
-
207
- Modifying the results table
208
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
209
-
210
- You can modify the columns by implementing custom hooks for the header and
211
- rows. The following example :code: `conftest.py ` adds a description column with
212
- the test function docstring, adds a sortable time column, and removes the links
213
- column:
214
-
215
- .. code-block :: python
216
-
217
- from datetime import datetime
218
- from py.xml import html
219
- import pytest
220
-
221
-
222
- def pytest_html_results_table_header (cells ):
223
- cells.insert(2 , html.th(" Description" ))
224
- cells.insert(1 , html.th(" Time" , class_ = " sortable time" , col = " time" ))
225
- cells.pop()
226
-
227
-
228
- def pytest_html_results_table_row (report , cells ):
229
- cells.insert(2 , html.td(report.description))
230
- cells.insert(1 , html.td(datetime.utcnow(), class_ = " col-time" ))
231
- cells.pop()
232
-
233
-
234
- @pytest.hookimpl (hookwrapper = True )
235
- def pytest_runtest_makereport (item , call ):
236
- outcome = yield
237
- report = outcome.get_result()
238
- report.description = str (item.function.__doc__ )
239
-
240
- You can also remove results by implementing the
241
- :code: `pytest_html_results_table_row ` hook and removing all cells. The
242
- following example removes all passed results from the report:
243
-
244
- .. code-block :: python
245
-
246
- def pytest_html_results_table_row (report , cells ):
247
- if report.passed:
248
- del cells[:]
249
-
250
- The log output and additional HTML can be modified by implementing the
251
- :code: `pytest_html_results_html ` hook. The following example replaces all
252
- additional HTML and log output with a notice that the log is empty:
253
-
254
- .. code-block :: python
255
-
256
- from py.xml import html
257
-
258
-
259
- def pytest_html_results_table_html (report , data ):
260
- if report.passed:
261
- del data[:]
262
- data.append(html.div(" No log output captured." , class_ = " empty log" ))
263
-
264
- Display options
265
- ---------------
266
-
267
- By default, all rows in the **Results ** table will be expanded except those that have :code: `Passed `.
268
-
269
- This behavior can be customized either with a query parameter: :code: `?collapsed=Passed,XFailed,Skipped `
270
- or by setting the :code: `render_collapsed ` in a configuration file (pytest.ini, setup.cfg, etc).
271
-
272
- .. code-block :: ini
273
-
274
- [pytest]
275
- render_collapsed = True
276
-
277
- **NOTE: ** Setting :code: `render_collapsed ` will, unlike the query parameter, affect all statuses.
278
-
279
- The formatting of the timestamp used in the :code: `Durations ` column can be modified by setting :code: `duration_formatter `
280
- on the :code: `report ` attribute. All `time.strftime `_ formatting directives are supported. In addition, it is possible
281
- to supply :code: `%f ` to get duration milliseconds. If this value is not set, the values in the :code: `Durations ` column are
282
- displayed in :code: `%S.%f ` format where :code: `%S ` is the total number of seconds a test ran for.
283
-
284
- Below is an example of a :code: `conftest.py ` file setting :code: `duration_formatter `:
285
-
286
- .. code-block :: python
287
-
288
- import pytest
289
-
290
-
291
- @pytest.hookimpl (hookwrapper = True )
292
- def pytest_runtest_makereport (item , call ):
293
- outcome = yield
294
- report = outcome.get_result()
295
- setattr (report, " duration_formatter" , " %H:%M:%S.%f " )
36
+ We welcome contributions.
296
37
297
- ** NOTE **: Milliseconds are always displayed with a precision of 2
38
+ To learn more, see ` Development < https://pytest-html.readthedocs.io/en/latest/development.html >`_
298
39
299
40
Screenshots
300
41
-----------
301
42
302
43
.. image :: https://cloud.githubusercontent.com/assets/122800/11952194/62daa964-a88e-11e5-9745-2aa5b714c8bb.png
303
44
:target: https://cloud.githubusercontent.com/assets/122800/11951695/f371b926-a88a-11e5-91c2-499166776bd3.png
304
45
:alt: Enhanced HTML report
305
-
306
- Contributing
307
- ------------
308
-
309
- We welcome contributions.
310
-
311
- To learn more, see `Development <https://github.com/pytest-dev/pytest-html/blob/master/development.rst >`_
312
-
313
- Resources
314
- ---------
315
-
316
- - `Release Notes <http://github.com/pytest-dev/pytest-html/blob/master/CHANGES.rst >`_
317
- - `Issue Tracker <http://github.com/pytest-dev/pytest-html/issues >`_
318
- - `Code <http://github.com/pytest-dev/pytest-html/ >`_
319
-
320
-
321
- .. _JSON : http://json.org/
322
- .. _time.strftime : https://docs.python.org/3/library/time.html#time.strftime
0 commit comments