diff --git a/.travis.yml b/.travis.yml index 587b83da..ca515e3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,38 @@ matrix: include: - python: "3.6" env: TRAVIS_PYLINT=true + - os : osx + language: generic + python: 3.7 + env: PYTHON=3.7 + - os: windows + language: sh + python: 3.7 + before_install: + - choco install python3 + - export PATH="/c/Python37:/c/Python37/Scripts:$PATH" + - python -m pip install --upgrade pip wheel + script: + - python -m virtualenv .env + - .env/Scripts/pip.exe install -e .[testing,doc] + - .env/Scripts/py.test.exe --cov=slash --cov-report=html tests + allow_failures: + - os: windows # command to run tests, e.g. python setup.py test +before_install: | + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + brew update + brew install openssl readline + brew outdated pyenv || brew upgrade pyenv + brew install pyenv-virtualenv + pyenv install $PYTHON + export PYENV_VERSION=$PYTHON + export PATH="/Users/travis/.pyenv/shims:${PATH}" + pyenv-virtualenv venv + source venv/bin/activate + python --version + fi install: - pip install virtualenv - pip install codecov diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000..0dc73aa7 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,49 @@ +# Python package +# Create and test a Python package on multiple Python versions. +# Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/python + +trigger: +- master + +jobs: + +- job: 'Test' + pool: + vmImage: 'vs2017-win2016' + strategy: + matrix: + Python35: + python.version: '3.5' + Python36: + python.version: '3.6' + Python37: + python.version: '3.7' + maxParallel: 4 + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + architecture: 'x64' + + - script: | + python -m pip install --upgrade pip && pip install .[testing,doc] + displayName: 'Install dependencies' + + - script: | + mkdir d:\temp && py.test tests --cov=slash --cov-report=html --cov-report=xml --junitxml=junit/test-results.xml + displayName: 'pytest' + env: {TMPDIR: 'd:\temp\'} + + - task: PublishTestResults@2 + condition: succeededOrFailed() + inputs: + testResultsFiles: '**/test-*.xml' + testRunTitle: 'Publish test results for Python $(python.version)' + + - task: PublishCodeCoverageResults@1 + inputs: + codeCoverageTool: Cobertura + summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' + reportDirectory: '$(System.DefaultWorkingDirectory)/**/htmlcov' diff --git a/tests/test_logging.py b/tests/test_logging.py index 26e2c819..65f41dc7 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -1,6 +1,7 @@ # pylint: disable=unused-argument,redefined-outer-name import functools import os +import sys import logbook import brotli @@ -45,7 +46,7 @@ def test_with_log_error(): assert [res.message for res in result.get_errors()] == expected_error_messages assert [rec.message for rec in test_handler.records] == [message, non_capture_message] - +@pytest.mark.skipif(sys.platform == 'win32', reason="does not run on windows") def test_last_session_symlinks(files_dir, links_dir, session): test_log_file = files_dir.join( @@ -154,7 +155,7 @@ def test_log_symlinks_without_root_path(suite, config_override, symlink_name): config_override('log.{}'.format(symlink_name), 'some/subdir') assert suite.run().ok() - +@pytest.mark.skipif(sys.platform == 'win32', reason="does not run on windows") def test_last_test_not_overriden_by_stop_on_error(links_dir, suite): failed_test = suite[4] failed_test.when_run.fail() @@ -192,7 +193,7 @@ def test_result_log_links(files_dir, session): assert result.get_log_path() is not None assert result.get_log_path().startswith(str(files_dir)) - +@pytest.mark.skipif(sys.platform == 'win32', reason="does not run on windows") def test_last_failed(suite, links_dir): suite[-5].when_run.fail() last_failed = suite[-2] @@ -216,6 +217,7 @@ def test_errors_log_for_test(suite, suite_test, errors_log_path, logs_dir): lines = f.read().splitlines() assert error_line in lines +@pytest.mark.skipif(sys.platform == 'win32', reason="does not run on windows") @pytest.mark.parametrize('should_keep_failed_tests', [True, False]) def test_logs_deletion(suite, suite_test, errors_log_path, logs_dir, config_override, should_keep_failed_tests): config_override('log.cleanup.enabled', True) diff --git a/tests/test_parallel.py b/tests/test_parallel.py index 8ce3b286..bf418979 100644 --- a/tests/test_parallel.py +++ b/tests/test_parallel.py @@ -1,6 +1,8 @@ import slash import os import signal +import sys + from .utils.suite_writer import Suite from slash.resuming import get_tests_from_previous_session from slash.exceptions import InteractiveParallelNotAllowed, ParallelTimeout @@ -12,6 +14,9 @@ import tempfile import pytest +if sys.platform.startswith("win"): + pytest.skip("does not run on windows", allow_module_level=True) + @pytest.fixture(scope='module', autouse=True) def no_parallel_user_config(request): tmpdir = tempfile.mkdtemp() diff --git a/tests/test_suite_files.py b/tests/test_suite_files.py index bf39af89..98787354 100644 --- a/tests/test_suite_files.py +++ b/tests/test_suite_files.py @@ -24,8 +24,7 @@ def test_iter_suite_paths_files_relpath(filename, paths): f.write(relpath) f.write('\n') - assert [p for p, _ in suite_files.iter_suite_file_paths([filename])] == [os.path.abspath(p) for p in paths] - + assert [os.path.normcase(p) for p, _ in suite_files.iter_suite_file_paths([filename])] == [os.path.normcase(os.path.abspath(p)) for p in paths] def test_suite_files(suite, suite_test, suite_file): # pylint: disable=unused-argument suite.run(args=[]) diff --git a/tests/test_test_loading.py b/tests/test_test_loading.py index 1c6d6b5a..34bd638c 100644 --- a/tests/test_test_loading.py +++ b/tests/test_test_loading.py @@ -54,7 +54,7 @@ def test_dir(tmpdir, names, indices): @pytest.fixture def names(): - return ['a/test_a_b.py', 'a/test_b_a.py', 'b/test_a_a.py', 'b/test_a_b.py'] + return [os.path.normpath(p) for p in ['a/test_a_b.py', 'a/test_b_a.py', 'b/test_a_a.py', 'b/test_a_b.py']] def _sorted_by_indices(items, indices): returned = [None for _ in items] diff --git a/tests/test_warnings.py b/tests/test_warnings.py index dd3ff4ec..f0f80cdc 100644 --- a/tests/test_warnings.py +++ b/tests/test_warnings.py @@ -1,4 +1,5 @@ # pylint: disable=unused-variable,redefined-outer-name +import os import collections import warnings from contextlib import contextmanager @@ -44,7 +45,7 @@ def warning_added(warning): assert isinstance(w.filename, str) assert w.lineno assert w.filename - assert w.filename.rsplit('/', 1)[-1] == suite_test.file.get_relative_path() + assert w.filename.rsplit(os.path.sep, 1)[-1] == suite_test.file.get_relative_path() warning_type = w.details['type'] assert isinstance(warning_type, str) assert warning_type == 'LogbookWarning' diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py index fb78b9dc..8b3ac42a 100644 --- a/tests/utils/__init__.py +++ b/tests/utils/__init__.py @@ -43,7 +43,7 @@ def override_config(self, path, value): def get_new_path(self): returned = tempfile.mkdtemp() - self.addCleanup(shutil.rmtree, returned) + self.addCleanup(shutil.rmtree, returned, ignore_errors=True) return returned _forge = None