fune/testing/mochitest/tests/python/conftest.py
Mitchell Hentges 0116a8d491 Bug 1748737: Update deprecated pytest code r=webdriver-reviewers,ahal,whimboo
`pytest` is about to be upgraded, so this patch resolves a bunch of the
issues currently blocking the upgrade.
Most changes done in this patch are described in the "deprecations" page
on the pytest docs:
https://docs.pytest.org/en/latest/deprecations.html#using-class-in-custom-collectors

One undocumented change is that defining a pytest argument as the same name as an
in-scope, imported fixture function, will no longer use that imported function.

Differential Revision: https://phabricator.services.mozilla.com/D136537
2022-01-21 18:21:55 +00:00

147 lines
4.7 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
import six
import json
import os
from argparse import Namespace
import pytest
import mozinfo
from manifestparser import TestManifest, expression
from moztest.selftest.fixtures import binary_fixture, setup_test_harness # noqa
here = os.path.abspath(os.path.dirname(__file__))
setup_args = [os.path.join(here, "files"), "mochitest", "testing/mochitest"]
@pytest.fixture(scope="function")
def parser(request):
parser = pytest.importorskip("mochitest_options")
app = getattr(request.module, "APP", "generic")
return parser.MochitestArgumentParser(app=app)
@pytest.fixture(scope="function")
def runtests(setup_test_harness, binary, parser, request):
"""Creates an easy to use entry point into the mochitest harness.
:returns: A function with the signature `*tests, **opts`. Each test is a file name
(relative to the `files` dir). At least one is required. The opts are
used to override the default mochitest options, they are optional.
"""
flavor = "plain"
if "flavor" in request.fixturenames:
flavor = request.getfixturevalue("flavor")
runFailures = ""
if "runFailures" in request.fixturenames:
runFailures = request.getfixturevalue("runFailures")
setup_test_harness(*setup_args, flavor=flavor)
runtests = pytest.importorskip("runtests")
mochitest_root = runtests.SCRIPT_DIR
if flavor == "plain":
test_root = os.path.join(mochitest_root, "tests", "selftests")
manifest_name = "mochitest.ini"
elif flavor == "browser-chrome":
test_root = os.path.join(mochitest_root, "browser", "tests", "selftests")
manifest_name = "browser.ini"
else:
raise Exception(f"Invalid flavor {flavor}!")
# pylint --py3k: W1648
buf = six.StringIO()
options = vars(parser.parse_args([]))
options.update(
{
"app": binary,
"flavor": flavor,
"runFailures": runFailures,
"keep_open": False,
"log_raw": [buf],
}
)
if runFailures == "selftest":
options["crashAsPass"] = True
options["timeoutAsPass"] = True
runtests.mozinfo.update({"selftest": True})
if not os.path.isdir(runtests.build_obj.bindir):
package_root = os.path.dirname(mochitest_root)
options.update(
{
"certPath": os.path.join(package_root, "certs"),
"utilityPath": os.path.join(package_root, "bin"),
}
)
options["extraProfileFiles"].append(
os.path.join(package_root, "bin", "plugins")
)
options.update(getattr(request.module, "OPTIONS", {}))
def normalize(test):
return {
"name": test,
"relpath": test,
"path": os.path.join(test_root, test),
# add a dummy manifest file because mochitest expects it
"manifest": os.path.join(test_root, manifest_name),
"manifest_relpath": manifest_name,
"skip-if": runFailures,
}
def inner(*tests, **opts):
assert len(tests) > 0
# Inject a TestManifest in the runtests option if one
# has not been already included by the caller.
if not isinstance(options["manifestFile"], TestManifest):
manifest = TestManifest()
options["manifestFile"] = manifest
# pylint --py3k: W1636
manifest.tests.extend(list(map(normalize, tests)))
options.update(opts)
result = runtests.run_test_harness(parser, Namespace(**options))
out = json.loads("[" + ",".join(buf.getvalue().splitlines()) + "]")
buf.close()
return result, out
return inner
@pytest.fixture
def build_obj(setup_test_harness):
setup_test_harness(*setup_args)
mochitest_options = pytest.importorskip("mochitest_options")
return mochitest_options.build_obj
@pytest.fixture(autouse=True)
def skip_using_mozinfo(request, setup_test_harness):
"""Gives tests the ability to skip based on values from mozinfo.
Example:
@pytest.mark.skip_mozinfo("!e10s || os == 'linux'")
def test_foo():
pass
"""
setup_test_harness(*setup_args)
runtests = pytest.importorskip("runtests")
runtests.update_mozinfo()
skip_mozinfo = request.node.get_closest_marker("skip_mozinfo")
if skip_mozinfo:
value = skip_mozinfo.args[0]
if expression.parse(value, **mozinfo.info):
pytest.skip("skipped due to mozinfo match: \n{}".format(value))