File: tox.ini

package info (click to toggle)
python-beartype 0.22.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,504 kB
  • sloc: python: 85,502; sh: 328; makefile: 30; javascript: 18
file content (436 lines) | stat: -rw-r--r-- 24,434 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
# --------------------( LICENSE                            )--------------------
# Copyright (c) 2014-2025 Beartype authors.
# See "LICENSE" for further details.
#
# --------------------( SYNOPSIS                           )--------------------
# Project-wide tox configuration, applied to all invocations of the tox test
# harness within this project.
#
# tox is a high-level Python-specific testing utility wrapping comparatively
# lower-level Python-specific testing frameworks (e.g., py.test, unittest2).
# Whereas the latter only exercise this project's codebase from the current
# working directory (CWD) without installing this project and hence exercising
# this project's installation, tox exercises both.
#
# Specifically, tox iteratively:
# 1. Creates a source-based tarball distribution of this project (e.g., via
#    "python setup.py sdist").
# 2. Installs this tarball *AND* a system-agnostic Python interpreter into one
#    isolated virtual environment for each testing configuration.
# 3. Tests this installation with the specified testing framework.
#
# --------------------( CAVEATS                            )--------------------
# *THIS CONFIGURATION DOES NOT SUPPORT PARALLELIZATION.* Although "tox" can be
# configured to run "tox" environments in parallel, doing so is fraught with
# hardship, produces unreadable output in the best of circumstances, and invites
# non-trivial race conditions between competing "tox" environments. It's best
# *NOT* to go there at all. Anyone requiring parallelization should simply be
# running our GitHub Actions-based "tests" workflow instead, which implicitly
# runs tests in a sane, safe, paralellized manner.
#
# *THIS CONFIGURATION IS INTOLERANT OF UNICODE CHARACTERS.* Note that setting
# "PYIOENCODING = UTF-8" under the "setenv" section below has no meaningful
# effect. For unknown reasons, "tox" is incapable of processing UTF-8 here.
# This is why nobody gets good things. If this file contains one or more
# UTF-8-encoded characters, "tox" fails with a non-human-readable traceback:
#     Traceback (most recent call last):
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/runpy.py", line 194, in _run_module_as_main
#         return _run_code(code, main_globals, None,
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/runpy.py", line 87, in _run_code
#         exec(code, run_globals)
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/tox/__main__.py", line 4, in <module>
#         tox.cmdline()
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/tox/session/__init__.py", line 44, in cmdline
#         main(args)
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/tox/session/__init__.py", line 65, in main
#         config = load_config(args)
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/tox/session/__init__.py", line 81, in load_config
#         config = parseconfig(args)
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/tox/config/__init__.py", line 282, in parseconfig
#         ParseIni(config, config_file, content)
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/tox/config/__init__.py", line 1145, in __init__
#         self._cfg = py.iniconfig.IniConfig(config.toxinipath, ini_data)
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 54, in __init__
#         tokens = self._parse(iter(f))
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 82, in _parse
#         for lineno, line in enumerate(line_iter):
#       File "/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/codecs.py", line 322, in decode
#         (result, consumed) = self._buffer_decode(data, self.errors, final)
#     UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd7 in position 3335: invalid continuation byte
#     Error: Process completed with exit code 1.
#
# --------------------( VARIABLES                          )--------------------
# tox dynamically substitutes "{"- and "}"-delimited variable names with the
# strings to which those variables expand. Supported variable names include:
# * "{envtmpdir}", the absolute dirname of a temporary directory specific to
#   the current virtual environment to which this project has been installed.
# * "{posargs}", the whitespace-delimited list of all command-line arguments
#   passed to the current invocation of the "tox" command.
# * "{toxinidir}", the absolute dirname of the directory containing this file
#   (e.g., the project root).

# ....................{ TODO                               }....................
#FIXME: This configuration has become intolerably slow. It's not tox's fault.
#It's pip's fault. Or, rather, it's our fault for continuing to use pip below.
#Using pip was "fine" (for certain definitions of "fine") when the "[test-tox]"
#extra in our "pyproject.toml" file listed only a handful of optional
#dependencies. That is *ABSOLUTELY* no longer the case. *ANY* modification
#whatesover to those extras now incurs literally tens of minutes of time merely
#spent on pip installing dependencies. So... what do we do?
#
#Obviously, we switch to uv. Our ".github/workflows" have *ALL* already switched
#to uv. So, there are no longer any reasonable blockers to getting this done.
#Do this as soon as feasible, please. *sigh*

# ....................{ TOX                                }....................
# Metadata specific to tox itself.
[tox]

# Comma- and newline-delimited string listing the names and optional versions
# of all mandatory core dependencies required to merely create a new venv.
#
# Note that project dependencies should *NOT* be listed here.
#requires =
#    pip >= 20.0.0
#    setuptools < 50.0.0

# ....................{ TOX ~ py                           }....................
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# WARNING: Changes to this setting *MUST* be manually synchronized with:
# * The "tox-env" setting in ".github/workflows/python_test.yml".
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Whitelist-delimited list of all "tox" environments to be tested, where "tox":
# * Expands Bash-style glob expressions in all environments.
# * Expands a prefixing "py" to "python".
# * Expands a suffixing "t" to the free-threading GIL-free variant of that
#   interpreter.
# * Delimits the subsequent two digits with a dot to associate each resulting
#   test configuration with the basename of an external command running an
#   externally installed Python interpreter.
# * Expands "-"-delimited lists via the Cartesian set product A x B,
#   effectively "multiplying" each environment on the left of each "-" against
#   each environment on the right of that "-". Moreover, each such environment
#   remains preserved and thus distinctly testable as that environment.
#
# Notable "tox" environments defined below include:
# * The "init" environment, run before *ALL* other "tox" environments and thus
#   preparing the local filesystem for those subsequently run environments.
# * The "py"-prefixed environment group, which "tox" expands via the rules above
#   into the test matrix of *ALL* Python interpreters to be tested.
# * The "finally" environment, run *AFTER* all other "tox" environments and thus
#   aggregating results produced by those previously run environments onto the
#   local filesystem.
#
# Order is typically important between "tox" environments. Thankfully, this
# order may be specified via the "depends =" setting in each "tox" environment.
#
# For example, setting "envlist = py27,py38" produces a test matrix exercising
# the externally installed "python2.7" and "python3.8" commands. See also:
#     https://tox.readthedocs.io/en/latest/config.html#generating-environments-conditional-settings
envlist =
    init
    py{310,311,312,313,313t,314,314t,315,315t}-coverage

#FIXME: Include this back in the above "envlist" if and when we resurrect this.
# finally

# Ignore Python environments unavailable on the current system. By default,
# "tox" fails on the first unavailable Python environment. While sensible for
# continuous integration (CI), this default fails to generalize for local
# developers lacking one or more Python environments.
#
# Note that our CI configuration explicitly falsifies this setting back to its
# CI-friendly default via the "--skip-missing-interpreters=false" CLI option,
# forcing CI failures for unavailable Python environments. See also:
#     https://github.com/tox-dev/tox/issues/903
skip_missing_interpreters = true

#FIXME: Disabled until required. Since "tox" currently behaves as expected,
#there's no incentive to break what's worky.
# # Comma- and newline-delimited string listing the names of all PyPI-hosted
# # projects required as mandatory dependencies to bootstrap "tox" -- typically
# # including some combination of "tox" itself, "virtualenv", and/or "pip".
# #
# # Note that all application-specific dependencies (e.g., "numpy", "scipy")
# # should be listed in the "deps" and/or "extras" settings under each
# # "[testenv]" section below.
# requires =

# ....................{ INIT                               }....................
# Job run *BEFORE* all other "tox" environments, preparing the local filesystem
# for subsequently run environments.
[testenv:init]

# Human-readable string synopsizing this environment.
description = Prepare "{toxinidir}" for testing.

#FIXME: We *MIGHT* also need to explicitly order environments like so:
#    depends = py{310,311,312,313,313t,314,314t,315,315t}-coverage
#Let's avoid doing this unless we absolutely must. DRY for life, yo! \o/

# Avoid installing this package under this environment.
skip_install = true

#FIXME: Not right. This *SHOULD* be using PEP 735-compliant dependency groups
#managed by "pyproject.toml", but... eh? Who's got the time, huh? *sigh*
# Whitespace-delimited string listing the names of all mandatory dependencies
# (i.e., third-party packages) required to run the commands listed below.
#
# Note that "tox" effectively requires this setting to be explicitly defined. If
# this setting is *NOT* explicitly defined, "tox" defaults this setting to the
# default "deps" setting defined by the default "[testenv]" configuration, which
# then erroneously installs this *ENTIRE* package and *ALL* dependencies simply
# to trivially run the "coverage erase" command below. Truly, a facepalm.
deps = coverage

# Newline-delimited string listing all shell commands required to test this
# project under this environment. See comments below for detailed discussion.
commands =
    # Unconditionally remove all prior coverage-specific temporary files (e.g.,
    # ".coverage.*") created by the prior "tox" run, regardless of whether we're
    # subsequently collecting coverage metrics. It's easiest to do this
    # unconditionally rather than depending on "coverage:", which only invites
    # fragile failure-prone edge case logic.
    {envpython} -m coverage erase
    # coverage: {envpython} -m coverage erase --data-file="{toxinidir}/.coverage"

# ....................{ TEST                               }....................
# Default job run for each "tox" environment lacking an environment-specific job
# named "[testenv:{environment_name}]", testing this project under that
# environment.
[testenv]

# Human-readable string synopsizing this environment.
description = Test "{toxinidir}" with "{basepython} -m pytest".

# ....................{ TEST ~ shell                       }....................
#FIXME: Sadly conflicts with Coverage.py. This used to work. We strongly suspect
#that our ".coveragerc" configuration is to blame. Oh, well. What you gonna do?
# Absolute dirname of the directory to change to for this environment, required
# to avoid accidental import collisions with uninstalled packages of the same
# name residing in "{toxinidir}". See also the following pertinent blog post,
# "Testing your python package as installed":
#     https://blog.ganssle.io/articles/2019/08/test-as-installed.html
#changedir = {envtmpdir}

# Newline-delimited string listing all environment variables to be temporarily
# set in each shell subprocess running tests.
setenv =
    # Permit the "pip" installation commands internally invoked under each
    # "tox" venv to optionally install wheels from an external third-party PyPI
    # repository explicitly supporting PyPy. If this is *NOT* done,
    # PyPy-specific "tox" venvs typically fail to install one or more Python
    # packages in the standard scientific stack.
    #
    # Note that this repository resides at:
    #     https://github.com/antocuni/pypy-wheels
    PIP_EXTRA_INDEX_URL = https://antocuni.github.io/pypy-wheels/manylinux2010

    #FIXME: This doesn't actually work. Gods... why is "pyright" so sucky!?!?
    #"pyright" doesn't respect a "latest" value for this environment variable
    #despite explicitly advising the user to do just that. I laugh and then cry.
    # Prevent the third-party static type-checker "pyright" from emitting
    # ignorable warnings that the current "pyright" version is not the most
    # recent. No one cares about you or your versioning, "pyright". Go away.
    # Specifically, this is what "pyright" now wastes everyone's time with:
    #     WARNING: there is a new pyright version available (v1.1.391 ->
    #     v1.1.392.post0). Please install the new version or set
    #     PYRIGHT_PYTHON_FORCE_VERSION to `latest`
    #PYRIGHT_PYTHON_FORCE_VERSION = latest

    # Enable the Python Development Mode (PDM), which:
    #     "Introduces additional runtime checks that are too expensive to be
    #     enabled by default. It should not be more verbose than the default if
    #     the code is correct; new warnings are only emitted when an issue is
    #     detected."
    # Specifically, the PDM enables:
    # * "-W default", emitting warnings ignored by default. Yes, Python
    #   insanely ignores various categories of warnings by default -- including
    #   deprecating warnings, which *ABSOLUTELY* should be emitted by default,
    #   but aren't. We can't resolve that for end users but we can resolve that
    #   for ourselves.
    # * "PYTHONMALLOC=debug", registering memory allocators hooks detecting
    #   unsafe call stack, memory, and GIL violations.
    # * "PYTHONFAULTHANDLER=1", registering fault handlers emitting Python
    #   tracebacks on segmentation faults.
    # * "PYTHONASYNCIODEBUG=1", enabling asyncio debug mode logging unawaited
    #   coroutines.
    # * Detections for unsafe string encoding and decoding operations.
    # * Logging io.IOBase.close() exceptions on object finalization.
    # * Enabling the "dev_mode" attribute of "sys.flags".
    # See also:
    #     https://docs.python.org/3/library/devmode.html
    #PYTHONDEVMODE = 1

    # Prevent Python from buffering and hence failing to log output in the
    # unlikely (but feasible) event of catastrophic failure from either the
    # active Python process or OS kernel.
    PYTHONUNBUFFERED = 1

    #FIXME: Seemingly unneeded at the moment, but you never know. *shrug*
    # # Absolute filename of the Coverage.py-specific output file containing
    # # coverage metrics collected for the current "tox" environment.
    # COVERAGE_FILE = {toxinidir}/.coverage
    #
    # # Absolute filename of the Coverage.py-specific configuration file.
    # # Coverage.py *SHOULD* detect this implicitly, but appears to have
    # # issues when run outside the "{toxinidir}". *shrug*
    # COVERAGE_RCFILE = {toxinidir}/.coveragerc

    # If the caller explicitly concatenated the current environment name by
    # "-coverage" (e.g., "py310-coverage")...
    coverage:
        # Command fragment measuring coverage while running tests, defined
        # *ONLY* when the caller explicitly concatenated the current environment
        # name by "-coverage" (e.g., "py310-coverage"). Dismantled, this is:
        #
        # Note that we intentionally do *NOT* leverage the "pytest-cov" plugin,
        # which lacks sufficient configurability and friendly maintainership to
        # warrant yet another fragile dependency.
        _COVERAGE_COMMAND = coverage run -m
        # _COVERAGE_COMMAND = coverage run --data-file="{toxinidir}/.coverage" -m

# Newline-delimited string listing all environment variables to be passed from
# the current shell process to each shell subprocess running tests.
# Dismantled, this is:
# * "CI" and "GITHUB_ACTIONS", enabling our test suite to programatically
#   detect execution by a remote continuous integration (CI) host.
passenv =
    CI
    GITHUB_ACTIONS
    PIP_CACHE_DIR

# ....................{ TEST ~ dependencies                }....................
# Whitespace-delimited string listing the names of all "pyproject.toml"-based
# "extras" required as mandatory or optional dependencies.
extras =
    # Install all mandatory test-specific dependencies. This is the official
    # solution supported by "tox" developers for eliminating redundancy between
    # testing dependencies listed within this file and the top-level
    # "pyproject.toml" configuration. While non-intuitive, we have little
    # recourse. See also:
    #     https://stackoverflow.com/questions/29870629/pip-install-test-dependencies-for-tox-from-setup-py
    #     https://stackoverflow.com/questions/39922650/tox-tests-use-setup-py-extra-require-as-tox-deps-source
    #     https://github.com/tox-dev/tox/issues/13#issuecomment-247788280
    #
    # Note that this also requires ".[test-tox]" to be listed as a dependency.
    test-tox

    # If the caller explicitly concatenated the current environment name by
    # "-coverage" (e.g., "py310-coverage"), install all optional
    # coverage-specific dependencies as well.
    coverage: test-tox-coverage

# Whitespace-delimited string listing the names of all mandatory dependencies
# (i.e., third-party packages) required to test this environment.
#
# Note that this also requires "test-tox" to be listed as an extra above.
deps = .[test-tox]

# ....................{ TEST ~ commands                    }....................
# Shell command with which to install project dependencies.
#
# This command extends the default "install_command" with support for an
# optional "${_TOX_PIP_INSTALL_OPTIONS}" environment variable defaulting to the
# empty string. This variable is typically defined by the higher-level
# ".github/workflows/python_test.yml" continuous integration (CI) configuration
# file on a platform-specific basis (e.g., "--force-reinstall" under macOS).
install_command =
    python -m pip install {env:_TOX_PIP_INSTALL_OPTIONS:} {opts} {packages}

# Newline-delimited string listing all shell commands required to test this
# project under this environment. Note that:
# * For disambiguity, avoid running any Python-based commands *EXCEPT* those
#   explicitly prefixed by "{envpython}" (i.e., the absolute filename of the
#   venv-specific Python interpreter).
# * For portability between POSIX-compliant platforms (e.g., Linux, macOS) and
#   POSIX-noncompliant platforms (e.g., Windows), the current platform and
#   shell should *NOT* assumed. Ergo, commands should be confined to those
#   explicitly prefixed by "{envpython}".
# * By default, the failure (i.e., non-zero exit status) of a single command
#   terminates this environment with failure. To prevent that, conditionally
#   squelch the failure of specific commands by prefixing those commands with
#   the "-" character (i.e., dash, minus); this nomenclature is inherited from
#   the "make" ecosystem, whose recipes utilize similar syntax.
commands =
    # Print metadata on the current versions of Python and pytest (in order).
    {envpython} --version
    {envpython} -m pytest --version

    # Run our entire pytest-based test suite. Dismantled, this is:
    # * "{env:_COVERAGE_COMMAND:}", expanding to either:
    #   * If measuring coverage, the value of the "${_COVERAGE_COMMAND}"
    #     environment variable defined above.
    #   * Else, the empty string.
    # * "--maxfail={n}", halting testing on the {n}th failure.
    # * "-p no:*", disabling various pytest plugins known to be harmful. See our
    #   "pytest.ini" file for further commentary on the hideous state of pytest
    #   plugins and why they are True Evil Personified (TEP).
    {envpython} \
        -m {env:_COVERAGE_COMMAND:} \
        pytest --maxfail=1 -p no:asyncio -p no:xvfb {posargs} "{toxinidir}"
    # {envpython} -m {env:_COVERAGE_COMMAND:} pytest --maxfail=1 -vvvv {posargs} "{toxinidir}"
    # {envpython} -m {env:_COVERAGE_COMMAND:} pytest --maxfail=1 -k test_pep563_closure_nested {posargs} "{toxinidir}"

    # If the caller explicitly concatenated the current environment name by
    # "-coverage" (e.g., "py310-coverage")...
    #
    # Note that this DRY violation with the "finally" environment defined below
    # is required by Codecov integration in our GitHub Actions-based
    # ".github/workflows/python_test.yml" workflow. This is *EXTREMELY*
    # non-ideal, but seemingly insurmountable unless we walk away from Codecov,
    # which we're increasingly inclined to do. Codecov: you bother us.
    coverage:
        # Combine all environment-specific ".coverage.*" files created by the
        # "{env:_COVERAGE_COMMAND:}" (e.g., "coverage run") on previously run
        # environments into a single unified ".coverage" file *BEFORE*
        # running any further coverage subcommands requiring this file.
        -{envpython} -m coverage combine "{toxinidir}/"

        # Generate a coverage report in the specific format expected by Codecov.
        -{envpython} -m coverage xml -o "{toxinidir}/coverage.xml"

#FIXME: Super, but basically doesn't work. Why? Because Codecov requires the
#"coverage:" functionality defined in the default "[testenv]" above. You can do
#one or the other, but you can't do both. *sigh*
# # ....................{ FINALLY                            }....................
# # Job run *AFTER* all other "tox" environments, aggregating all results output
# # from previously run environments onto the local filesystem.
# [testenv:finally]
#
# # Human-readable string synopsizing this environment.
# description = Finalizing "{toxinidir}" after testing.
#
# #FIXME: We *MIGHT* also need to explicitly order environments like so:
# #    depends = py{310,311,312,313,313t,314,314t,315,315t}-coverage
# #Let's avoid doing this unless we absolutely must. DRY for life, yo! \o/
#
# # Avoid installing this project under this environment.
# skip_install = true
#
# #FIXME: Not right. This *SHOULD* be using PEP 735-compliant dependency groups
# #managed by "pyproject.toml", but... eh? Who's got the time, huh? *sigh*
# # Whitespace-delimited string listing the names of all mandatory dependencies
# # (i.e., third-party packages) required to run the commands listed below.
# #
# # Note that "tox" effectively requires this setting to be explicitly defined. If
# # this setting is *NOT* explicitly defined, "tox" defaults this setting to the
# # default "deps" setting defined by the default "[testenv]" configuration, which
# # then erroneously installs this *ENTIRE* package and *ALL* dependencies simply
# # to trivially run the "coverage erase" command below. Truly, a facepalm.
# deps = coverage
#
# # Newline-delimited string listing all shell commands required to test this
# # project under this environment. See comments below for detailed discussion.
# commands =
#     # If the caller explicitly concatenated the current environment name by
#     # "-coverage" (e.g., "py310-coverage")...
#     coverage:
#         # Combine all environment-specific ".coverage.*" files created by the
#         # "{env:_COVERAGE_COMMAND:}" (e.g., "coverage run") on previously run
#         # environments into a single unified ".coverage" file *BEFORE*
#         # running any further coverage subcommands requiring this file.
#         -{envpython} -m coverage combine "{toxinidir}/"
#
#         # Generate a coverage report in the specific format expected by Codecov.
#         -{envpython} -m coverage xml -o "{toxinidir}/coverage.xml"