Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-adams committed Jan 28, 2016
0 parents commit 2c2a7ac
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.egg-info
.cache
*.pyc
*.tox
build/
dist/
.DS_Store
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
language: python
sudo: false
python:
- "2.6"
- "2.7"
- "3.2"
- "3.3"
- "3.4"
- "3.5"
install:
- "pip install flake8"
- "pip install -e ."
before_script:
- "flake8"
script:
- py.test
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2016 Mark Adams

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
31 changes: 31 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.. image:: https://secure.travis-ci.org/mark-adams/pytest-test-groups.png?branch=master
:alt: Build Status
:target: https://travis-ci.org/mark-adams/pytest-test-groups

Welcome to pytest-test-groups!
==============================

pytest-test-groups allows you to split your test runs into groups of a specific
size to make it easier to split up your test runs.


Usage
---------------------

::

# Install pytest-test-groups
pip install pytest-test-groups

# Split the tests into 10 groups and run the second group
py.test --test-group-count 10 --test-group=2


Why would I use this?
------------------------------------------------------------------

Sometimes you may have some long running test jobs that take a
while to complete. This can be a major headache when trying to
run tests quickly. pytest-test-groups allows you to easily say
"split my tests into groups of 10 tests and run the second group".
This is primarily useful in the context of CI builds.
40 changes: 40 additions & 0 deletions pytest_test_groups/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import math


def get_group_size(total_items, total_groups):
return int(math.ceil(float(total_items) / total_groups))


def get_group(items, group_size, group_id):
start = group_size * (group_id - 1)
end = start + group_size

if start >= len(items) or start < 0:
raise ValueError("Invalid test-group argument")

return items[start:end]


def pytest_addoption(parser):
group = parser.getgroup('split your tests into evenly sized groups and run them')
group.addoption('--test-group-count', dest='test-group-count', type=int,
help='The number of groups to split the tests into')
group.addoption('--test-group', dest='test-group', type=int,
help='The group of tests that should be executed')


def pytest_collection_modifyitems(session, config, items):
group_count = config.getoption('test-group-count')
group_id = config.getoption('test-group')

if not group_count or not group_id:
return

total_items = len(items)

group_size = get_group_size(total_items, group_count)
tests_in_group = get_group(items, group_size, group_id)
del items[:]
items.extend(tests_in_group)

print('Running test group #{0} ({1} tests)'.format(group_id, len(items)))
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 119
40 changes: 40 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import codecs
import os

from setuptools import setup


def read(fname):
file_path = os.path.join(os.path.dirname(__file__), fname)
return codecs.open(file_path, encoding='utf-8').read()

setup(
name="pytest-test-groups",
description=('A Pytest plugin for running a subset of your tests by '
'splitting them in to equally sized groups.'),
url='https://github.com/mark-adams/pytest-test-groups',
author='Mark Adams',
author_email='[email protected]',
packages=['pytest_test_groups'],
version='0.9',
long_description=read('README.rst'),
install_requires=['pytest>=2.5'],
classifiers=['Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Software Development :: Testing',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5'
],
entry_points={
'pytest11': [
'test-groups = pytest_test_groups',
]
},
)
50 changes: 50 additions & 0 deletions tests/test_groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import pytest

from pytest_test_groups import get_group, get_group_size


def test_group_size_computed_correctly_for_even_group():
expected = 8
actual = get_group_size(32, 4) # 32 total tests; 4 groups

assert expected == actual


def test_group_size_computed_correctly_for_odd_group():
expected = 8
actual = get_group_size(31, 4) # 31 total tests; 4 groups

assert expected == actual


def test_group_is_the_proper_size():
items = [str(i) for i in range(32)]
group = get_group(items, 8, 1)

assert len(group) == 8


def test_all_groups_together_form_original_set_of_tests():
items = [str(i) for i in range(32)]

groups = [get_group(items, 8, i) for i in range(1, 5)]

combined = []
for group in groups:
combined.extend(group)

assert combined == items


def test_group_that_is_too_high_raises_value_error():
items = [str(i) for i in range(32)]

with pytest.raises(ValueError):
get_group(items, 8, 5)


def test_group_that_is_too_low_raises_value_error():
items = [str(i) for i in range(32)]

with pytest.raises(ValueError):
get_group(items, 8, 0)
17 changes: 17 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[tox]
envlist = py{26,27,33,34,35}, flake8

[testenv]
commands =
py.test
deps =
pytest==2.8.7


[testenv:flake8]
commands =
flake8
deps =
flake8
flake8-import-order
pep8-naming

0 comments on commit 2c2a7ac

Please sign in to comment.