From commits-noreply at bitbucket.org Tue Feb 2 11:32:38 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 2 Feb 2010 10:32:38 +0000 (UTC) Subject: [py-svn] py-trunk commit 4c8a950ce346: fix title to not mention distributed programming which Message-ID: <20100202103238.65F407EF18@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265106741 -3600 # Node ID 4c8a950ce346d8f151fefac222dbfc7e91dae728 # Parent 0c6cafb6f4e6920baa63a0a86fd8113bfc2f07b1 fix title to not mention distributed programming which is separated out into execnet. --- a/doc/index.txt +++ b/doc/index.txt @@ -1,9 +1,9 @@ -py lib: testing and distributed programming library +py lib: testing and filesystem abstraction ==================================================== -The ``py`` lib has several namespaces which help with testing, -generating and distributing code across machines. Here is -documentation on the most interesting ones: +The ``py`` lib has several namespaces which help with automated testing, +and with accessing filesystems. Here is some documentation on the +core namespaces: `py.test`_ write and deploy unit- and functional tests to multiple machines. From hpk at codespeak.net Wed Feb 3 12:31:51 2010 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 3 Feb 2010 12:31:51 +0100 (CET) Subject: [py-svn] r71077 - in py/extradoc/talk/pycon-us-2010/pytest-introduction: . 1 1/myscan 1/myscan/test Message-ID: <20100203113151.78DA61683DA@codespeak.net> Author: hpk Date: Wed Feb 3 12:31:50 2010 New Revision: 71077 Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/ - copied from r70384, py/extradoc/talk/pycon-us-2009/pytest-introduction/ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/__init__.py py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/config.py py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/test/ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/test/__init__.py py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/test/test_config.py py/extradoc/talk/pycon-us-2010/pytest-introduction/author.latex py/extradoc/talk/pycon-us-2010/pytest-introduction/beamerdefs.txt py/extradoc/talk/pycon-us-2010/pytest-introduction/makepdf (contents, props changed) py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-basic.txt py/extradoc/talk/pycon-us-2010/pytest-introduction/rst2beamer.py (contents, props changed) py/extradoc/talk/pycon-us-2010/pytest-introduction/title.latex Log: initial tutorial draft, work-in-progress Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/__init__.py ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/__init__.py Wed Feb 3 12:31:50 2010 @@ -0,0 +1 @@ +# Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/config.py ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/config.py Wed Feb 3 12:31:50 2010 @@ -0,0 +1,10 @@ +from ConfigParser import ConfigParser + +class Config: + def __init__(self, path): + f = open(path) + parser = ConfigParser() + parser.readfp(f) + f.close() + parser.read(path) + self.extensions = parser.get("myapp", 'extensions').split() Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/test/__init__.py ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/test/__init__.py Wed Feb 3 12:31:50 2010 @@ -0,0 +1 @@ +# Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/test/test_config.py ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/1/myscan/test/test_config.py Wed Feb 3 12:31:50 2010 @@ -0,0 +1,18 @@ + +from py.test import raises +from myscan.config import Config +import os + +def test_config_extensions(): + import tempfile + tmpdir = tempfile.mkdtemp() + path = os.path.join(tmpdir, 'config.ini') + f = open(path, 'w') + f.write("[myapp]\n") + f.write("extensions = .txt .rst") + f.close() + config = Config(path) + assert config.extensions == ['.txt', '.rst'] + +def test_parsefile_file_not_exists(): + raises(IOError, "Config('file_not_exists')") Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/author.latex ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/author.latex Wed Feb 3 12:31:50 2010 @@ -0,0 +1,7 @@ +\definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} + +\title[py.test basic testing tutorial] {pytest basic testing tutorial} +\author[H. Krekel]{Holger Krekel \\ http://merlinux.eu} + +\institute[PyCon US 2010, Atlanta]{PyCon US 2010, Atlanta} +\date{Feb 18th, 2010} Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/beamerdefs.txt ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/beamerdefs.txt Wed Feb 3 12:31:50 2010 @@ -0,0 +1,77 @@ +.. colors +.. =========================== + +.. role:: green +.. role:: red + + +.. general useful commands +.. =========================== + +.. |pause| raw:: latex + + \pause + +.. |small| raw:: latex + + {\small + +.. |end_small| raw:: latex + + } + + +.. closed bracket +.. =========================== + +.. |>| raw:: latex + + } + + +.. example block +.. =========================== + +.. |example<| raw:: latex + + \begin{exampleblock}{ + + +.. |end_example| raw:: latex + + \end{exampleblock} + + + +.. alert block +.. =========================== + +.. |alert<| raw:: latex + + \begin{alertblock}{ + + +.. |end_alert| raw:: latex + + \end{alertblock} + + + +.. columns +.. =========================== + +.. |column1| raw:: latex + + \begin{columns} + \begin{column}{0.45\textwidth} + +.. |column2| raw:: latex + + \end{column} + \begin{column}{0.45\textwidth} + + +.. |end_columns| raw:: latex + + \end{column} + \end{columns} Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/makepdf ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/makepdf Wed Feb 3 12:31:50 2010 @@ -0,0 +1,14 @@ +#!/bin/bash + +# you can find rst2beamer.py here: +# http://codespeak.net/svn/user/antocuni/bin/rst2beamer.py + +# WARNING: to work, it needs this patch for docutils +# https://sourceforge.net/tracker/?func=detail&atid=422032&aid=1459707&group_id=38414 + +BASE=pytest-basic +python rst2beamer.py --stylesheet=stylesheet.latex --documentoptions=14pt $BASE.txt $BASE.latex || exit +sed 's/\\date{}/\\input{author.latex}/' $BASE.latex >tmpfile || exit +sed 's/\\maketitle/\\input{title.latex}/' tmpfile >$BASE.latex || exit +pdflatex $BASE.latex || exit + Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-basic.txt ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-basic.txt Wed Feb 3 12:31:50 2010 @@ -0,0 +1,484 @@ +.. include:: beamerdefs.txt +.. include:: + +================================================================= +Rapid testing with py.test +================================================================= + +these slides +==================== + +If you have time before the tutorial starts, please make sure +you have installed the latest pylib. You need either: + +- ``setuptools``: http://pypi.python.org/pypi/setuptools +- ``distribute``: http://pypi.python.org/pypi/distribute + +and can then type:: + + easy_install py # or + pip install py + +A copy of this presentation & exercises: + +http://codespeak.net/svn/py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-introduction.zip + +me +== + +Holger Krekel + +- developer of py.test and execnet +- founded the PyPy project +- Python since around 2000 +- Test-driven development since 2001 +- operates a small company doing open + source, Python and test-oriented consulting + +you +=== + +What is your background? + +.. class:: handout + + Python background + Testing background + python testing libraries: unittest, nose, py.test... + +why automated testing? +================================== + +- to allow for later changes +- to raise confidence that code works +- to specify and document behaviour +- collaborative and faster development cycles + +Developer oriented automated tests +======================================== + +* unittest: units react well to input. +* integration: components co-operate nicely +* functional: code changes work out in user environments + +unittest +============ + +assert that functions and classes behave as expected + +.. image:: img/small.png + :align: center + :scale: 70 + + +integration +============== + +assert units/components co-operate nicely + +.. image:: img/medium.png + :align: center + :scale: 70 + + +functional / system +======================== + +things work in user target environment + +.. image:: img/large.png + :align: center + :scale: 70 + +The test tool question +======================================== + +what is the job of automated testing tools? + + +my current answer +======================================== + +* verify code changes work out +* be helpful when tests fail + +If failures are not helpful ... +======================================== + +improve the test tool or + +write more or write different tests + +py.test basics +============================================================================ + +.. image:: img/new_color_in_dark_old_city_by_marikaz.jpg + :scale: 100 + :align: left + +http://marikaz.deviantart.com/ CC 3.0 AN-ND + +py.test fundamental features +=============================== + +- cross-project testing tool +- no-boilerplate test code +- useful information when a test fails +- deep extensibility +- distribute tests to multiple hosts + +cross-project test tool +=========================== + +- tests are run via ``py.test`` command line tool. + +- project specific ``conftest.py`` files + +- testing starts from files/dirs or current dir + +examples:: + + py.test test_file.py + py.test path/to/tests + +A Typical Python test layout +========================================== +:: + + mypkg/__init__.py + ... + mypkg/tests/test_module.py + ... + +example invocation:: + + py.test mypkg + +Another typical test layout +========================================== +:: + + mypkg/__init__.py + ... + test/test_module.py + +example invocations:: + + py.test test + py.test # starts discovery in cwd + +mind the `tests/__init__.py` files +========================================== + +- test files are imported as normal python modules +- make test directories a package to disambiguate + +note: first non-``__init__.py`` dir is inserted into sys.path + +automatic test discovery +=================================== + +py.test walks over the filesystem and: + +- discovers ``test_*.py`` test files +- discovers ``test_`` functions and ``Test`` classes + +**automatic discovery avoids boilerplate** + +no boilerplate python test code +================================= + +example test functions/methods:: + + def test_something(): + x = 3 + assert x == 4 + + class TestSomething: + def test_something(self): + x = 1 + assert x == 5 + +assert introspection +======================= + +:: + + def test_assert_introspection(): + # with unittest.py + assert x # assertTrue() + assert x == 1 # assertEqual(x, 1) + assert x != 2 # assertNotEqual(x, 2) + assert not x # assertFalse(x) + + +assertin expected exceptions +================================ + +:: + + import py + + def test_raises_one(): + py.test.raises(ValueError, int, 'foo') + + def test_raises_two(): + py.test.raises(ValueError, "int('foo')") + +Failure / Traceback Demo +=========================== + +interactive demo: ``py.test failure_demo.py`` + + +print() debugging +================= + +:: + + def test_something1(): + print "Useful debugging information." + assert False + +output captured per function run, only shown on failure. + +some important options +======================== + +see also ``py.test -h``: + +- -s disable catching of stdout/stderr +- -x exit instantly on first failure +- -k run tests whose names contain a keyword +- -l show locals in tracebacks. +- --pdb start Python debugger on errors +- --tb/fulltrace - control traceback generation. + +Getting Started ... +============================= + +Installation: + +``easy_install -U py``, ``pip install py`` or: + + - hg clone https://bitbucket.org/hpk42/py-trunk/ + - run "python setup.py" with "install" or "develop" + +Notes: + + http://pylib.org/install.html + +"myscan": Exercises of this tutorial +===================================== + +we'll step-by-step build up a ``myscan`` project with tests. + +in the process you learn how to use py.test conveniently. + + +sketching our "myscan" project +================================ + +Application Objects: + +- Config object: read configuration from an .ini file +- Scanner object: parse files for lines starting with a prefix + +Tests will be about: + +- config file parsing +- using the scanner object and its method(s) + +Starting Exercise +=========================== + +- create ``myscan/test/test_config.py`` (plus ``__init__.py`` files) +- create ``myscan/config.py`` +- write a test that instantiates ``myscan.config.Config()`` + and checks that ``extensions`` is initialized +- run ``py.test mypkg`` + +Helping Notes +============================= + +test setup / fixture basics +==================================================== + +a test fixture: + +- sets up objects or apps for testing +- provides test code with "base" app objects +- py.test supports xUnit/unittest.py/nosetests style setup + +test functions and funcargs +==================================================== + +**funcargs** are a unique py.test feature: + +- a mechanism for providing test "base" values +- can easily depend on command line options +- separates test code from test setup +- naturally extend towards test parametrization + +let's look a bit more at the motivation ... + +Typical test function - viewed abstractly +========================================== +:: + + from mypkg.mod import SomeClass + def test_method(): + inst1 = SomeClass("somevalue") + ... + assert inst1.method() == "ok" + + +observations and the fixture question +========================================== + +* the test wants to check a method call result +* ``SomeClass`` base value Instantiation mixes with test code +* the ``mypkg.mod.SomeClass`` reference may change + +What if multiple test functions need a similar instance? + +old-style strategy: xUnit-style fixtures +========================================== + +:: + + from mypkg.mod import SomeClass + import unittest + class TestGroup(unittest.TestCase): + def setUp(self): + self.inst1 = SomeClass("somevalue") + + def test_something(self): + ... use self.inst1 ... + assert self.inst1.method() == "ok" + + +observations / notes +========================================== + +* unittest-runner automatically invokes ``self.setUp()`` + for each test function invocation. +* test value for Instantiation mixes with test module code +* ``mypkg.mod.SomeClass`` reference may change +* **multiple methods can reuse the same setup** +* **test functions group by setup code** + +meet "funcargs" - test function arguments +========================================== + +simple funcarg test code example:: + + def test_something(inst1): + assert inst1.method() == "ok" + +observations +============== + +* test function "requests" arguments it needs +* functions/methods re-use same funcarg setup +* grouping in test classes independent of setup + +How to provide the function argument? +========================================== +:: + + #./conftest.py (or directly in test module) + + from mypkg.mod import SomeClass + def pytest_funcarg__inst1(request): + return SomeClass("somevalue") + +funcarg factory observations +=================================================== + +* discovered through naming convention +* loosely coupled, separated from test code +* will be called for each test function +* has one mypkg.mod.SomeClass reference + +Exercise +========================================== + +* write a package "mypkg" +* add mypkg/__init__.py and mypkg/test_url.py +* add a ``def test_path(url)`` function +* write a ``pytest_funcarg__url`` factory in mypkg/conftest.py +* run your test + +(Bonus: play with wrong funcarg names) + +application scenario setup (30) +=================================================== + +- + +exercise: separate your test setup and test code and +implement the "mysetup" testing pattern + +step 1: use a "mysetup" +======================================== + +Let's write a simple test function living in a test file +``test_sample.py`` that uses a ``mysetup`` funcarg for accessing test +specific setup. + +.. sourcecode:: python + + # ./test_sample.py + def test_answer(mysetup): + app = mysetup.myapp() + answer = app.question() + assert answer == 42 + + +marking tests (15) +=================================================== + +interactive lecture: +- marking tests for skip and xfail +- marking classes and modules +- selectively running tests + +hooks and plugins (15) +=================================================== + +interactive lecture: +- conftest plugins +- plugin discovery +- pytest hook functions + +new command line option (20) +=================================================== + +exercise: +- add a new cmdline option for the "mysetup" setup object +- skip test depending on a cmdline option + +coverage testing (20) +=================================================== + +- figleaf and coverage tools +- installing figleaf or coverage +- exercise: get html coverage for your code + +overview on advanced usages (10) +=================================================== + +interactive lecture: +- looponfailing +- distributed testing (part II) +- generative tests (part II) +- doctests (part II) +- javascript testing + +conclusion (10 mins) +=================================================== + +- summary +- feedback session + Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/rst2beamer.py ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/rst2beamer.py Wed Feb 3 12:31:50 2010 @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# encoding: utf-8 +""" +A docutils script converting restructured text into Beamer-flavoured LaTeX. + +Beamer is a LaTeX document class for presentations. Via this script, ReST can +be used to prepare slides. It can be called:: + + rst2beamer.py infile.txt > outfile.tex + +where ``infile.tex`` contains the produced Beamer LaTeX. + +See for more details. + +""" +# TODO: modifications for handout sections? +# TOOD: sections and subsections? +# TODO: enable beamer themes? +# TODO: convert document metadata to front page fields? +# TODO: toc-conversion? +# TODO: fix descriptions + +# Unless otherwise stated, created by P-M Agapow on 2007-08-21 +# and open for academic & non-commercial use and modification . + +__docformat__ = 'restructuredtext en' +__author__ = "Paul-Michael Agapow " +__version__ = "0.2" + + +### IMPORTS ### + +import locale +from docutils.core import publish_cmdline, default_description +from docutils.writers.latex2e import Writer as Latex2eWriter +from docutils.writers.latex2e import LaTeXTranslator, DocumentClass +from docutils import nodes + +## CONSTANTS & DEFINES: ### + +BEAMER_SPEC = ( + 'Beamer options', + 'These are derived almost entirely from the LaTeX2e options', + tuple ( + [ + ( + 'Specify theme.', + ['--theme'], + {'default': '', } + ), + ( + 'Specify document options. Multiple options can be given, ' + 'separated by commas. Default is "10pt,a4paper".', + ['--documentoptions'], + {'default': '', } + ), + ] + list (Latex2eWriter.settings_spec[2][2:]) + ), +) + +BEAMER_DEFAULTS = { + 'output_encoding': 'latin-1', + 'documentclass': 'beamer', +} + + +### IMPLEMENTATION ### + +try: + locale.setlocale (locale.LC_ALL, '') +except: + pass + +class BeamerTranslator (LaTeXTranslator): + """ + A converter for docutils elements to beamer-flavoured latex. + """ + + def __init__ (self, document): + LaTeXTranslator.__init__ (self, document) + self.head_prefix = [x for x in self.head_prefix if ('{typearea}' not in x)] + hyperref_posn = [i for i in range (len (self.head_prefix)) if ('{hyperref}' in self.head_prefix[i])] + self.head_prefix[hyperref_posn[0]] = '\\usepackage{hyperref}\n' + self.head_prefix.extend ([ + '\\definecolor{rrblitbackground}{rgb}{0.55, 0.3, 0.1}\n', + '\\newenvironment{rtbliteral}{\n', + '\\begin{ttfamily}\n', + '\\color{rrblitbackground}\n', + '}{\n', + '\\end{ttfamily}\n', + '}\n', + ]) + # this fixes the hardcoded section titles in docutils 0.4 + self.d_class = DocumentClass ('article') + + def begin_frametag (self): + return '\\begin{frame}\n' + + def end_frametag (self): + return '\\end{frame}\n' + + def visit_section (self, node): + if (self.section_level == 0): + self.body.append (self.begin_frametag()) + LaTeXTranslator.visit_section (self, node) + + def depart_section (self, node): + # Remove counter for potential subsections: + LaTeXTranslator.depart_section (self, node) + if (self.section_level == 0): + self.body.append (self.end_frametag()) + + def visit_title (self, node): + if (self.section_level == 1): + self.body.append ('\\frametitle{%s}\n\n' % self.encode(node.astext())) + raise nodes.SkipNode + else: + LaTeXTranslator.visit_title (self, node) + + def depart_title (self, node): + if (self.section_level != 1): + LaTeXTranslator.depart_title (self, node) + + def visit_literal_block(self, node): + if not self.active_table.is_open(): + self.body.append('\n\n\\smallskip\n\\begin{rtbliteral}\n') + self.context.append('\\end{rtbliteral}\n\\smallskip\n\n') + else: + self.body.append('\n') + self.context.append('\n') + if (self.settings.use_verbatim_when_possible and (len(node) == 1) + # in case of a parsed-literal containing just a "**bold**" word: + and isinstance(node[0], nodes.Text)): + self.verbatim = 1 + self.body.append('\\begin{verbatim}\n') + else: + self.literal_block = 1 + self.insert_none_breaking_blanks = 1 + + def depart_literal_block(self, node): + if self.verbatim: + self.body.append('\n\\end{verbatim}\n') + self.verbatim = 0 + else: + self.body.append('\n') + self.insert_none_breaking_blanks = 0 + self.literal_block = 0 + self.body.append(self.context.pop()) + + +class BeamerWriter (Latex2eWriter): + """ + A docutils writer that modifies the translator and settings for beamer. + """ + settings_spec = BEAMER_SPEC + settings_defaults = BEAMER_DEFAULTS + + def __init__(self): + Latex2eWriter.__init__(self) + self.translator_class = BeamerTranslator + + +if __name__ == '__main__': + description = ( + "Generates Beamer-flavoured LaTeX for PDF-based presentations." + default_description) + publish_cmdline (writer=BeamerWriter(), description=description) + + +### END ###################################################################### + Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/title.latex ============================================================================== --- (empty file) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/title.latex Wed Feb 3 12:31:50 2010 @@ -0,0 +1,7 @@ +\begin{titlepage} +\begin{figure}[h] +\includegraphics[width=64px,height=64px]{img/merlinux-logo.jpg} +\qquad +\includegraphics[width=80px]{img/py-web.png} +\end{figure} +\end{titlepage} From hpk at codespeak.net Wed Feb 3 12:44:11 2010 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 3 Feb 2010 12:44:11 +0100 (CET) Subject: [py-svn] r71078 - in py/extradoc/talk/pycon-us-2010/pytest-introduction: . 0 Message-ID: <20100203114411.3377D1683DA@codespeak.net> Author: hpk Date: Wed Feb 3 12:44:10 2010 New Revision: 71078 Added: py/extradoc/talk/pycon-us-2010/pytest-introduction/0/ py/extradoc/talk/pycon-us-2010/pytest-introduction/0/test_examples.py - copied, changed from r71077, py/extradoc/talk/pycon-us-2010/pytest-introduction/test_examples.py Removed: py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-introduction.html py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-introduction.txt py/extradoc/talk/pycon-us-2010/pytest-introduction/test_examples.py Modified: py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-basic.txt Log: cleanup, put test_examples.py into "0" subdir Copied: py/extradoc/talk/pycon-us-2010/pytest-introduction/0/test_examples.py (from r71077, py/extradoc/talk/pycon-us-2010/pytest-introduction/test_examples.py) ============================================================================== --- py/extradoc/talk/pycon-us-2010/pytest-introduction/test_examples.py (original) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/0/test_examples.py Wed Feb 3 12:44:10 2010 @@ -24,7 +24,7 @@ print "Useful debugging information." assert True - at py.test.mark.xfail("Expected failure.") + at py.test.mark.xfail def test_something2(): print "Useful debugging information." assert False @@ -45,7 +45,7 @@ print "Useful debugging information." assert True - at py.test.mark.xfail("Expected failure.") + at py.test.mark.xfail() def test_something2(): print "Useful debugging information." assert False @@ -67,7 +67,7 @@ assert True def test_two(): assert 1 == 1 - at py.test.mark.xfail("Expected failure.") + at py.test.mark.xfail() def test_three(): assert 1 == 2 def test_raises_one(): Modified: py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-basic.txt ============================================================================== --- py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-basic.txt (original) +++ py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-basic.txt Wed Feb 3 12:44:10 2010 @@ -289,18 +289,30 @@ - config file parsing - using the scanner object and its method(s) -Starting Exercise +Starting Exercise [1] =========================== -- create ``myscan/test/test_config.py`` (plus ``__init__.py`` files) -- create ``myscan/config.py`` -- write a test that instantiates ``myscan.config.Config()`` - and checks that ``extensions`` is initialized -- run ``py.test mypkg`` +create ``myscan/test/test_config.py`` and ``myscan/config.py`` +plus ``__init__.py`` files. + +write a test that creates an ``.ini`` file with this content:: + + [myapp] + extensions = .txt .rst + +then calls ``config = myscan.Config(filename)`` and asserts that +``config.extensions == ['.txt', '.rst']`` + +``py.test myscan`` Helping Notes ============================= +- ``tempfile.mkdtemp()`` creates a tmpdir +- ``ConfigParser.ConfigParser().read()`` reads an ini.file + +http://docs.python.org/library/configparser.html + test setup / fixture basics ==================================================== @@ -427,7 +439,7 @@ ``test_sample.py`` that uses a ``mysetup`` funcarg for accessing test specific setup. -.. sourcecode:: python +:: # ./test_sample.py def test_answer(mysetup): Deleted: /py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-introduction.html ============================================================================== --- /py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-introduction.html Wed Feb 3 12:44:10 2010 +++ (empty file) @@ -1,841 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -
-
-
- - -
-
-
- - - -
-
-

py.test - introduction

-

If you have time before the tutorial starts, please install the latest pylib:

- -

Get a copy of this presentation & exercises

- -
-
-

the plan

- -
-
-

us

-

Brian Dorsey <brian@dorseys.org>

-

enthusiastic user of py.test.

-

Holger Krekel <holger@merlinux.eu>

-

lead developer of py.test.

-
-
-

you

-

Who are you?

-

Python background -Testing background -python testing libraries: unitest, nose, py.test...

-
-
-

motivation and terms

-

(about 10 minutes)

-
-
-

A pragmatic view on test types

-

let's talk about small, medium or large tests.

-
-
-

Small Tests: one aspect

-
img/small.png
-
-
-

Medium Tests: two aspects

-
img/medium.png
-
-
-

Large Tests: three/more

-
img/large.png
-
-
-

why do automated testing?

-
    -
  • make sure the code works as advertised
  • -
  • make sure changes don't break existing behaviour
  • -
  • make sure bugs don't come back silently
  • -
  • leads to faster development and easier maintenance
  • -
-
-
-

test driven development

-
    -
  • There is some religion around Test Driven Development.
  • -
-
-
-

pragmatism

-

"I don't do test-driven development; I do stupidity-driven testing. When I do something stupid, I write a test to make sure I don't do it again." - Titus Brown

-
    -
  • Brian does Happy Path testing - kind of minimal TDD + SDD.
  • -
-
-
-

py.test core concepts

-

The fundamental features of py.test (about 10 minutes)

-
    -
  • no boilerplate: write tests rapidly
  • -
  • run all or subsets of tests
  • -
  • lots of useful information when a test fails
  • -
-
-
-

lets go!

-

$ py.test

-

(DEMO)

-
-
-

automatic test discovery

-

search all test_ and _test files

-

py.test searches for all modules which start with test_ or end with -_test. Within those modules, it collects all functions and methods which -start with test_.

-
-
-

function or class

-
-def test_something():
-    assert True
-
-class TestSomething():
-    def test_something(self):
-        assert True
-
-

Use individual test functions or group tests in classes. Use whichever -makes the most sense for each test or group of tests.

-
-
-

assert introspection

-
-def test_assert_introspection():
-    assert True         # assertTrue()
-    assert 1 == 1       # assertEqual()
-    assert not 1 == 2   # assertNotEqual()
-    assert not False    # assertFalse()
-
-

This allows you to write test code which looks just like application code. -For example, no need to pass functions and parameters separately into -assertEquals.

-
- -
-

less boilerplate

-

py.test uses naming conventions to reduce boilerplate registration code.

-
    -
  • file, function, class, method
  • -
  • TestSuite discovery story
  • -
-
-
-

simplicity

-

All of these features simplify writing your tests.

-
-
-

and many more

-

Many extra benefits included if you need them, ignore if not.

-
    -
  • setup / teardown of test runtime environment
  • -
  • testing on multiple platforms & python versions
  • -
  • distributed testing - across both processes and machines
  • -
  • extending with plugins
  • -
-
-
-

nose and py.test

-

"nose provides an alternate test discovery and running process for unittest, one that is intended to mimic the behavior of py.test as much as is reasonably possible without resorting to too much magic." -- from nose home page

-
    -
  • nosetest and py.test share basic philosophy and features.
  • -
  • py.test has a more refined debugging/failure API
  • -
  • nose has plugins - upcoming pytest-1.0 as well
  • -
  • for basic use, not much difference
  • -
  • more co-operation between the projects upcoming
  • -
-

None of the above features are in xUnit frameworks (like stdlib unittest)

-

Nose doesn't do re-interpretation of failed statements, so it prints less -context information when tests fail. The implementers of Nose prefer to -drop into pdb and debug when detailed context information is needed. (TODO: -confirm with Jason P that this is still true)

-
-
-

installation

-

Installation, hello world. (30 minutes)

-
    -
  • installation
  • -
  • test functions
  • -
  • 20 minute work time
  • -
-

Basic setup and working through inevitable setup problems. Some people -will finish very quickly - ask them to help others get setup.

-
-
-

exercise 1 (~20 min)

- -

Get a copy of this presentation & exercises

- -
-
-

basic usage

-

Basic usage of py.test (40 minutes)

-
    -
  • reinterpretation of asserts
  • -
  • working with failures - debug with print
  • -
  • exceptions
  • -
  • 10 minute work time - exercise
  • -
  • -
  • test classes
  • -
  • setup and teardown test state (special methods / funcargs)
  • -
  • 10 minute work time - exercise
  • -
-
-
-

exercise 2

-
    -
  • reinterpretation of asserts
  • -
  • working with failures - debug with print
  • -
  • bonus: exceptions
  • -
-
-
-

assert introspection

-
-def test_assert_introspection():
-    assert True         # assertTrue()
-    assert 1 == 1       # assertEqual()
-    assert not 1 == 2   # assertNotEqual()
-    assert not False    # assertFalse()
-
-

This allows you to write test code which looks just like application code. -For example, no need to pass functions and parameters separately into -assertEquals.

-
-
-

print() debugging

-
-import py
-
-def test_something1():
-    print "Useful debugging information."
-    assert True
-
-@py.test.mark.xfail("Expected failure.")
-def test_something2():
-    print "Useful debugging information."
-    assert False
-
-

stdout is captured for each test, and only printed if the test fails. You -can leave your debugging print statments in place to help your future -self.

-
-
-

testing exceptions

-
-import py
-
-def test_raises_one():
-    py.test.raises(ValueError, int, 'foo')
-
-def test_raises_two():
-    py.test.raises(ValueError, "int('foo')")
-
-
-
-

exercise 2 (~10 min)

-
-def test_one():
-    print "debug text"
-    assert True
-def test_two():
-    assert 1 == 1
-@py.test.mark.xfail("Expected failure.")
-def test_three():
-    assert 1 == 2
-def test_raises_one():
-    py.test.raises(ValueError, int, 'foo')
-def test_raises_two():
-    py.test.raises(ValueError, "int('foo')")
-
-
-
-

exercise 3

-
    -
  • test classes
  • -
  • setup and teardown test state (special methods / funcargs)
  • -
-
-
-

exercise 3 (~10 min)

-
-class TestSomething():
-    def setup_class(cls):
-        pass
-    def setup_method(self, method):
-        pass
-
-    def test_one(self):
-        assert True
-    def test_two(self):
-        assert 1 == 1
-
-
-
-

break

-
-
-

options

-
-$ py.test --help
-usage: py.test [options] [file_or_dir] [file_or_dir] [...]
-
-options:
--h, --help            show this help message and exit
-
-test collection and failure interaction options:
-    -v, --verbose       increase verbosity.
-    -x, --exitfirst     exit instantly on first error or failed test.
-    -k KEYWORD          only run test items matching the given space separated
-                        keywords.  precede a keyword with '-' to negate.
-                        Terminate the expression with ':' to treat a match as
-                        a signal to run all subsequent tests.
-    -l, --showlocals    show locals in tracebacks (disabled by default).
-    --pdb               start pdb (the Python debugger) on errors.
-    --tb=style          traceback verboseness (long/short/no).
-    -s                  disable catching of stdout/stderr during test run.
-    ...
-
-
-test collection and failure interaction options:
-    --boxed             box each test run in a separate process
-    -p PLUGIN           load the specified plugin after command line parsing.
-                        Example: '-p hello' will trigger 'import pytest_hello'
-                        and instantiate 'HelloPlugin' from the module.
-    -f, --looponfail    run tests, re-run failing test set until all pass.
-
-test process debugging:
-    --collectonly       only collect tests, don't execute them.
-    --traceconfig       trace considerations of conftest.py files.
-    --nomagic           don't reinterpret asserts, no traceback cutting.
-    --fulltrace         don't cut any tracebacks (default is to cut).
-    --basetemp=dir      base temporary directory for this test run.
-    --iocapture=method  set iocapturing method: fd|sys|no.
-    --debug             generate and show debugging information.
-
-distributed testing:
-    --dist=distmode     set mode for distributing tests to exec environments.
-                        each: send each test to each available environment.
-                        load: send each test to available environment.
-                        (default) no: run tests inprocess, don't distribute.
-    --tx=xspec          add a test execution environment. some examples: --tx
-                        popen//python=python2.5 --tx socket=192.168.1.102:8888
-                        --tx ssh=user@codespeak.net//chdir=testcache
-    -d                  load-balance tests.  shortcut for '--dist=load'
-    -n numprocesses     shortcut for '--dist=load --tx=NUM*popen'
-    --rsyncdir=dir1     add directory for rsyncing to remote tx nodes.
-
-
-
-

selected options

-

Options (25 minutes)

-
    -
  • -s - disable catching of stdout/stderr during test run.
  • -
  • -x/--exitfirst (*) - exit instantly on first error or failed test.
  • -
  • --showlocals (*) - show locals in tracebacks.
  • -
  • --pdb (*) - start pdb (the Python debugger) on errors.
  • -
  • -f/--looponfail (*) - loop on failing test set.
  • -
  • -k (*) - only run test items matching the given keyword.
  • -
  • --tb/fulltrace - different options to control traceback generation.
  • -
-

(*) more detail in advanced tutorial

-
-
-

demo: -s / --iocapture=no

-

test_trace_setup.py

-
-
-

demo: --exitfirst

-

test_examples.py

-
-
-

demo: --looponfail

-

test_examples.py

-
-
-

demo: -k

-

test_examples.py

-
-
-

exercise 4 (~10 min)

-
    -
  • -s - disable catching of stdout/stderr during test run.
  • -
  • -x/--exitfirst (*) - exit instantly on first error or failed test.
  • -
  • --showlocals (*) - show locals in tracebacks.
  • -
  • --pdb (*) - start pdb (the Python debugger) on errors.
  • -
  • -f/--looponfail (*) - loop on failing test set.
  • -
  • -k (*) - only run test items matching the given keyword.
  • -
  • --tb/fulltrace - different options to control traceback generation.
  • -
-

Experiment with a few of these options, ask questions and play.

-

If you're in the advanced class this afternoon. Think about other options -you'd like. Maybe we can make a plugin.

-
-
-

branching out

-

Branching out (20 minutes)

-
    -
  • skipping tests
  • -
  • generative tests
  • -
  • 10 minute work time - exercises
  • -
-
-
-

skipping tests

-
-import py
-
-def test_something_we_want_to_skip():
-    py.test.skip("fix delayed.")
-    assert True
-
-
-
-

generative tests 1

-
-def test_ensure_sufficient_spam1():
-    assert 'spam' in 'spam'.lower()
-    assert 'spam' in 'SPAM'.lower()
-    assert 'spam' in 'eggs & spam'.lower()
-    assert 'spam' in 'spammy'.lower()
-    assert 'spam' in 'more spam'.lower()
-
-
-
-

generative tests 2

-
-def test_ensure_sufficient_spam2():
-    data = ['spam', 'SPAM', 'eggs & spam',
-            'spammy', 'more spam']
-    for item in data:
-        assert 'spam' in item.lower()
-
-
-
-

generative tests 3

-
-def contains_spam(item):
-    assert 'spam' in item.lower()
-
-def test_ensure_sufficient_spam3():
-    data = ['spam', 'SPAM', 'eggs & spam',
-            'spammy', 'more spam']
-    for item in data:
-        yield contains_spam, item
-
-
-
-

exercise 5 (~10 min)

-
    -
  • skipping tests
  • -
  • generative tests
  • -
-
-
-

using plugins

-

Overview of using plugins (25 minutes)

-
    -
  • unittest
  • -
  • doctests
  • -
  • pocoo
  • -
-
-
-

enabling plugins - command line

-

$ py.test -p doctest -p unittest

-
-
-

enabling plugins - conftest.py

-

pytest_plugins = "doctest", "unittest"

-
-
-

plugins shipped with py.test

-

py/test/plugin

-
-
-

unittest plugin

-

(DEMO)

-
-
-

doctest plugin

-

(DEMO)

-
-
-

pocoo plugin

-

(DEMO)

-
-
-

wrap up & questions

-

Wrapping up and questions (20 minutes)

-

where to go from here:

- -

Quesitons?

-
-
- - Deleted: /py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-introduction.txt ============================================================================== --- /py/extradoc/talk/pycon-us-2010/pytest-introduction/pytest-introduction.txt Wed Feb 3 12:44:10 2010 +++ (empty file) @@ -1,646 +0,0 @@ - -py.test - introduction -====================== - -If you have time before the tutorial starts, please install the latest pylib: - -- svn checkout http://codespeak.net/svn/py/dist -- ... or download tar from: http://codespeak.net/py/dist/download.html -- run "python setup.py" with "install" or "develop" - -Get a copy of this presentation & exercises - -- http://codespeak.net/svn/py/extradoc/talk/pycon-us-2009/pytest-introduction/pytest-introduction.zip - - -the plan -======== - -- `motivation and terms`_ -- `py.test core concepts`_ -- `installation`_ (w/exercise) -- `basic usage`_ (w/exercise) -- `break`_ -- `options`_ (w/exercise) -- `branching out`_ (w/exercise) -- `using plugins`_ -- `wrap up & questions`_ - - -us -== - -Brian Dorsey - -enthusiastic user of py.test. - - -Holger Krekel - -lead developer of py.test. - - -you -=== - -Who are you? - -.. class:: handout - - Python background - Testing background - python testing libraries: unitest, nose, py.test... - - -motivation and terms -==================== - -*(about 10 minutes)* - - -A pragmatic view on test types -================================= - -let's talk about small, medium or large tests. - - -Small Tests: one aspect -============================== - -.. image:: img/small.png - :align: center - - -Medium Tests: two aspects -============================== - -.. image:: img/medium.png - :align: center - - -Large Tests: three/more -============================== - -.. image:: img/large.png - :align: center - - -why do automated testing? -========================= - -- make sure the code works as advertised -- make sure changes don't break existing behaviour -- make sure bugs don't come back silently -- leads to faster development and easier maintenance - - -test driven development -======================= - -- There is some religion around Test Driven Development. - - -pragmatism -========== - -*"I don't do test-driven development; I do stupidity-driven testing. When I do something stupid, I write a test to make sure I don't do it again."* - Titus Brown - -- Brian does Happy Path testing - kind of minimal TDD + SDD. - - -py.test core concepts -===================== - -*The fundamental features of py.test (about 10 minutes)* - -- no boilerplate: write tests rapidly -- run all or subsets of tests -- lots of useful information when a test fails - - -lets go! -======== - -$ py.test - -(DEMO) - - -automatic test discovery -======================== - -search all `test_` and `_test` files - -.. class:: handout - - py.test searches for all modules which start with `test_` or end with - `_test`. Within those modules, it collects all functions and methods which - start with `test_`. - - -function or class -================= - -:: - - def test_something(): - assert True - - class TestSomething(): - def test_something(self): - assert True - -.. class:: handout - - Use individual test functions or group tests in classes. Use whichever - makes the most sense for each test or group of tests. - - -assert introspection -==================== - -:: - - def test_assert_introspection(): - assert True # assertTrue() - assert 1 == 1 # assertEqual() - assert not 1 == 2 # assertNotEqual() - assert not False # assertFalse() - -.. class:: handout - - This allows you to write test code which looks just like application code. - For example, no need to pass functions and parameters separately into - assertEquals. - - -print() debugging -================= - -:: - - import py - - def test_something1(): - print "Useful debugging information." - assert True - - @py.test.mark.xfail("Expected failure.") - def test_something2(): - print "Useful debugging information." - assert False - - -.. class:: handout - - stdout is captured for each test, and only printed if the test fails. You - can leave your debugging print statments in place to help your future - self. - - -less boilerplate -================ - -py.test uses naming conventions to reduce boilerplate registration code. - -- file, function, class, method -- TestSuite discovery story - - -simplicity -========== - -All of these features simplify writing your tests. - - -and many more -============= - -Many extra benefits included if you need them, ignore if not. - -- setup / teardown of test runtime environment -- testing on multiple platforms & python versions -- distributed testing - across both processes and machines -- extending with plugins - - -nose and py.test -================ - -*"nose provides an alternate test discovery and running process for unittest, one that is intended to mimic the behavior of py.test as much as is reasonably possible without resorting to too much magic."* -- from nose home page - -- nosetest and py.test share basic philosophy and features. -- py.test has a more refined debugging/failure API -- nose has plugins - upcoming pytest-1.0 as well -- for basic use, not much difference -- more co-operation between the projects upcoming - -.. class:: handout - - None of the above features are in xUnit frameworks (like stdlib unittest) - - Nose doesn't do re-interpretation of failed statements, so it prints less - context information when tests fail. The implementers of Nose prefer to - drop into pdb and debug when detailed context information is needed. (TODO: - confirm with Jason P that this is still true) - - -installation -============ - -*Installation, hello world. (30 minutes)* - -- installation -- test functions -- 20 minute work time - -.. class:: handout - - Basic setup and working through inevitable setup problems. Some people - will finish very quickly - ask them to help others get setup. - -exercise 1 (~20 min) -===================== - -- svn checkout http://codespeak.net/svn/py/dist -- ... or download tar from: http://codespeak.net/py/dist/download.html -- run "python setup.py" with "install" or "develop" - -Get a copy of this presentation & exercises - -- http://codespeak.net/svn/py/extradoc/talk/pycon-us-2009/pytest-introduction/pytest-introduction.zip -- run: py.test test_hello.py -- find someone else to help successfully run test_hello.py - - -basic usage -=========== - -*Basic usage of py.test (40 minutes)* - -- reinterpretation of asserts -- working with failures - debug with print -- exceptions -- 10 minute work time - exercise -- -- test classes -- setup and teardown test state (special methods / funcargs) -- 10 minute work time - exercise - - -exercise 2 -========== - -- reinterpretation of asserts -- working with failures - debug with print -- bonus: exceptions - - -assert introspection -==================== - -:: - - def test_assert_introspection(): - assert True # assertTrue() - assert 1 == 1 # assertEqual() - assert not 1 == 2 # assertNotEqual() - assert not False # assertFalse() - -.. class:: handout - - This allows you to write test code which looks just like application code. - For example, no need to pass functions and parameters separately into - assertEquals. - - -print() debugging -================= - -:: - - import py - - def test_something1(): - print "Useful debugging information." - assert True - - @py.test.mark.xfail("Expected failure.") - def test_something2(): - print "Useful debugging information." - assert False - - -.. class:: handout - - stdout is captured for each test, and only printed if the test fails. You - can leave your debugging print statments in place to help your future - self. - - -testing exceptions -================== - -:: - - import py - - def test_raises_one(): - py.test.raises(ValueError, int, 'foo') - - def test_raises_two(): - py.test.raises(ValueError, "int('foo')") - - -exercise 2 (~10 min) -===================== - -:: - - def test_one(): - print "debug text" - assert True - def test_two(): - assert 1 == 1 - @py.test.mark.xfail("Expected failure.") - def test_three(): - assert 1 == 2 - def test_raises_one(): - py.test.raises(ValueError, int, 'foo') - def test_raises_two(): - py.test.raises(ValueError, "int('foo')") - - -exercise 3 -========== - -- test classes -- setup and teardown test state (special methods / funcargs) - - -exercise 3 (~10 min) -===================== - -:: - - class TestSomething(): - def setup_class(cls): - pass - def setup_method(self, method): - pass - - def test_one(self): - assert True - def test_two(self): - assert 1 == 1 - - -break -===== - - -options -======= - -:: - - $ py.test --help - usage: py.test [options] [file_or_dir] [file_or_dir] [...] - - options: - -h, --help show this help message and exit - - test collection and failure interaction options: - -v, --verbose increase verbosity. - -x, --exitfirst exit instantly on first error or failed test. - -k KEYWORD only run test items matching the given space separated - keywords. precede a keyword with '-' to negate. - Terminate the expression with ':' to treat a match as - a signal to run all subsequent tests. - -l, --showlocals show locals in tracebacks (disabled by default). - --pdb start pdb (the Python debugger) on errors. - --tb=style traceback verboseness (long/short/no). - -s disable catching of stdout/stderr during test run. - ... - - -.. class:: handout - -:: - - test collection and failure interaction options: - --boxed box each test run in a separate process - -p PLUGIN load the specified plugin after command line parsing. - Example: '-p hello' will trigger 'import pytest_hello' - and instantiate 'HelloPlugin' from the module. - -f, --looponfail run tests, re-run failing test set until all pass. - - test process debugging: - --collectonly only collect tests, don't execute them. - --traceconfig trace considerations of conftest.py files. - --nomagic don't reinterpret asserts, no traceback cutting. - --fulltrace don't cut any tracebacks (default is to cut). - --basetemp=dir base temporary directory for this test run. - --iocapture=method set iocapturing method: fd|sys|no. - --debug generate and show debugging information. - - distributed testing: - --dist=distmode set mode for distributing tests to exec environments. - each: send each test to each available environment. - load: send each test to available environment. - (default) no: run tests inprocess, don't distribute. - --tx=xspec add a test execution environment. some examples: --tx - popen//python=python2.5 --tx socket=192.168.1.102:8888 - --tx ssh=user at codespeak.net//chdir=testcache - -d load-balance tests. shortcut for '--dist=load' - -n numprocesses shortcut for '--dist=load --tx=NUM*popen' - --rsyncdir=dir1 add directory for rsyncing to remote tx nodes. - - -selected options -================ - -*Options (25 minutes)* - -- -s - disable catching of stdout/stderr during test run. -- -x/--exitfirst (*) - exit instantly on first error or failed test. -- --showlocals (*) - show locals in tracebacks. -- --pdb (*) - start pdb (the Python debugger) on errors. -- -f/--looponfail (*) - loop on failing test set. -- -k (*) - only run test items matching the given keyword. -- --tb/fulltrace - different options to control traceback generation. - -(*) more detail in advanced tutorial - -demo: -s / --iocapture=no -========================= - -test_trace_setup.py - -demo: --exitfirst -================= - -test_examples.py - - -demo: --looponfail -================== - -test_examples.py - - -demo: -k -======== - -test_examples.py - - -exercise 4 (~10 min) -===================== - -- -s - disable catching of stdout/stderr during test run. -- -x/--exitfirst (*) - exit instantly on first error or failed test. -- --showlocals (*) - show locals in tracebacks. -- --pdb (*) - start pdb (the Python debugger) on errors. -- -f/--looponfail (*) - loop on failing test set. -- -k (*) - only run test items matching the given keyword. -- --tb/fulltrace - different options to control traceback generation. - -.. class:: handout - - Experiment with a few of these options, ask questions and play. - - If you're in the advanced class this afternoon. Think about other options - you'd like. Maybe we can make a plugin. - - -branching out -============= - -*Branching out (20 minutes)* - -- skipping tests -- generative tests -- 10 minute work time - exercises - - -skipping tests -============== - -:: - - import py - - def test_something_we_want_to_skip(): - py.test.skip("fix delayed.") - assert True - - -generative tests 1 -================== - -:: - - def test_ensure_sufficient_spam1(): - assert 'spam' in 'spam'.lower() - assert 'spam' in 'SPAM'.lower() - assert 'spam' in 'eggs & spam'.lower() - assert 'spam' in 'spammy'.lower() - assert 'spam' in 'more spam'.lower() - - -generative tests 2 -================== - -:: - - def test_ensure_sufficient_spam2(): - data = ['spam', 'SPAM', 'eggs & spam', - 'spammy', 'more spam'] - for item in data: - assert 'spam' in item.lower() - - -generative tests 3 -================== - -:: - - def contains_spam(item): - assert 'spam' in item.lower() - - def test_ensure_sufficient_spam3(): - data = ['spam', 'SPAM', 'eggs & spam', - 'spammy', 'more spam'] - for item in data: - yield contains_spam, item - - -exercise 5 (~10 min) -===================== - -- skipping tests -- generative tests - - -using plugins -============= - -*Overview of using plugins (25 minutes)* - -- unittest -- doctests -- pocoo - - -enabling plugins - command line -=============================== - -$ py.test -p doctest -p unittest - - -enabling plugins - conftest.py -============================== - -pytest_plugins = "doctest", "unittest" - - -plugins shipped with py.test -============================ - -py/test/plugin - - -unittest plugin -=============== - -(DEMO) - - -doctest plugin -============== - -(DEMO) - - -pocoo plugin -============ - -(DEMO) - - -wrap up & questions -=================== - -*Wrapping up and questions (20 minutes)* - -where to go from here: - -- http://pytest.org -- irc.freenode.org #pylib - -Quesitons? - - - - Deleted: /py/extradoc/talk/pycon-us-2010/pytest-introduction/test_examples.py ============================================================================== --- /py/extradoc/talk/pycon-us-2010/pytest-introduction/test_examples.py Wed Feb 3 12:44:10 2010 +++ (empty file) @@ -1,125 +0,0 @@ -# function or class -# - -def test_something(): - assert True - -class TestSomething(): - def test_something(self): - assert True -# assert introspection -# - -def test_assert_introspection(): - assert True # assertTrue() - assert 1 == 1 # assertEqual() - assert not 1 == 2 # assertNotEqual() - assert not False # assertFalse() -# print() debugging -# - -import py - -def test_something1(): - print "Useful debugging information." - assert True - - at py.test.mark.xfail("Expected failure.") -def test_something2(): - print "Useful debugging information." - assert False -# assert introspection -# - -def test_assert_introspection(): - assert True # assertTrue() - assert 1 == 1 # assertEqual() - assert not 1 == 2 # assertNotEqual() - assert not False # assertFalse() -# print() debugging -# - -import py - -def test_something1(): - print "Useful debugging information." - assert True - - at py.test.mark.xfail("Expected failure.") -def test_something2(): - print "Useful debugging information." - assert False -# testing exceptions -# - -import py - -def test_raises_one(): - py.test.raises(ValueError, int, 'foo') - -def test_raises_two(): - py.test.raises(ValueError, "int('foo')") -# exercise 2 (~10 min) -# - -def test_one(): - print "debug text" - assert True -def test_two(): - assert 1 == 1 - at py.test.mark.xfail("Expected failure.") -def test_three(): - assert 1 == 2 -def test_raises_one(): - py.test.raises(ValueError, int, 'foo') -def test_raises_two(): - py.test.raises(ValueError, "int('foo')") -# exercise 3 (~10 min) -# - -class TestSomething(): - def setup_class(cls): - pass - def setup_method(self, method): - pass - - def test_one(self): - assert True - def test_two(self): - assert 1 == 1 -# skipping tests -# - -import py - -def test_something_we_want_to_skip(): - py.test.skip("fix delayed.") - assert True -# generative tests 1 -# - -def test_ensure_sufficient_spam1(): - assert 'spam' in 'spam'.lower() - assert 'spam' in 'SPAM'.lower() - assert 'spam' in 'eggs & spam'.lower() - assert 'spam' in 'spammy'.lower() - assert 'spam' in 'more spam'.lower() -# generative tests 2 -# - -def test_ensure_sufficient_spam2(): - data = ['spam', 'SPAM', 'eggs & spam', - 'spammy', 'more spam'] - for item in data: - assert 'spam' in item.lower() -# generative tests 3 -# - -def contains_spam(item): - assert 'spam' in item.lower() - -def test_ensure_sufficient_spam3(): - data = ['spam', 'SPAM', 'eggs & spam', - 'spammy', 'more spam'] - for item in data: - yield contains_spam, item From commits-noreply at bitbucket.org Thu Feb 4 12:27:06 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 4 Feb 2010 11:27:06 +0000 (UTC) Subject: [py-svn] py-trunk commit 63eee427687c: check and load test*/conftest.py early from anchors - Message-ID: <20100204112706.76E0D7EF2A@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265282813 -3600 # Node ID 63eee427687c806c84c024fbcf82e23f8d8c6744 # Parent 4c8a950ce346d8f151fefac222dbfc7e91dae728 check and load test*/conftest.py early from anchors - this makes it a bit more convenient to have command line options available from a root directory of a project that does not directly contain a conftest.py --- a/py/_test/conftesthandle.py +++ b/py/_test/conftesthandle.py @@ -39,6 +39,10 @@ class Conftest(object): anchor = current.join(arg, abs=1) if anchor.check(): # we found some file object self._path2confmods[None] = self.getconftestmodules(anchor) + # let's also consider test* dirs + if anchor.check(dir=1): + for x in anchor.listdir("test*"): + self.getconftestmodules(x) break else: assert 0, "no root of filesystem?" --- a/testing/test_conftesthandle.py +++ b/testing/test_conftesthandle.py @@ -132,3 +132,19 @@ def test_setinitial_confcut(testdir): assert conftest._confcutdir == sub assert conftest.getconftestmodules(sub) == [] assert conftest.getconftestmodules(conf.dirpath()) == [] + +def test_setinitial_not_considers_conftest_in_non_test_dirs(testdir): + sub = testdir.mkdir("sub") + sub.ensure("conftest.py") + conftest = Conftest() + conftest.setinitial([sub.dirpath()]) + assert not conftest._conftestpath2mod + + at py.test.mark.multi(name='test tests testing'.split()) +def test_setinitial_considers_conftest_in_test_dirs(testdir, name): + sub = testdir.mkdir(name) + subconftest = sub.ensure("conftest.py") + conftest = Conftest() + conftest.setinitial([sub.dirpath()]) + assert subconftest in conftest._conftestpath2mod + assert len(conftest._conftestpath2mod) == 1 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Changes between 1.2.1 and 1.2.0 ===================================== +- early-load "test*/conftest.py" files, i.e. conftest.py files in + directories starting with 'test'. allows to conveniently keep and access + test-related options without having to put a conftest.py into the package root dir. - fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value - fix issue78: always call python-level teardown functions even if the according setup failed. This includes refinements for calling setup_module/class functions From commits-noreply at bitbucket.org Thu Feb 4 16:13:40 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 4 Feb 2010 15:13:40 +0000 (UTC) Subject: [py-svn] py-trunk commit f58cfc0bf0b9: fix a test Message-ID: <20100204151340.52FBC7EF27@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265296410 -3600 # Node ID f58cfc0bf0b9dda38d5b451ecb9559f6f012364a # Parent 63605bbed9cd43bb510c68d8ee9617e9ba43fd4e fix a test --- a/testing/test_funcargs.py +++ b/testing/test_funcargs.py @@ -160,7 +160,7 @@ class TestRequest: def test_func(something): pass """) req = funcargs.FuncargRequest(item) - py.test.raises(req.Error, req.getfuncargvalue, "notexists") + py.test.raises(req.LookupError, req.getfuncargvalue, "notexists") val = req.getfuncargvalue("something") assert val == 1 val = req.getfuncargvalue("something") From commits-noreply at bitbucket.org Thu Feb 4 16:01:36 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 4 Feb 2010 15:01:36 +0000 (UTC) Subject: [py-svn] py-trunk commit 63605bbed9cd: show a short and nice traceback for funcarg lookup errors Message-ID: <20100204150136.2FFF87EF00@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265295662 -3600 # Node ID 63605bbed9cd43bb510c68d8ee9617e9ba43fd4e # Parent 63eee427687c806c84c024fbcf82e23f8d8c6744 show a short and nice traceback for funcarg lookup errors --- a/py/_test/funcargs.py +++ b/py/_test/funcargs.py @@ -64,7 +64,7 @@ class FuncargRequest: _argprefix = "pytest_funcarg__" _argname = None - class Error(LookupError): + class LookupError(LookupError): """ error on performing funcarg request. """ def __init__(self, pyfuncitem): @@ -170,7 +170,6 @@ class FuncargRequest: if name not in available: available.append(name) fspath, lineno, msg = self._pyfuncitem.reportinfo() - line = "%s:%s" %(fspath, lineno) - msg = "funcargument %r not found for: %s" %(argname, line) + msg = "LookupError: no factory found for function argument %r" % (argname,) msg += "\n available funcargs: %s" %(", ".join(available),) - raise self.Error(msg) + raise self.LookupError(msg) --- a/py/_test/pycollect.py +++ b/py/_test/pycollect.py @@ -5,6 +5,7 @@ import py import inspect from py._test.collect import configproperty, warnoldcollect from py._test import funcargs +from py._code.code import TerminalRepr class PyobjMixin(object): def obj(): @@ -252,12 +253,38 @@ class FunctionMixin(PyobjMixin): traceback = ntraceback.filter() return traceback + def _repr_failure_py(self, excinfo): + if excinfo.errisinstance(funcargs.FuncargRequest.LookupError): + fspath, lineno, msg = self.reportinfo() + lines, _ = inspect.getsourcelines(self.obj) + for i, line in enumerate(lines): + if line.strip().startswith('def'): + return FuncargLookupErrorRepr(fspath, lineno, + lines[:i+1], str(excinfo.value)) + return super(FunctionMixin, self)._repr_failure_py(excinfo) + def repr_failure(self, excinfo, outerr=None): assert outerr is None, "XXX outerr usage is deprecated" return self._repr_failure_py(excinfo) shortfailurerepr = "F" +class FuncargLookupErrorRepr(TerminalRepr): + def __init__(self, filename, firstlineno, deflines, errorstring): + self.deflines = deflines + self.errorstring = errorstring + self.filename = filename + self.firstlineno = firstlineno + + def toterminal(self, tw): + tw.line() + for line in self.deflines: + tw.line(" " + line.strip()) + for line in self.errorstring.split("\n"): + tw.line(" " + line.strip(), red=True) + tw.line() + tw.line("%s:%d" % (self.filename, self.firstlineno+1)) + class Generator(FunctionMixin, PyCollectorMixin, py.test.collect.Collector): def collect(self): # test generators are seen as collectors but they also --- a/testing/test_funcargs.py +++ b/testing/test_funcargs.py @@ -30,7 +30,8 @@ class TestFillFuncArgs: return 42 """) item = testdir.getitem("def test_func(some): pass") - exc = py.test.raises(LookupError, "funcargs.fillfuncargs(item)") + exc = py.test.raises(funcargs.FuncargRequest.LookupError, + "funcargs.fillfuncargs(item)") s = str(exc.value) assert s.find("xyzsomething") != -1 @@ -560,3 +561,18 @@ def test_funcarg_non_pycollectobj(testdi funcargs.fillfuncargs(clscol) assert clscol.funcargs['arg1'] == 42 + +def test_funcarg_lookup_error(testdir): + p = testdir.makepyfile(""" + def test_lookup_error(unknown): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*ERROR at setup of test_lookup_error*", + "*def test_lookup_error(unknown):*", + "*LookupError: no factory found*unknown*", + "*available funcargs*", + "*1 error*", + ]) + assert "INTERNAL" not in result.stdout.str() --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Changes between 1.2.1 and 1.2.0 ===================================== +- display a short and concise traceback if a funcarg lookup fails - early-load "test*/conftest.py" files, i.e. conftest.py files in directories starting with 'test'. allows to conveniently keep and access test-related options without having to put a conftest.py into the package root dir. From commits-noreply at bitbucket.org Thu Feb 4 23:45:30 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 4 Feb 2010 22:45:30 +0000 (UTC) Subject: [py-svn] py-trunk commit da57b132ee9d: add a --funcargs option showing available funcargs Message-ID: <20100204224530.8D2377EF1D@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265323507 -3600 # Node ID da57b132ee9db9e8d91326e33c681dbe55cb1c4e # Parent f58cfc0bf0b9dda38d5b451ecb9559f6f012364a add a --funcargs option showing available funcargs --- a/testing/plugin/test_pytest_terminal.py +++ b/testing/plugin/test_pytest_terminal.py @@ -588,3 +588,12 @@ def test_trace_reporting(testdir): "*active plugins*" ]) assert result.ret == 0 + + at py.test.mark.nodist +def test_show_funcarg(testdir, option): + result = testdir.runpytest(*option._getcmdargs()) + assert result.stdout.fnmatch_lines([ + "*tmpdir*", + "*temporary directory*", + ] + ]) --- a/py/_plugin/pytest_terminal.py +++ b/py/_plugin/pytest_terminal.py @@ -23,21 +23,27 @@ def pytest_addoption(parser): group._addoption('--fulltrace', action="store_true", dest="fulltrace", default=False, help="don't cut any tracebacks (default is to cut).") - + group._addoption('--funcargs', + action="store_true", dest="showfuncargs", default=False, + help="show available function arguments, sorted by plugin") def pytest_configure(config): if config.option.collectonly: reporter = CollectonlyReporter(config) + elif config.option.showfuncargs: + config.setsessionclass(ShowFuncargSession) + reporter = None else: reporter = TerminalReporter(config) - # XXX see remote.py's XXX - for attr in 'pytest_terminal_hasmarkup', 'pytest_terminal_fullwidth': - if hasattr(config, attr): - #print "SETTING TERMINAL OPTIONS", attr, getattr(config, attr) - name = attr.split("_")[-1] - assert hasattr(self.reporter._tw, name), name - setattr(reporter._tw, name, getattr(config, attr)) - config.pluginmanager.register(reporter, 'terminalreporter') + if reporter: + # XXX see remote.py's XXX + for attr in 'pytest_terminal_hasmarkup', 'pytest_terminal_fullwidth': + if hasattr(config, attr): + #print "SETTING TERMINAL OPTIONS", attr, getattr(config, attr) + name = attr.split("_")[-1] + assert hasattr(self.reporter._tw, name), name + setattr(reporter._tw, name, getattr(config, attr)) + config.pluginmanager.register(reporter, 'terminalreporter') def getreportopt(optvalue): d = {} @@ -447,3 +453,42 @@ def flatten(l): yield y else: yield x + +from py._test.session import Session +class ShowFuncargSession(Session): + def main(self, colitems): + self.sessionstarts() + try: + self.showargs(colitems[0]) + finally: + self.sessionfinishes(exitstatus=1) + + def showargs(self, colitem): + tw = py.io.TerminalWriter() + from py._test.funcargs import getplugins + from py._test.funcargs import FuncargRequest + plugins = getplugins(colitem, withpy=True) + verbose = self.config.getvalue("verbose") + for plugin in plugins: + available = [] + for name, factory in vars(plugin).items(): + if name.startswith(FuncargRequest._argprefix): + name = name[len(FuncargRequest._argprefix):] + if name not in available: + available.append([name, factory]) + if available: + pluginname = plugin.__name__ + for name, factory in available: + if verbose: + funcargspec = "%s -- from %s" %(name, plugin,) + else: + funcargspec = name + tw.line(funcargspec, green=True) + doc = factory.__doc__ or "" + if doc: + for line in doc.split("\n"): + tw.line(" " + line.strip()) + else: + tw.line(" no docstring available", red=True) + tw.line(factory, red=True) + tw.line(plugin, red=True) --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Changes between 1.2.1 and 1.2.0 ===================================== +- add a new option "--funcargs" that shows available funcargs + and their help strings (docstrings on the factory) for a + given test path - display a short and concise traceback if a funcarg lookup fails - early-load "test*/conftest.py" files, i.e. conftest.py files in directories starting with 'test'. allows to conveniently keep and access From commits-noreply at bitbucket.org Fri Feb 5 22:51:24 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 5 Feb 2010 21:51:24 +0000 (UTC) Subject: [py-svn] py-trunk commit cd736fb48fe1: refined usage and options for "py.cleanup": Message-ID: <20100205215124.101EB7EE7A@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265406641 -3600 # Node ID cd736fb48fe11cf57270096d78da29124ebf0e8b # Parent da57b132ee9db9e8d91326e33c681dbe55cb1c4e refined usage and options for "py.cleanup": py.cleanup # remove "*.pyc" and "*$py.class" (jython) files py.cleanup -e .swp -e .cache # also remove files with these extensions py.cleanup -s # remove "build" and "dist" directory next to setup.py files py.cleanup -d # also remove empty directories py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'" py.cleanup -n # dry run, only show what would be removed --- a/py/_cmdline/pycleanup.py +++ b/py/_cmdline/pycleanup.py @@ -1,47 +1,86 @@ #!/usr/bin/env python """\ -py.cleanup [PATH] +py.cleanup [PATH] ... -Delete pyc file recursively, starting from PATH (which defaults to the current -working directory). Don't follow links and don't recurse into directories with -a ".". +Delete typical python development related files recursively under the specified PATH (which defaults to the current working directory). Don't follow links and don't recurse into directories with a dot. Optionally remove setup.py related files and empty +directories. + """ import py +import sys, subprocess def main(): parser = py.std.optparse.OptionParser(usage=__doc__) - parser.add_option("-e", "--remove", dest="ext", default=".pyc", action="store", - help="remove files with the given comma-separated list of extensions" - ) + parser.add_option("-e", metavar="ENDING", + dest="endings", default=[".pyc", "$py.class"], action="append", + help=("(multi) recursively remove files with the given ending." + " '.pyc' and '$py.class' are in the default list.")) + parser.add_option("-d", action="store_true", dest="removedir", + help="remove empty directories.") + parser.add_option("-s", action="store_true", dest="setup", + help="remove 'build' and 'dist' directories next to setup.py files") + parser.add_option("-a", action="store_true", dest="all", + help="synonym for '-S -d -e pip-log.txt'") parser.add_option("-n", "--dryrun", dest="dryrun", default=False, action="store_true", - help="display would-be-removed filenames" - ) - parser.add_option("-d", action="store_true", dest="removedir", - help="remove empty directories") + help="don't actually delete but display would-be-removed filenames.") (options, args) = parser.parse_args() - if not args: - args = ["."] - ext = options.ext.split(",") - def shouldremove(p): - return p.ext in ext + + Cleanup(options, args).main() + +class Cleanup: + def __init__(self, options, args): + if not args: + args = ["."] + self.options = options + self.args = [py.path.local(x) for x in args] + if options.all: + options.setup = True + options.removedir = True + options.endings.append("pip-log.txt") + + def main(self): + if self.options.setup: + for arg in self.args: + self.setupclean(arg) - for arg in args: - path = py.path.local(arg) - py.builtin.print_("cleaning path", path, "of extensions", ext) - for x in path.visit(shouldremove, lambda x: x.check(dotfile=0, link=0)): - remove(x, options) - if options.removedir: - for x in path.visit(lambda x: x.check(dir=1), - lambda x: x.check(dotfile=0, link=0)): - if not x.listdir(): - remove(x, options) + for path in self.args: + py.builtin.print_("cleaning path", path, + "of extensions", self.options.endings) + for x in path.visit(self.shouldremove, self.recursedir): + self.remove(x) + if self.options.removedir: + for x in path.visit(lambda x: x.check(dir=1), self.recursedir): + if not x.listdir(): + self.remove(x) -def remove(path, options): - if options.dryrun: - py.builtin.print_("would remove", path) - else: - py.builtin.print_("removing", path) - path.remove() - + def shouldremove(self, p): + for ending in self.options.endings: + if p.basename.endswith(ending): + return True + + def recursedir(self, path): + return path.check(dotfile=0, link=0) + + def remove(self, path): + if not path.check(): + return + if self.options.dryrun: + py.builtin.print_("would remove", path) + else: + py.builtin.print_("removing", path) + path.remove() + + def XXXcallsetup(self, setup, *args): + old = setup.dirpath().chdir() + try: + subprocess.call([sys.executable, str(setup)] + list(args)) + finally: + old.chdir() + + def setupclean(self, path): + for x in path.visit("setup.py", self.recursedir): + basepath = x.dirpath() + self.remove(basepath / "build") + self.remove(basepath / "dist") --- a/testing/cmdline/test_cmdline.py +++ b/testing/cmdline/test_cmdline.py @@ -45,8 +45,10 @@ class TestPyCleanup: assert p.check() pyc = p.new(ext='pyc') pyc.ensure() + pyclass = p.new(basename=p.basename + '$py.class') result = testdir.runpybin("py.cleanup", tmpdir) assert not pyc.check() + assert not pyclass.check() def test_dir_remove_simple(self, testdir, tmpdir): subdir = tmpdir.mkdir("subdir") @@ -59,3 +61,43 @@ class TestPyCleanup: result = testdir.runpybin("py.cleanup", tmpdir, '-d') assert result.ret == 0 assert not subdir.check() + + @py.test.mark.multi(opt=["-s"]) + def test_remove_setup_simple(self, testdir, tmpdir, opt): + subdir = tmpdir.mkdir("subdir") + p = subdir.ensure("setup.py") + subdir.mkdir("build").ensure("hello", "world.py") + egg1 = subdir.mkdir("something.egg-info") + egg1.mkdir("whatever") + okbuild = subdir.mkdir("preserved1").mkdir("build") + egg2 = subdir.mkdir("preserved2").mkdir("other.egg-info") + subdir.mkdir("dist") + result = testdir.runpybin("py.cleanup", opt, subdir) + assert result.ret == 0 + assert okbuild.check() + assert egg1.check() + assert egg2.check() + assert subdir.join("preserved1").check() + assert subdir.join("preserved2").check() + assert not subdir.join("build").check() + assert not subdir.join("dist").check() + + def test_remove_all(self, testdir, tmpdir): + tmpdir.ensure("setup.py") + tmpdir.ensure("build", "xyz.py") + tmpdir.ensure("dist", "abc.py") + piplog = tmpdir.ensure("preserved2", "pip-log.txt") + tmpdir.ensure("hello.egg-info") + setup = tmpdir.ensure("setup.py") + tmpdir.ensure("src/a/b") + x = tmpdir.ensure("src/x.py") + x2 = tmpdir.ensure("src/x.pyc") + x3 = tmpdir.ensure("src/x$py.class") + result = testdir.runpybin("py.cleanup", "-a", tmpdir) + assert result.ret == 0 + assert len(tmpdir.listdir()) == 3 + assert setup.check() + assert x.check() + assert not x2.check() + assert not x3.check() + assert not piplog.check() --- a/CHANGELOG +++ b/CHANGELOG @@ -1,22 +1,37 @@ Changes between 1.2.1 and 1.2.0 ===================================== -- add a new option "--funcargs" that shows available funcargs - and their help strings (docstrings on the factory) for a - given test path +- refined usage and options for "py.cleanup": + py.cleanup # remove "*.pyc" and "*$py.class" (jython) files + py.cleanup -e .swp -e .cache # also remove files with these extensions + py.cleanup -s # remove "build" and "dist" directory next to setup.py files + py.cleanup -d # also remove empty directories + py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'" + py.cleanup -n # dry run, only show what would be removed + +- add a new option "py.test --funcargs" which shows available funcargs + and their help strings (docstrings on their respective factory function) + for a given test path + - display a short and concise traceback if a funcarg lookup fails + - early-load "test*/conftest.py" files, i.e. conftest.py files in directories starting with 'test'. allows to conveniently keep and access test-related options without having to put a conftest.py into the package root dir. + - fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value + - fix issue78: always call python-level teardown functions even if the according setup failed. This includes refinements for calling setup_module/class functions which will now only be called once instead of the previous behaviour where they'd be called multiple times if they raise an exception (including a Skipped exception). Any exception will be re-corded and associated with all tests in the according module/class scope. + - fix issue63: assume <40 columns to be a bogus terminal width, default to 80 + - update apipkg.py to fix an issue where recursive imports might unnecessarily break importing + - fix plugin links Changes between 1.2 and 1.1.1 From commits-noreply at bitbucket.org Fri Feb 5 22:57:57 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 5 Feb 2010 21:57:57 +0000 (UTC) Subject: [py-svn] py-trunk commit 429b304d7dd1: fix this test Message-ID: <20100205215757.D66A77EE81@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265407066 -3600 # Node ID 429b304d7dd119afc29b85146d772e85394b4cae # Parent cd736fb48fe11cf57270096d78da29124ebf0e8b fix this test --- a/testing/plugin/test_pytest_terminal.py +++ b/testing/plugin/test_pytest_terminal.py @@ -591,9 +591,10 @@ def test_trace_reporting(testdir): @py.test.mark.nodist def test_show_funcarg(testdir, option): - result = testdir.runpytest(*option._getcmdargs()) + args = option._getcmdargs() + ["--funcargs"] + result = testdir.runpytest(*args) assert result.stdout.fnmatch_lines([ "*tmpdir*", "*temporary directory*", ] - ]) + ) From commits-noreply at bitbucket.org Sat Feb 6 22:37:23 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 6 Feb 2010 21:37:23 +0000 (UTC) Subject: [py-svn] py-trunk commit faffbe7dd81e: actually look into all non-dot subdirs for conftest.py files - recursive walk would be too heavy for large source trees but first-level subdirs are fine IMO. Note that prior to py.test 1.0 doing this "look-ahead" was not easily doable because it was hard to avoid global state in conftest.py, this is not true anymore - so i feel ok telling people to cleanup their conftest files if they get problems (you can imagine people doing all kinds of things at global conftest.py module scope, can't you?) Message-ID: <20100206213723.A1E8C7EEFE@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265492224 -3600 # Node ID faffbe7dd81e90257291be836bfb222d6f8a15ad # Parent 429b304d7dd119afc29b85146d772e85394b4cae actually look into all non-dot subdirs for conftest.py files - recursive walk would be too heavy for large source trees but first-level subdirs are fine IMO. Note that prior to py.test 1.0 doing this "look-ahead" was not easily doable because it was hard to avoid global state in conftest.py, this is not true anymore - so i feel ok telling people to cleanup their conftest files if they get problems (you can imagine people doing all kinds of things at global conftest.py module scope, can't you?) --- a/testing/test_genitems.py +++ b/testing/test_genitems.py @@ -24,15 +24,6 @@ class Test_genitems: p = testdir.makepyfile(conftest="raise SyntaxError\n") py.test.raises(SyntaxError, testdir.inline_genitems, p.dirpath()) - def test_subdir_conftest_error(self, testdir): - tmp = testdir.tmpdir - tmp.ensure("sub", "conftest.py").write("raise SyntaxError('x')\n") - items, reprec = testdir.inline_genitems(tmp) - collectionfailures = reprec.getfailedcollections() - assert len(collectionfailures) == 1 - ev = collectionfailures[0] - assert "SyntaxError: x" in ev.longrepr.reprcrash.message - def test_example_items1(self, testdir): p = testdir.makepyfile(''' def testone(): --- a/py/_test/conftesthandle.py +++ b/py/_test/conftesthandle.py @@ -41,7 +41,7 @@ class Conftest(object): self._path2confmods[None] = self.getconftestmodules(anchor) # let's also consider test* dirs if anchor.check(dir=1): - for x in anchor.listdir("test*"): + for x in anchor.listdir(lambda x: x.check(dir=1, dotfile=0)): self.getconftestmodules(x) break else: --- a/testing/test_conftesthandle.py +++ b/testing/test_conftesthandle.py @@ -32,7 +32,7 @@ class TestConftestValueAccessGlobal: l = [] conftest = Conftest(onimport=l.append) conftest.setinitial([basedir.join("adir")]) - assert len(l) == 1 + assert len(l) == 2 assert conftest.rget("a") == 1 assert conftest.rget("b", basedir.join("adir", "b")) == 2 assert len(l) == 2 @@ -133,18 +133,15 @@ def test_setinitial_confcut(testdir): assert conftest.getconftestmodules(sub) == [] assert conftest.getconftestmodules(conf.dirpath()) == [] -def test_setinitial_not_considers_conftest_in_non_test_dirs(testdir): - sub = testdir.mkdir("sub") - sub.ensure("conftest.py") - conftest = Conftest() - conftest.setinitial([sub.dirpath()]) - assert not conftest._conftestpath2mod - - at py.test.mark.multi(name='test tests testing'.split()) -def test_setinitial_considers_conftest_in_test_dirs(testdir, name): + at py.test.mark.multi(name='test tests whatever .dotdir'.split()) +def test_setinitial_conftest_subdirs(testdir, name): sub = testdir.mkdir(name) subconftest = sub.ensure("conftest.py") conftest = Conftest() conftest.setinitial([sub.dirpath()]) - assert subconftest in conftest._conftestpath2mod - assert len(conftest._conftestpath2mod) == 1 + if name != ".dotdir": + assert subconftest in conftest._conftestpath2mod + assert len(conftest._conftestpath2mod) == 1 + else: + assert subconftest not in conftest._conftestpath2mod + assert len(conftest._conftestpath2mod) == 0 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,9 +15,9 @@ Changes between 1.2.1 and 1.2.0 - display a short and concise traceback if a funcarg lookup fails -- early-load "test*/conftest.py" files, i.e. conftest.py files in - directories starting with 'test'. allows to conveniently keep and access - test-related options without having to put a conftest.py into the package root dir. +- early-load "conftest.py" files in non-dot first-level sub directories. + allows to conveniently keep and access test-related options without + having to put a conftest.py into the package root dir. - fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value From commits-noreply at bitbucket.org Sun Feb 7 01:56:56 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 7 Feb 2010 00:56:56 +0000 (UTC) Subject: [py-svn] py-trunk commit 8ad566a440d0: fix docstring Message-ID: <20100207005656.2B8B67EF0B@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265504203 -3600 # Node ID 8ad566a440d003e40eca621c5adb796ad5973c03 # Parent faffbe7dd81e90257291be836bfb222d6f8a15ad fix docstring --- a/py/_plugin/pytest_monkeypatch.py +++ b/py/_plugin/pytest_monkeypatch.py @@ -68,10 +68,9 @@ def pytest_funcarg__monkeypatch(request) monkeypatch.syspath_prepend(path) All modifications will be undone when the requesting - test function finished its execution. For the ``del`` - methods the ``raising`` parameter determines if a - KeyError or AttributeError will be raised if the - deletion has no target. + test function finished its execution. The ``raising`` + parameter determines if a KeyError or AttributeError + will be raised if the set/deletion operation has no target. """ monkeypatch = MonkeyPatch() request.addfinalizer(monkeypatch.undo) From commits-noreply at bitbucket.org Sun Feb 7 02:09:23 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 7 Feb 2010 01:09:23 +0000 (UTC) Subject: [py-svn] py-trunk commit 480938f9813a: nice-ify --funcarg reporting, show paths instead of useless python reprs Message-ID: <20100207010923.78B207EF1B@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265504954 -3600 # Node ID 480938f9813a5ac7c1d96c779a02595d2ee14635 # Parent 8ad566a440d003e40eca621c5adb796ad5973c03 nice-ify --funcarg reporting, show paths instead of useless python reprs --- a/py/_plugin/pytest_terminal.py +++ b/py/_plugin/pytest_terminal.py @@ -457,6 +457,7 @@ def flatten(l): from py._test.session import Session class ShowFuncargSession(Session): def main(self, colitems): + self.fspath = py.path.local() self.sessionstarts() try: self.showargs(colitems[0]) @@ -479,8 +480,9 @@ class ShowFuncargSession(Session): if available: pluginname = plugin.__name__ for name, factory in available: + loc = self.getlocation(factory) if verbose: - funcargspec = "%s -- from %s" %(name, plugin,) + funcargspec = "%s -- %s" %(name, loc,) else: funcargspec = name tw.line(funcargspec, green=True) @@ -489,6 +491,13 @@ class ShowFuncargSession(Session): for line in doc.split("\n"): tw.line(" " + line.strip()) else: - tw.line(" no docstring available", red=True) - tw.line(factory, red=True) - tw.line(plugin, red=True) + tw.line(" %s: no docstring available" %(loc,), + red=True) + + def getlocation(self, function): + import inspect + fn = py.path.local(inspect.getfile(function)) + lineno = function.func_code.co_firstlineno + if fn.relto(self.fspath): + fn = fn.relto(self.fspath) + return "%s:%d" %(fn, lineno+1) From commits-noreply at bitbucket.org Sun Feb 7 02:15:58 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 7 Feb 2010 01:15:58 +0000 (UTC) Subject: [py-svn] py-trunk commit f05c260e91fa: if a funcarg is misspelled/missing, hint at using "--funcargs" Message-ID: <20100207011558.361417EF0B@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265505347 -3600 # Node ID f05c260e91fa7bd2b9bb1724a0ca8ce733ae1812 # Parent 480938f9813a5ac7c1d96c779a02595d2ee14635 if a funcarg is misspelled/missing, hint at using "--funcargs" --- a/py/_test/funcargs.py +++ b/py/_test/funcargs.py @@ -172,4 +172,5 @@ class FuncargRequest: fspath, lineno, msg = self._pyfuncitem.reportinfo() msg = "LookupError: no factory found for function argument %r" % (argname,) msg += "\n available funcargs: %s" %(", ".join(available),) + msg += "\n use 'py.test --funcargs [testpath]' for help on them." raise self.LookupError(msg) From commits-noreply at bitbucket.org Sun Feb 7 02:56:00 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 7 Feb 2010 01:56:00 +0000 (UTC) Subject: [py-svn] py-trunk commit 1e3b35459d06: add some issues Message-ID: <20100207015600.095057EF1F@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265507750 -3600 # Node ID 1e3b35459d064d6f4793364d237769b7f7d1b8e1 # Parent f05c260e91fa7bd2b9bb1724a0ca8ce733ae1812 add some issues --- a/ISSUES.txt +++ b/ISSUES.txt @@ -8,6 +8,44 @@ maybe also introduce a py.test.mark.test mark a function to become a tested one. Lookup JUnit ways of tagging tests. +introduce py.test.mark registration +----------------------------------------- +tags: feature 1.3 + +introduce a hook that allows to register a named mark decorator +with documentation and add "py.test --marks" to get +a list of available marks. Deprecate "dynamic" mark +definitions. + +consider introducing py.test.mark.skip_[not]win32/jython/pyXY +------------------------------------------------------------- +tags: feature 1.3 + +conveniently introduce markers for platforms to +have a shorter form for skipping. + +generalize parametrized testing to generate combinations +------------------------------------------------------------- +tags: feature 1.3 + +think about extending metafunc.addcall or add a new method to allow to +generate tests with combinations of all generated versions - what to do +about "id" and "param" in such combinations though? + +introduce py.test.mark.multi +----------------------------------------- +tags: feature 1.3 + +introduce py.test.mark.multi to specify a number +of values for a given function argument. + +introduce py.test.mark.multi +----------------------------------------- +tags: feature 1.3 + +introduce py.test.mark.multi to specify a number +of values for a given function argument. + have imported module mismatch honour relative paths -------------------------------------------------------- tags: bug 1.2 @@ -108,3 +146,5 @@ show available funcargs - it should hono path::TestClass syntax so one can easily inspect where funcargs come from or which are available. + + From commits-noreply at bitbucket.org Mon Feb 8 14:17:17 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 8 Feb 2010 13:17:17 +0000 (UTC) Subject: [py-svn] py-trunk commit cd5f4f2caa97: fix a pdb problem when dropping to a "raises" related failure Message-ID: <20100208131717.4DA9F7EF18@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265635021 -3600 # Node ID cd5f4f2caa97afe7e3b75d06c1d9e10dea27666f # Parent 1e3b35459d064d6f4793364d237769b7f7d1b8e1 fix a pdb problem when dropping to a "raises" related failure --- a/py/_plugin/pytest_pdb.py +++ b/py/_plugin/pytest_pdb.py @@ -91,10 +91,11 @@ class Pdb(py.std.pdb.Pdb): stack, i = pdb.Pdb.get_stack(self, f, t) if f is None: i = max(0, len(stack) - 1) + while i and stack[i][0].f_locals.get("__tracebackhide__", False): + i-=1 return stack, i def post_mortem(t): - # modified from pdb.py for the new get_stack() implementation p = Pdb() p.reset() p.interaction(None, t) --- a/testing/plugin/test_pytest_pdb.py +++ b/testing/plugin/test_pytest_pdb.py @@ -43,3 +43,22 @@ class TestPDB: child.expect("1 failed") if child.isalive(): child.wait() + + def test_pdb_interaction_exception(self, testdir): + p1 = testdir.makepyfile(""" + import py + def globalfunc(): + pass + def test_1(): + py.test.raises(ValueError, globalfunc) + """) + child = testdir.spawn_pytest("--pdb %s" % p1) + child.expect(".*def test_1") + child.expect(".*py.test.raises.*globalfunc") + child.expect("(Pdb)") + child.sendline("globalfunc") + child.expect(".*function") + child.sendeof() + child.expect("1 failed") + if child.isalive(): + child.wait() --- a/CHANGELOG +++ b/CHANGELOG @@ -29,6 +29,8 @@ Changes between 1.2.1 and 1.2.0 - fix issue63: assume <40 columns to be a bogus terminal width, default to 80 +- fix pdb debugging to be in the correct frame on raises-related errors + - update apipkg.py to fix an issue where recursive imports might unnecessarily break importing From commits-noreply at bitbucket.org Mon Feb 8 16:39:47 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 8 Feb 2010 15:39:47 +0000 (UTC) Subject: [py-svn] py-trunk commit c143a8c8840a: going for the 1.2.1 release Message-ID: <20100208153947.632327EE6D@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265643569 -3600 # Node ID c143a8c8840a1c68570890c8ac6165bbf92fd3c6 # Parent cd5f4f2caa97afe7e3b75d06c1d9e10dea27666f going for the 1.2.1 release --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ dictionary or an import path. (c) Holger Krekel and others, 2004-2010 """ -version = "1.2.0post1" +version = "1.2.1" __version__ = version = version or "1.2.x" import py.apipkg --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ def main(): name='py', description='py.test and pylib: rapid testing and development utils.', long_description = long_description, - version= trunk or '1.2.0post1', + version= trunk or '1.2.1', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], --- /dev/null +++ b/doc/announce/release-1.2.1.txt @@ -0,0 +1,66 @@ +py.test/pylib 1.2.1: little fixes and improvements +-------------------------------------------------------------------------------- + +py.test is an advanced automated testing tool working with +Python2, Python3 and Jython versions on all major operating +systems. It has a simple plugin architecture and can run many +existing common Python test suites without modification. It offers +some unique features not found in other testing tools. +See http://pytest.org for more info. + +py.test 1.2.1 brings bug fixes and some new options and abilities triggered +by user feedback: + +* --funcargs [testpath] will show available builtin- and project funcargs. +* display a short and concise traceback if funcarg lookup fails. +* early-load "conftest.py" files in non-dot first-level sub directories. +* --tb=line will print a single line for each failing test (issue67) +* py.cleanup has a number of new options, cleanups up setup.py related files +* fix issue78: always call python-level teardown functions even if the + according setup failed. + +For more detailed information see the changelog below. + +cheers and have fun, + +holger + + +Changes between 1.2.1 and 1.2.0 +===================================== + +- refined usage and options for "py.cleanup":: + + py.cleanup # remove "*.pyc" and "*$py.class" (jython) files + py.cleanup -e .swp -e .cache # also remove files with these extensions + py.cleanup -s # remove "build" and "dist" directory next to setup.py files + py.cleanup -d # also remove empty directories + py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'" + py.cleanup -n # dry run, only show what would be removed + +- add a new option "py.test --funcargs" which shows available funcargs + and their help strings (docstrings on their respective factory function) + for a given test path + +- display a short and concise traceback if a funcarg lookup fails + +- early-load "conftest.py" files in non-dot first-level sub directories. + allows to conveniently keep and access test-related options in a ``test`` + subdir and still add command line options. + +- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value + +- fix issue78: always call python-level teardown functions even if the + according setup failed. This includes refinements for calling setup_module/class functions + which will now only be called once instead of the previous behaviour where they'd be called + multiple times if they raise an exception (including a Skipped exception). Any exception + will be re-corded and associated with all tests in the according module/class scope. + +- fix issue63: assume <40 columns to be a bogus terminal width, default to 80 + +- fix pdb debugging to be in the correct frame on raises-related errors + +- update apipkg.py to fix an issue where recursive imports might + unnecessarily break importing + +- fix plugin links --- a/MANIFEST.in +++ b/MANIFEST.in @@ -10,7 +10,7 @@ graft bin graft testing #exclude *.orig #exclude *.rej -exclude .hginore +#exclude .hginore #exclude *.pyc #recursive-exclude testing *.pyc *.orig *.rej *$py.class #prune .pyc --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,8 @@ Changes between 1.2.1 and 1.2.0 ===================================== -- refined usage and options for "py.cleanup": +- refined usage and options for "py.cleanup":: + py.cleanup # remove "*.pyc" and "*$py.class" (jython) files py.cleanup -e .swp -e .cache # also remove files with these extensions py.cleanup -s # remove "build" and "dist" directory next to setup.py files @@ -16,8 +17,8 @@ Changes between 1.2.1 and 1.2.0 - display a short and concise traceback if a funcarg lookup fails - early-load "conftest.py" files in non-dot first-level sub directories. - allows to conveniently keep and access test-related options without - having to put a conftest.py into the package root dir. + allows to conveniently keep and access test-related options in a ``test`` + subdir and still add command line options. - fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value From commits-noreply at bitbucket.org Mon Feb 8 17:40:15 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 8 Feb 2010 16:40:15 +0000 (UTC) Subject: [py-svn] py-trunk commit 4f122a2db31e: Added tag 1.2.1 for changeset c143a8c8840a Message-ID: <20100208164015.7A64D7EEE0@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265647195 -3600 # Node ID 4f122a2db31e91daf998da3f08a4f17131554062 # Parent c143a8c8840a1c68570890c8ac6165bbf92fd3c6 Added tag 1.2.1 for changeset c143a8c8840a --- a/.hgtags +++ b/.hgtags @@ -21,3 +21,4 @@ 4816e8b80602a3fd3a0a120333ad85fbe7d8bab4 60c44bdbf093285dc69d5462d4dbb4acad325ca6 1.1.0 319187fcda66714c5eb1353492babeec3d3c826f 1.1.1 4fc5212f7626a56b9eb6437b5c673f56dd7eb942 1.2.0 +c143a8c8840a1c68570890c8ac6165bbf92fd3c6 1.2.1 From commits-noreply at bitbucket.org Tue Feb 9 18:32:33 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 9 Feb 2010 17:32:33 +0000 (UTC) Subject: [py-svn] py-trunk commit 91252ac8af39: note down two issues after having helped prologic - also related to Message-ID: <20100209173233.7178A7EECF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265736737 -3600 # Node ID 91252ac8af3913cacd27778c0809750901b710d7 # Parent 4f122a2db31e91daf998da3f08a4f17131554062 note down two issues after having helped prologic - also related to earlier discussions with ronny and others. --- a/ISSUES.txt +++ b/ISSUES.txt @@ -17,6 +17,26 @@ with documentation and add "py.test --ma a list of available marks. Deprecate "dynamic" mark definitions. +do early-teardown of test modules +----------------------------------------- +tags: feature 1.3 + +currently teardowns are called when the next tests is setup +except for the function/method level where interally +"teardown_exact" tears down immediately. Generalize +this to perform the "neccessary" teardown compared to +the "next" test item during teardown - this should +get rid of some irritations because otherwise e.g. +prints of teardown-code appear in the setup of the next test. + +do recursive walk of conftest.py files? +----------------------------------------- +tags: feature 1.3 + +it maybe makes sense to generally do a recursive search of conftest.py +files before command line parsing - this would help to offer the +full list of options as applicable to a given test project. + consider introducing py.test.mark.skip_[not]win32/jython/pyXY ------------------------------------------------------------- tags: feature 1.3 --- a/doc/test/talks.txt +++ b/doc/test/talks.txt @@ -7,6 +7,13 @@ Talks and Tutorials tutorial examples and blog postings --------------------------------------------- +.. _`tutorial1 repository`: http://bitbucket.org/hpk42/pytest-tutorial1/ +.. _`pycon 2010 tutorial PDF`: http://bitbucket.org/hpk42/pytest-tutorial1/raw/tip/pytest-basic.pdf + +basic usage and funcargs: + +- `pycon 2010 tutorial PDF`_ and `tutorial1 repository`_ + function arguments: - `application setup in test functions with funcargs`_ From commits-noreply at bitbucket.org Wed Feb 10 14:22:06 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 13:22:06 +0000 (UTC) Subject: [py-svn] py-trunk commit f3fd6547bba8: fix docs to not point to a downloadable plugin if the Message-ID: <20100210132206.3170A7EF31@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265808109 -3600 # Node ID f3fd6547bba85918012177dce908360e1e4feb0b # Parent 91252ac8af3913cacd27778c0809750901b710d7 fix docs to not point to a downloadable plugin if the plugin is external (thanks to prologic for feedbacking on this confusion) --- a/doc/test/index.txt +++ b/doc/test/index.txt @@ -17,6 +17,13 @@ customize_: configuration, customization changelog_: history of changes covering last releases +**Continous Integration of py.test's own tests and plugins with Hudson**: + + `http://hudson.testrun.org/view/pytest`_ + +.. _`http://hudson.testrun.org/view/pytest`: http://hudson.testrun.org/view/pytest/ + + .. _changelog: ../changelog.html .. _`plugins`: plugin/index.html .. _`talks, tutorials, examples`: talks.html --- a/doc/test/plugin/figleaf.txt +++ b/doc/test/plugin/figleaf.txt @@ -6,16 +6,29 @@ report test coverage using the 'figleaf' .. contents:: :local: +Install +--------------- + +To install the plugin issue:: + + easy_install pytest-figleaf # or + pip install pytest-figleaf + +and if you are using pip you can also uninstall:: + + pip uninstall pytest-figleaf + + Usage --------------- -after pip or easy_install mediated installation of ``pytest-figleaf`` you can type:: +After installation you can simply type:: py.test --figleaf [...] to enable figleaf coverage in your test run. A default ".figleaf" data file -and "html" directory will be created. You can use ``--fig-data`` -and ``fig-html`` to modify the paths. +and "html" directory will be created. You can use command line options +to control where data and html files are created. command line options -------------------- @@ -28,14 +41,4 @@ command line options ``--fig-html=dir`` set html reporting dir, default "html". -Start improving this plugin in 30 seconds -========================================= - - -1. Download `pytest_figleaf.py`_ plugin source code -2. put it somewhere as ``pytest_figleaf.py`` into your import path -3. a subsequent ``py.test`` run will use your local version - -Checkout customize_, other plugins_ or `get in contact`_. - .. include:: links.txt --- a/doc/test/funcargs.txt +++ b/doc/test/funcargs.txt @@ -1,5 +1,5 @@ ============================================================== -**funcargs**: advanced test parametrization +**funcargs**: advanced test fixtures and parametrization ============================================================== .. contents:: @@ -77,9 +77,15 @@ 3. ``test_function(42)`` call is execute Note that if you misspell a function argument or want to use one that isn't available, you'll see an error -with a list of available function arguments. +with a list of available function arguments. You can +also issue:: -factory functions receive a `request object`_ + py.test --funcargs test_simplefactory.py + +to see available function arguments (which you can also +think of as "resources"). + +Factory functions receive a `request object`_ which they can use to register setup/teardown functions or access meta data about a test. --- a/doc/test/plugin/links.txt +++ b/doc/test/plugin/links.txt @@ -1,47 +1,45 @@ .. _`helpconfig`: helpconfig.html -.. _`terminal`: terminal.html -.. _`pytest_recwarn.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_recwarn.py +.. _`pytest_recwarn.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_recwarn.py .. _`unittest`: unittest.html -.. _`pytest_monkeypatch.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_monkeypatch.py -.. _`pytest_genscript.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_genscript.py +.. _`pytest_monkeypatch.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_monkeypatch.py +.. _`pytest_genscript.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_genscript.py .. _`pastebin`: pastebin.html .. _`skipping`: skipping.html .. _`genscript`: genscript.html .. _`plugins`: index.html .. _`mark`: mark.html .. _`tmpdir`: tmpdir.html -.. _`pytest_doctest.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_doctest.py +.. _`pytest_doctest.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_doctest.py .. _`capture`: capture.html -.. _`pytest_nose.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_nose.py -.. _`pytest_restdoc.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_restdoc.py +.. _`pytest_nose.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_nose.py +.. _`pytest_restdoc.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_restdoc.py .. _`restdoc`: restdoc.html .. _`xdist`: xdist.html -.. _`pytest_pastebin.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_pastebin.py -.. _`pytest_tmpdir.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_tmpdir.py -.. _`pytest_figleaf.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_figleaf.py -.. _`pytest_hooklog.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_hooklog.py +.. _`pytest_pastebin.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_pastebin.py +.. _`pytest_tmpdir.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_tmpdir.py +.. _`terminal`: terminal.html +.. _`pytest_hooklog.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_hooklog.py .. _`junitxml`: junitxml.html -.. _`plugin.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/plugin.py -.. _`pytest_skipping.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_skipping.py +.. _`pytest_skipping.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_skipping.py .. _`checkout the py.test development version`: ../../install.html#checkout -.. _`pytest_helpconfig.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_helpconfig.py +.. _`pytest_helpconfig.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_helpconfig.py .. _`oejskit`: oejskit.html .. _`doctest`: doctest.html -.. _`pytest_mark.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_mark.py +.. _`pytest_mark.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_mark.py .. _`get in contact`: ../../contact.html -.. _`pytest_capture.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_capture.py +.. _`pytest_capture.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_capture.py .. _`figleaf`: figleaf.html .. _`customize`: ../customize.html .. _`hooklog`: hooklog.html -.. _`pytest_terminal.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_terminal.py +.. _`pytest_terminal.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_terminal.py .. _`recwarn`: recwarn.html -.. _`pytest_pdb.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_pdb.py +.. _`pytest_pdb.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_pdb.py .. _`monkeypatch`: monkeypatch.html .. _`coverage`: coverage.html .. _`resultlog`: resultlog.html -.. _`pytest_junitxml.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_junitxml.py +.. _`pytest_junitxml.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_junitxml.py .. _`django`: django.html -.. _`pytest_unittest.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_unittest.py +.. _`pytest_unittest.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_unittest.py .. _`nose`: nose.html -.. _`pytest_resultlog.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.0/py/_plugin/pytest_resultlog.py +.. _`pytest_resultlog.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_resultlog.py .. _`pdb`: pdb.html --- a/doc/test/plugin/terminal.txt +++ b/doc/test/plugin/terminal.txt @@ -19,9 +19,11 @@ command line options ``--report=opts`` show more info, valid: skipped,xfailed ``--tb=style`` - traceback verboseness (long/short/no). + traceback print mode (long/short/line/no). ``--fulltrace`` don't cut any tracebacks (default is to cut). +``--funcargs`` + show available function arguments, sorted by plugin Start improving this plugin in 30 seconds ========================================= --- a/doc/test/plugin/xdist.txt +++ b/doc/test/plugin/xdist.txt @@ -28,6 +28,18 @@ You may specify different Python version .. _`pytest-xdist`: http://pypi.python.org/pypi/pytest-xdist +Install / Uninstall +--------------------- + +To install the xdist plugin simply type:: + + easy_install pytest-xdist # or + pip install pytest-xdist + +and to uninstall:: + + pip uninstall pytest-xdist + Usage examples --------------------- @@ -169,14 +181,4 @@ command line options ``--rsyncdir=dir1`` add directory for rsyncing to remote tx nodes. -Start improving this plugin in 30 seconds -========================================= - - -1. Download `plugin.py`_ plugin source code -2. put it somewhere as ``plugin.py`` into your import path -3. a subsequent ``py.test`` run will use your local version - -Checkout customize_, other plugins_ or `get in contact`_. - .. include:: links.txt --- a/doc/test/plugin/monkeypatch.txt +++ b/doc/test/plugin/monkeypatch.txt @@ -75,10 +75,9 @@ helper methods to modify objects, dictio monkeypatch.syspath_prepend(path) All modifications will be undone when the requesting -test function finished its execution. For the ``del`` -methods the ``raising`` parameter determines if a -KeyError or AttributeError will be raised if the -deletion has no target. +test function finished its execution. The ``raising`` +parameter determines if a KeyError or AttributeError +will be raised if the set/deletion operation has no target. Start improving this plugin in 30 seconds ========================================= --- a/bin-for-dist/makepluginlist.py +++ b/bin-for-dist/makepluginlist.py @@ -187,7 +187,8 @@ class PluginDoc(RestWriter): self.emit_funcargs(plugin) self.emit_options(plugin) - self.emit_source(plugin, config.hg_changeset) + if name not in externals: + self.emit_source(plugin, config.hg_changeset) #self.sourcelink = (purename, # "http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/" + # purename + ".py") --- a/doc/confrest.py +++ b/doc/confrest.py @@ -66,10 +66,11 @@ pageTracker._trackPageview(); self.a_docref("Index", "test/index.html"), self.a_docref("Quickstart", "test/quickstart.html"), self.a_docref("Features", "test/features.html"), + self.a_docref("Funcargs", "test/funcargs.html"), self.a_docref("Plugins", "test/plugin/index.html"), - self.a_docref("Funcargs", "test/funcargs.html"), self.a_docref("Customize", "test/customize.html"), self.a_docref("Tutorials", "test/talks.html"), + self.a_href("hudson-tests", "http://hudson.testrun.org") ), html.div( html.h3("supporting APIs:"), From commits-noreply at bitbucket.org Wed Feb 10 16:11:35 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 15:11:35 +0000 (UTC) Subject: [py-svn] py-trunk commit 5fe0475ec05f: remove cover and xmlresult plugins as they are not easily installable Message-ID: <20100210151135.765C47EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project py-trunk # URL http://bitbucket.org/hpk42/py-trunk/overview/ # User holger krekel # Date 1265814679 -3600 # Node ID 5fe0475ec05f6b130cf8456b6690f37cac8f6808 # Parent f3fd6547bba85918012177dce908360e1e4feb0b remove cover and xmlresult plugins as they are not easily installable and lead to frustration (thanks again to prologic for getting back on it) --- a/doc/test/plugin/links.txt +++ b/doc/test/plugin/links.txt @@ -35,7 +35,6 @@ .. _`recwarn`: recwarn.html .. _`pytest_pdb.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_pdb.py .. _`monkeypatch`: monkeypatch.html -.. _`coverage`: coverage.html .. _`resultlog`: resultlog.html .. _`pytest_junitxml.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.2.1/py/_plugin/pytest_junitxml.py .. _`django`: django.html --- a/bin-for-dist/makepluginlist.py +++ b/bin-for-dist/makepluginlist.py @@ -4,7 +4,7 @@ WIDTH = 75 plugins = [ ('advanced python testing', - 'skipping mark pdb figleaf coverage ' + 'skipping mark pdb figleaf ' 'monkeypatch capture recwarn tmpdir',), ('distributed testing, CI and deployment', 'xdist pastebin junitxml resultlog genscript',), @@ -23,9 +23,6 @@ externals = { 'xdist': None, 'figleaf': None, 'django': "for testing django applications", - 'coverage': "for testing with Ned's coverage module ", - 'xmlresult': "for generating xml reports " - "and CruiseControl integration", } def warn(*args): --- a/doc/test/plugin/index.txt +++ b/doc/test/plugin/index.txt @@ -10,8 +10,6 @@ pdb_ interactive debugging with the Pyth figleaf_ (external) report test coverage using the 'figleaf' package. -coverage_ (external) for testing with Ned's coverage module - monkeypatch_ safely patch object attributes, dicts and environment variables. capture_ configurable per-test stdout/stderr capturing mechanisms. From commits-noreply at bitbucket.org Wed Feb 10 20:17:46 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 19:17:46 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 095abe9bfebe: removing old figleaf file to unconfuse Message-ID: <20100210191746.A30117EF15@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265829453 -3600 # Node ID 095abe9bfebecef74084405ba398baa9ee8c4be2 # Parent 845817424bc2c61af51eee7332bb8a568c46cc63 removing old figleaf file to unconfuse --- a/pytest_figleaf.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -report test coverage using the 'figleaf' package. - -Install ---------------- - -To install the plugin issue:: - - easy_install pytest-figleaf # or - pip install pytest-figleaf - -and if you are using pip you can also uninstall:: - - pip uninstall pytest-figleaf - - -Usage ---------------- - -After installation you can simply type:: - - py.test --figleaf [...] - -to enable figleaf coverage in your test run. A default ".figleaf" data file -and "html" directory will be created. You can use command line options -to control where data and html files are created. - -""" - -__version__ = "1.0" - -import py - -def pytest_addoption(parser): - group = parser.getgroup('figleaf based coverage reporting') - group.addoption('--figleaf', action='store_true', default=False, - dest = 'figleaf', - help=('trace python coverage with figleaf and write HTML ' - 'for files below the current working dir')) - group.addoption('--fig-data', action='store', default='.figleaf', - dest='figleafdata', metavar="dir", - help='set tracing file, default: ".figleaf".') - group.addoption('--fig-html', action='store', default='html', - dest='figleafhtml', metavar="dir", - help='set html reporting dir, default "html".') - -def pytest_configure(config): - if config.getvalue("figleaf"): - import figleaf - figleaf.start() - -def pytest_terminal_summary(terminalreporter): - config = terminalreporter.config - if not config.getvalue("figleaf"): - return - import figleaf.annotate_html - datafile = py.path.local(config.getvalue('figleafdata')) - tw = terminalreporter._tw - tw.sep('-', 'figleaf') - tw.line('Writing figleaf data to %s' % (datafile)) - figleaf.stop() - figleaf.write_coverage(str(datafile)) - coverage = get_coverage(datafile, config) - reportdir = py.path.local(config.getvalue('figleafhtml')) - tw.line('Writing figleaf html to file://%s' % (reportdir)) - figleaf.annotate_html.prepare_reportdir(str(reportdir)) - exclude = [] - figleaf.annotate_html.report_as_html(coverage, - str(reportdir), exclude, {}) - -def get_coverage(datafile, config): - import figleaf.annotate_html - # basepath = config.topdir - basepath = py.path.local() - data = figleaf.read_coverage(str(datafile)) - d = {} - coverage = figleaf.combine_coverage(d, data) - for path in coverage.keys(): - if not py.path.local(path).relto(basepath): - del coverage[path] - return coverage From commits-noreply at bitbucket.org Wed Feb 10 20:23:03 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 19:23:03 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 25b1ae20a408: s/figleaf/coverage Message-ID: <20100210192303.21B377EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265829773 -36000 # Node ID 25b1ae20a4084d7f07a0a2e6ad7e43cc58800512 # Parent 095abe9bfebecef74084405ba398baa9ee8c4be2 s/figleaf/coverage --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -This is a little py.test plugin for using the figleaf package +This is a little py.test plugin for using the coverage package to obtain python coverage information. In order to install this plugin and have py.test automatically From commits-noreply at bitbucket.org Wed Feb 10 20:24:29 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 19:24:29 +0000 (UTC) Subject: [py-svn] pytest-coverage commit fe412de426af: .hgignore: Ignore build dir Message-ID: <20100210192429.0C7B77EF35@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265829847 -36000 # Node ID fe412de426af40029504c667b39682f4fe2169ed # Parent 238ab0adee9cfd6a10d6166e5fe5f3bfa9913f04 .hgignore: Ignore build dir --- a/.hgignore +++ b/.hgignore @@ -2,4 +2,5 @@ syntax: glob *.pyc *.patch +build pytest_coverage.egg-info From commits-noreply at bitbucket.org Wed Feb 10 20:24:27 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 19:24:27 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 238ab0adee9c: s/figleaf/coverage Message-ID: <20100210192427.1B18E7EF33@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265829796 -36000 # Node ID 238ab0adee9cfd6a10d6166e5fe5f3bfa9913f04 # Parent 25b1ae20a4084d7f07a0a2e6ad7e43cc58800512 s/figleaf/coverage --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ include setup.py include LICENSE include README.txt -include pytest_figleaf.py -include test_pytest_figleaf.py +include pytest_coverage.py +include test_pytest_coverage.py From commits-noreply at bitbucket.org Wed Feb 10 20:31:21 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 19:31:21 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 0c3f822762f5: pytest_coverage.py: Fix typo with class variable 'coverPackage' Message-ID: <20100210193121.CC2C57EE7C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265830222 -36000 # Node ID 0c3f822762f567e2f03716fa30bde77ea089e788 # Parent fe412de426af40029504c667b39682f4fe2169ed pytest_coverage.py: Fix typo with class variable 'coverPackage' --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -18,7 +18,7 @@ class CoverageTestWrapper(object): """ coverTests = False - coverPackages = None + coverPackage = None def __init__(self, options, _covpkg=None): self.options = options From commits-noreply at bitbucket.org Wed Feb 10 20:31:24 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 19:31:24 +0000 (UTC) Subject: [py-svn] pytest-coverage commit fe73865f3406: pytest_coverage.py: Only build a list of modules to restrict in the output report if self.coverPackage is not None (otherwise display all modules). Message-ID: <20100210193124.BD9887EECF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265830270 -36000 # Node ID fe73865f34061f59c9e686c00e36dd482daa398e # Parent 0c3f822762f567e2f03716fa30bde77ea089e788 pytest_coverage.py: Only build a list of modules to restrict in the output report if self.coverPackage is not None (otherwise display all modules). --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -54,9 +54,12 @@ class CoverageTestWrapper(object): self.coverage.stop() self.coverage.save() - modules = [module - for name, module in sys.modules.items() - if module is not None and name.startswith(self.coverPackage)] + modules = [] + if self.coverPackage is not None: + modules = [module + for name, module in sys.modules.items() + if module is not None and \ + name.startswith(self.coverPackage)] # Remaining actions are reporting, with some common self.options. report_args = { From commits-noreply at bitbucket.org Wed Feb 10 20:38:39 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 19:38:39 +0000 (UTC) Subject: [py-svn] pytest-coverage commit ab88bc5b9a2e: fixing little things, tests pass for now Message-ID: <20100210193839.754507EE7C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265830708 -3600 # Node ID ab88bc5b9a2e2e6a86c88a73898ea7bbbcffe8b0 # Parent fe73865f34061f59c9e686c00e36dd482daa398e fixing little things, tests pass for now --- a/test_pytest_coverage.py +++ b/test_pytest_coverage.py @@ -16,7 +16,7 @@ def test_functional(testdir): assert result.ret == 0 assert result.stdout.fnmatch_lines([]) -def test_no_coverage_import(testdir): +def test_coverage_is_not_imported(testdir): testdir.makepyfile(""" import sys def test_whatever(): --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -4,8 +4,6 @@ import sys import optparse from types import ListType -import coverage - class CoverageTestWrapper(object): """ A Coverage Test Wrapper. @@ -18,24 +16,17 @@ class CoverageTestWrapper(object): """ coverTests = False - coverPackage = None + coverPackages = None - def __init__(self, options, _covpkg=None): + def __init__(self, options): self.options = options - - # _covpkg is for dependency injection, so we can test this code. - if _covpkg: - self.covpkg = _covpkg - else: - import coverage - self.covpkg = coverage - self.coverage = None - self.coverTests = options.cover_tests self.coverPackage = options.cover_package def start(self): + import coverage + self.covpkg = coverage # Set up coverage self.coverage = self.covpkg.coverage( data_suffix = bool(self.options.cover_parallel_mode), @@ -53,13 +44,11 @@ class CoverageTestWrapper(object): # end coverage and save the results self.coverage.stop() self.coverage.save() - + modules = [] - if self.coverPackage is not None: - modules = [module - for name, module in sys.modules.items() - if module is not None and \ - name.startswith(self.coverPackage)] + for name, module in sys.modules.items(): + if module is not None and name.startswith(self.coverPackage): + modules.append(name) # Remaining actions are reporting, with some common self.options. report_args = { @@ -97,7 +86,8 @@ class CoverageTestWrapper(object): options = [ optparse.Option('', '--cover-action', action='append', default=None, - dest='cover_actions', type="choice", choices=['annotate', 'html', 'report', 'xml'], + dest='cover_actions', type="choice", + choices=['annotate', 'html', 'report', 'xml'], help="""\ annotate Annotate source files with execution information. html Create an HTML report. @@ -106,7 +96,7 @@ xml Create an XML report of cove """.strip()), optparse.Option( '--cover-package', action='store', - dest="cover_package", + dest="cover_package", default="", metavar="COVER_PACKAGE", help="Restrict coverage output to selected package" ), @@ -205,7 +195,8 @@ class DoCover: # Monkey patch omit_filter to use regex patterns for file omits def omit_filter(omit_prefixes, code_units): import re - exclude_patterns = [re.compile(line.strip()) for line in omit_prefixes if line and not line.startswith('#')] + exclude_patterns = [re.compile(line.strip()) + for line in omit_prefixes if line and not line.startswith('#')] filtered = [] for cu in code_units: skip = False @@ -218,4 +209,4 @@ def omit_filter(omit_prefixes, code_unit filtered.append(cu) return filtered -coverage.codeunit.omit_filter = omit_filter +#coverage.codeunit.omit_filter = omit_filter From commits-noreply at bitbucket.org Wed Feb 10 21:03:22 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 20:03:22 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 3a8184250a7f: rather import Ross (rozza on github) plugin as a base Message-ID: <20100210200322.9A4507EF33@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265832183 -3600 # Node ID 3a8184250a7f416f46fd1f133feceeb8538d48a4 # Parent ab88bc5b9a2e2e6a86c88a73898ea7bbbcffe8b0 rather import Ross (rozza on github) plugin as a base --- a/test_pytest_coverage.py +++ b/test_pytest_coverage.py @@ -14,7 +14,9 @@ def test_functional(testdir): """) result = testdir.runpytest('--cover-action=report') assert result.ret == 0 - assert result.stdout.fnmatch_lines([]) + assert result.stdout.fnmatch_lines([ + '*Processing Coverage*', + ]) def test_coverage_is_not_imported(testdir): testdir.makepyfile(""" --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -1,212 +1,83 @@ -import os -import re -import sys -import optparse -from types import ListType +""" +Write and report coverage data with the 'coverage' package. +Original code by Ross Lawley. -class CoverageTestWrapper(object): - """ - A Coverage Test Wrapper. - - 1) Setup the with the parsed options - 2) Call start() - 3) Run your tests - 4) Call finish() - 5) Improve your code coverage ;) - """ - - coverTests = False - coverPackages = None +Requires Ned Batchelder's excellent coverage: +http://nedbatchelder.com/code/coverage/ +""" +import py - def __init__(self, options): - self.options = options - self.coverage = None - self.coverTests = options.cover_tests - self.coverPackage = options.cover_package - - def start(self): - import coverage - self.covpkg = coverage - # Set up coverage - self.coverage = self.covpkg.coverage( - data_suffix = bool(self.options.cover_parallel_mode), - cover_pylib = self.options.cover_pylib, - timid = self.options.cover_timid, - branch = self.options.cover_branch, - ) - - self.skipModules = sys.modules.keys()[:] - - # Run the script. - self.coverage.start() - - def finish(self): - # end coverage and save the results - self.coverage.stop() - self.coverage.save() - - modules = [] - for name, module in sys.modules.items(): - if module is not None and name.startswith(self.coverPackage): - modules.append(name) - - # Remaining actions are reporting, with some common self.options. - report_args = { - 'morfs': modules, - 'ignore_errors': self.options.cover_ignore_errors, - } - - # Handle any omits - # Allow pointing to a file as well - try: - omit_file = open(self.options.cover_omit) - omit_prefixes = [line.strip() for line in omit_file.readlines()] - report_args['omit_prefixes'] = omit_prefixes - except: - omit = self.options.cover_omit.split(',') - report_args['omit_prefixes'] = omit - - if 'report' in self.options.cover_actions: - self.coverage.report( - show_missing=self.options.cover_show_missing, **report_args) - if 'annotate' in self.options.cover_actions: - self.coverage.annotate( - directory=self.options.cover_directory, **report_args) - if 'html' in self.options.cover_actions: - self.coverage.html_report( - directory=self.options.cover_directory, **report_args) - if 'xml' in self.options.cover_actions: - outfile = self.options.cover_outfile - if outfile == '-': - outfile = None - self.coverage.xml_report(outfile=outfile, **report_args) - - return - -options = [ - optparse.Option('', - '--cover-action', action='append', default=None, - dest='cover_actions', type="choice", - choices=['annotate', 'html', 'report', 'xml'], - help="""\ -annotate Annotate source files with execution information. -html Create an HTML report. -report Report coverage stats on modules. -xml Create an XML report of coverage results. -""".strip()), - optparse.Option( - '--cover-package', action='store', - dest="cover_package", default="", - metavar="COVER_PACKAGE", - help="Restrict coverage output to selected package" - ), - optparse.Option("--cover-tests", action="store_true", - dest="cover_tests", - metavar="[NOSE_COVER_TESTS]", - default=False, - help="Include test modules in coverage report "), - optparse.Option( - '--cover-branch', action='store_true', - help="Measure branch execution. HIGHLY EXPERIMENTAL!" - ), - optparse.Option( - '--cover-directory', action='store', - metavar="DIR", - help="Write the output files to DIR." - ), - optparse.Option( - '--cover-ignore-errors', action='store_true', - help="Ignore errors while reading source files." - ), - optparse.Option( - '--cover-pylib', action='store_true', - help="Measure coverage even inside the Python installed library, " - "which isn't done by default." - ), - optparse.Option( - '--cover-show-missing', action='store_true', - help="Show line numbers of statements in each module that weren't " - "executed." - ), - optparse.Option( - '--cover-omit', action='store', - metavar="PRE1,PRE2,...", - default='', - help="Omit files when their filename path starts with one of these " - "prefixes." - ), - optparse.Option( - '--cover-outfile', action='store', - metavar="OUTFILE", - help="Write the XML report to this file. Defaults to 'coverage.xml'" - ), - optparse.Option( - '--cover-parallel-mode', action='store_true', - help="Include the machine name and process id in the .coverage " - "data file name." - ), - optparse.Option( - '--cover-timid', action='store_true', - help="Use a simpler but slower trace method. Try this if you get " - "seemingly impossible results!" - ), - optparse.Option( - '--cover-append', action='store_false', - help="Append coverage data to .coverage, otherwise it is started " - "clean with each run." - ) -] - -# py.test plugin hooks def pytest_addoption(parser): - """ - Get all the options from the coverage.runner and import them - """ group = parser.getgroup('Coverage options') - for opt in options: - group._addoption_instance(opt) + group.addoption('--cover-show-missing', action='store', default=None, + dest='show_missing', + help='Show missing files') + group.addoption('--cover-action', action='store', default=None, + dest='coverage', type="choice", + choices=['report', 'annotate', 'html'], + help=""" + html: Directory for html output + report: Output a text report, + annotate: Annotate your source code for which lines were executed and which were not + """.strip()) + group.addoption('--cover-directory', action='store', default=None, + dest='directory', + help='Directory for the reports (html / annotate results) defaults to ./coverage') + group.addoption('--cover-ignore-errors', action='store', default=None, + dest='ignore_errors', + help='Ignore errors') + group.addoption('--cover-omit', action='store', default=None, + dest='omit', + help='File with coverage files to omit') def pytest_configure(config): - # Load the runner and start it up - if config.getvalue("cover_actions"): - config.pluginmanager.register(DoCover(config), "do_coverage") + if config.getvalue("coverage"): + config.pluginmanager.register(DoCoverage(config), "docoverage") -class DoCover: +class DoCoverage: def __init__(self, config): - self.config = config - - def pytest_sessionstart(self): - self.coverage = CoverageTestWrapper(self.config.option) - # XXX maybe better to start/suspend/resume coverage - # for each single test item - self.coverage.start() + self.config = config + import coverage + self.cov = coverage.coverage() + self.cov.use_cache(0) # Do not cache any of the coverage.py stuff + self.cov.start() def pytest_terminal_summary(self, terminalreporter): - # Finished the tests start processing the coverage config = terminalreporter.config tw = terminalreporter._tw tw.sep('-', 'coverage') tw.line('Processing Coverage...') - self.coverage.finish() - - -# XXX please make the following unnessary -# Monkey patch omit_filter to use regex patterns for file omits -def omit_filter(omit_prefixes, code_units): - import re - exclude_patterns = [re.compile(line.strip()) - for line in omit_prefixes if line and not line.startswith('#')] - filtered = [] - for cu in code_units: - skip = False - for pattern in exclude_patterns: - if pattern.search(cu.filename): - skip = True - break - - if not skip: - filtered.append(cu) - return filtered - -#coverage.codeunit.omit_filter = omit_filter + self.cov.stop() + self.cov.save() + + # Get the configurations + config = terminalreporter.config + + show_missing = config.getvalue('show_missing') + omit = config.getvalue('omit') + report = config.getvalue('report') or 'report' + directory = config.getvalue('directory') or 'coverage' + + # Set up the report_args + report_args = { + 'morfs': [], + 'ignore_errors': config.getvalue('ignore_errors'), + } + + # Handle any omits + if omit: + try: + omit_file = py.path.local(omit) + omit_prefixes = [line.strip() for line in omit_file.readlines()] + report_args['omit_prefixes'] = omit_prefixes + except: + pass + + if report == 'report': + self.cov.report(show_missing=show_missing, **report_args) + if report == 'annotate': + self.cov.annotate(directory=directory, **report_args) + if report == 'html': + self.cov.html_report(directory=directory, **report_args) + From commits-noreply at bitbucket.org Wed Feb 10 21:06:53 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 20:06:53 +0000 (UTC) Subject: [py-svn] pytest-coverage commit de6277ef78cf: make the test actually minimally check that the report contains the test function Message-ID: <20100210200653.937877EF31@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265832400 -3600 # Node ID de6277ef78cf755f600c03ce485bf28ca97778a3 # Parent 3a8184250a7f416f46fd1f133feceeb8538d48a4 make the test actually minimally check that the report contains the test function --- a/test_pytest_coverage.py +++ b/test_pytest_coverage.py @@ -16,6 +16,7 @@ def test_functional(testdir): assert result.ret == 0 assert result.stdout.fnmatch_lines([ '*Processing Coverage*', + 'test_functional*4*3*75%*', ]) def test_coverage_is_not_imported(testdir): From commits-noreply at bitbucket.org Wed Feb 10 21:11:14 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 20:11:14 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 039446d6637f: adding a test and the option for --cover-package Message-ID: <20100210201114.330CD7EE7C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265832660 -3600 # Node ID 039446d6637fb9d5f85ea91f1fbbbdb3b77b9f0b # Parent de6277ef78cf755f600c03ce485bf28ca97778a3 adding a test and the option for --cover-package --- a/test_pytest_coverage.py +++ b/test_pytest_coverage.py @@ -31,3 +31,20 @@ def test_coverage_is_not_imported(testdi '*1 passed*', ]) #print result.stdout.str() + +def test_cover_package(testdir): + testdir.makepyfile(""" + def f(): + x = 42 + def test_whatever(): + pass + """) + result = testdir.runpytest('--cover-package=test_cover_package', + '--cover-action=report') + assert result.ret == 0 + assert result.stdout.fnmatch_lines([ + '*Processing Coverage*', + 'test_cover_package*4*3*75%*', + ]) + s = result.stdout.str() + assert 'py/_test' not in s, "other packages were not excluded!" --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -10,9 +10,6 @@ import py def pytest_addoption(parser): group = parser.getgroup('Coverage options') - group.addoption('--cover-show-missing', action='store', default=None, - dest='show_missing', - help='Show missing files') group.addoption('--cover-action', action='store', default=None, dest='coverage', type="choice", choices=['report', 'annotate', 'html'], @@ -24,6 +21,13 @@ def pytest_addoption(parser): group.addoption('--cover-directory', action='store', default=None, dest='directory', help='Directory for the reports (html / annotate results) defaults to ./coverage') + group.addoption('--cover-show-missing', action='store', default=None, + dest='show_missing', + help='Show missing files') + group.addoption('--cover-package', action='append', default=[], + dest='coverpackage', + help='(multi allowed) only include info from specified package.') + group.addoption('--cover-ignore-errors', action='store', default=None, dest='ignore_errors', help='Ignore errors') From commits-noreply at bitbucket.org Wed Feb 10 21:28:27 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 20:28:27 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 0f453c82fe17: implement --cover-package enough to pass the test Message-ID: <20100210202827.DFDB57EECF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265833696 -3600 # Node ID 0f453c82fe1730df693253a79a89fc2af9cdd174 # Parent 039446d6637fb9d5f85ea91f1fbbbdb3b77b9f0b implement --cover-package enough to pass the test --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -5,8 +5,7 @@ Original code by Ross Lawley. Requires Ned Batchelder's excellent coverage: http://nedbatchelder.com/code/coverage/ """ -import py - +import sys, py def pytest_addoption(parser): group = parser.getgroup('Coverage options') @@ -25,7 +24,7 @@ def pytest_addoption(parser): dest='show_missing', help='Show missing files') group.addoption('--cover-package', action='append', default=[], - dest='coverpackage', + dest='coverpackages', help='(multi allowed) only include info from specified package.') group.addoption('--cover-ignore-errors', action='store', default=None, @@ -62,12 +61,22 @@ class DoCoverage: omit = config.getvalue('omit') report = config.getvalue('report') or 'report' directory = config.getvalue('directory') or 'coverage' + # Set up the report_args report_args = { - 'morfs': [], 'ignore_errors': config.getvalue('ignore_errors'), } + coverpackages = self.config.getvalue("coverpackages") + if coverpackages: + modules = report_args['morfs'] = [] + for name, module in sys.modules.items(): + if module is not None and hasattr(module, '__file__'): + fn = module.__file__ + for pkg in coverpackages: + if name.startswith(pkg): + modules.append(fn) + break # Handle any omits if omit: From commits-noreply at bitbucket.org Wed Feb 10 21:32:30 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Feb 2010 20:32:30 +0000 (UTC) Subject: [py-svn] pytest-coverage commit b18c6cf598db: adding James and Ross as authors Message-ID: <20100210203230.A972C7EECF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265833924 -3600 # Node ID b18c6cf598dbe27aa6f8c2115c9ea5837df82e55 # Parent 0f453c82fe1730df693253a79a89fc2af9cdd174 adding James and Ross as authors --- a/setup.py +++ b/setup.py @@ -21,8 +21,8 @@ setup( description='py.test coverage plugin', long_description=__doc__, license='MIT', - author='holger krekel', - author_email='py-dev at codespeak.net,holger at merlinux.eu', + author='holger krekel, James Mills, Ross Lawley', + author_email='py-dev at codespeak.net', url='http://bitbucket.org/prologic/pytest-prologic', platforms=['linux', 'osx', 'win32'], py_modules=['pytest_coverage'], From commits-noreply at bitbucket.org Thu Feb 11 10:10:27 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 11 Feb 2010 09:10:27 +0000 (UTC) Subject: [py-svn] pytest-coverage commit dac090ea7327: pytest_coverage.py: Changed --cover-action to --cover-report (more meaningful ihmo - as in - report_type), also the dest for this option conflicted with py.test's --report option. Changed --cover-package to just --cover, use this to test if we should load the plugin or not. Message-ID: <20100211091027.7A30F7EF07@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265879398 -36000 # Node ID dac090ea73279920077fa4243d21a6ce18cfb322 # Parent b18c6cf598dbe27aa6f8c2115c9ea5837df82e55 pytest_coverage.py: Changed --cover-action to --cover-report (more meaningful ihmo - as in - report_type), also the dest for this option conflicted with py.test's --report option. Changed --cover-package to just --cover, use this to test if we should load the plugin or not. --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -9,8 +9,11 @@ import sys, py def pytest_addoption(parser): group = parser.getgroup('Coverage options') - group.addoption('--cover-action', action='store', default=None, - dest='coverage', type="choice", + group.addoption('--cover', action='append', default=[], + dest='coverpackages', + help='(multi allowed) only include info from specified package.') + group.addoption('--cover-report', action='store', default="report", + dest='report_type', type="choice", choices=['report', 'annotate', 'html'], help=""" html: Directory for html output @@ -23,10 +26,6 @@ def pytest_addoption(parser): group.addoption('--cover-show-missing', action='store', default=None, dest='show_missing', help='Show missing files') - group.addoption('--cover-package', action='append', default=[], - dest='coverpackages', - help='(multi allowed) only include info from specified package.') - group.addoption('--cover-ignore-errors', action='store', default=None, dest='ignore_errors', help='Ignore errors') @@ -35,7 +34,7 @@ def pytest_addoption(parser): help='File with coverage files to omit') def pytest_configure(config): - if config.getvalue("coverage"): + if config.getvalue("coverpackages"): config.pluginmanager.register(DoCoverage(config), "docoverage") class DoCoverage: @@ -59,7 +58,7 @@ class DoCoverage: show_missing = config.getvalue('show_missing') omit = config.getvalue('omit') - report = config.getvalue('report') or 'report' + report_type = config.getvalue('report_type') or 'report_type' directory = config.getvalue('directory') or 'coverage' @@ -87,10 +86,10 @@ class DoCoverage: except: pass - if report == 'report': + if report_type == 'report': self.cov.report(show_missing=show_missing, **report_args) - if report == 'annotate': - self.cov.annotate(directory=directory, **report_args) - if report == 'html': + elif report_type == 'annotate': + self.cov.annotate(directory=directory, **report_type) + elif report_type == 'html': self.cov.html_report(directory=directory, **report_args) From commits-noreply at bitbucket.org Thu Feb 11 10:10:29 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 11 Feb 2010 09:10:29 +0000 (UTC) Subject: [py-svn] pytest-coverage commit f160262910b3: Minor cosmetic changes Message-ID: <20100211091029.622187EF0D@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265879416 -36000 # Node ID f160262910b31d60fbf0ea612c6a4d2ac0e1d4c7 # Parent dac090ea73279920077fa4243d21a6ce18cfb322 Minor cosmetic changes --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -16,9 +16,9 @@ def pytest_addoption(parser): dest='report_type', type="choice", choices=['report', 'annotate', 'html'], help=""" - html: Directory for html output - report: Output a text report, - annotate: Annotate your source code for which lines were executed and which were not + html: Directory for html output. + report: Output a text report. + annotate: Annotate your source code for which lines were executed and which were not. """.strip()) group.addoption('--cover-directory', action='store', default=None, dest='directory', @@ -92,4 +92,3 @@ class DoCoverage: self.cov.annotate(directory=directory, **report_type) elif report_type == 'html': self.cov.html_report(directory=directory, **report_args) - From commits-noreply at bitbucket.org Thu Feb 11 10:54:05 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 11 Feb 2010 09:54:05 +0000 (UTC) Subject: [py-svn] pytest-coverage commit df4eeb6a1087: pytest_coverage.py: Use the terminal object (tw) to write out the coverage report when report_type is 'report' so it's picked up by other plugins such as pytest_pastebin Message-ID: <20100211095405.7CEC17EECF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1265882033 -36000 # Node ID df4eeb6a1087a7c59a880adf6f25df4f9ab78b35 # Parent f160262910b31d60fbf0ea612c6a4d2ac0e1d4c7 pytest_coverage.py: Use the terminal object (tw) to write out the coverage report when report_type is 'report' so it's picked up by other plugins such as pytest_pastebin --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -87,7 +87,7 @@ class DoCoverage: pass if report_type == 'report': - self.cov.report(show_missing=show_missing, **report_args) + self.cov.report(show_missing=show_missing, file=tw, **report_args) elif report_type == 'annotate': self.cov.annotate(directory=directory, **report_type) elif report_type == 'html': From commits-noreply at bitbucket.org Thu Feb 11 22:42:01 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 11 Feb 2010 21:42:01 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 96f47169f745: fix comment but leave "cover-omit" uncommented - it has Message-ID: <20100211214201.6ED508B5BF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265924504 -3600 # Node ID 96f47169f7458a1d29dc3a6c8a89c382df53e7c6 # Parent 66ff23bf9f9eb09179970d6cd86a5762f2e56975 fix comment but leave "cover-omit" uncommented - it has no test and it's not clear to me how useful it is - shouldn't we rather list to-be-included packages? --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -31,7 +31,7 @@ def pytest_addoption(parser): help='Ignore errors of finding source files for code.') #group.addoption('--cover-omit', action='store', default=None, # dest='omit', - # help='File with coverage files to omit') + # help='File listing files to omit from coverage reporting' def pytest_configure(config): if config.getvalue("coverpackages") or config.getvalue("report_type"): From commits-noreply at bitbucket.org Thu Feb 11 22:42:01 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 11 Feb 2010 21:42:01 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 66ff23bf9f9e: fix tests and cleanup module and naming a bit Message-ID: <20100211214201.4C6B88B5BE@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User holger krekel # Date 1265924394 -3600 # Node ID 66ff23bf9f9eb09179970d6cd86a5762f2e56975 # Parent df4eeb6a1087a7c59a880adf6f25df4f9ab78b35 fix tests and cleanup module and naming a bit --- a/test_pytest_coverage.py +++ b/test_pytest_coverage.py @@ -12,7 +12,7 @@ def test_functional(testdir): def test_whatever(): pass """) - result = testdir.runpytest('--cover-action=report') + result = testdir.runpytest('--cover-report=report') assert result.ret == 0 assert result.stdout.fnmatch_lines([ '*Processing Coverage*', @@ -39,8 +39,7 @@ def test_cover_package(testdir): def test_whatever(): pass """) - result = testdir.runpytest('--cover-package=test_cover_package', - '--cover-action=report') + result = testdir.runpytest('--cover=test_cover_package',) assert result.ret == 0 assert result.stdout.fnmatch_lines([ '*Processing Coverage*', --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -12,7 +12,7 @@ def pytest_addoption(parser): group.addoption('--cover', action='append', default=[], dest='coverpackages', help='(multi allowed) only include info from specified package.') - group.addoption('--cover-report', action='store', default="report", + group.addoption('--cover-report', action='store', default=None, dest='report_type', type="choice", choices=['report', 'annotate', 'html'], help=""" @@ -28,14 +28,14 @@ def pytest_addoption(parser): help='Show missing files') group.addoption('--cover-ignore-errors', action='store', default=None, dest='ignore_errors', - help='Ignore errors') - group.addoption('--cover-omit', action='store', default=None, - dest='omit', - help='File with coverage files to omit') + help='Ignore errors of finding source files for code.') + #group.addoption('--cover-omit', action='store', default=None, + # dest='omit', + # help='File with coverage files to omit') def pytest_configure(config): - if config.getvalue("coverpackages"): - config.pluginmanager.register(DoCoverage(config), "docoverage") + if config.getvalue("coverpackages") or config.getvalue("report_type"): + config.pluginmanager.register(DoCoverage(config), "coverage") class DoCoverage: def __init__(self, config): @@ -57,8 +57,8 @@ class DoCoverage: config = terminalreporter.config show_missing = config.getvalue('show_missing') - omit = config.getvalue('omit') - report_type = config.getvalue('report_type') or 'report_type' + #omit = config.getvalue('omit') + report_type = config.getvalue('report_type') or 'report' directory = config.getvalue('directory') or 'coverage' @@ -78,13 +78,10 @@ class DoCoverage: break # Handle any omits - if omit: - try: - omit_file = py.path.local(omit) - omit_prefixes = [line.strip() for line in omit_file.readlines()] - report_args['omit_prefixes'] = omit_prefixes - except: - pass + #if omit: + # omit_file = py.path.local(omit) + # omit_prefixes = [line.strip() for line in omit_file.readlines()] + # report_args['omit_prefixes'] = omit_prefixes if report_type == 'report': self.cov.report(show_missing=show_missing, file=tw, **report_args) From commits-noreply at bitbucket.org Sat Feb 13 12:35:41 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 11:35:41 +0000 (UTC) Subject: [py-svn] pytest-pycheckers commit 5bef9172457d: use the checker output as replacement for pytest tracebacks Message-ID: <20100213113541.B64237EE74@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-pycheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-pycheckers/overview/ # User Ronny Pfannschmidt # Date 1266060767 -3600 # Node ID 5bef9172457dd0d5cda10ff109b7ec7c83e43bff # Parent 30bef2ea4ca5e97e53bbe1e54a4ef11d4bafe157 use the checker output as replacement for pytest tracebacks --- a/codecheckers/plugin.py +++ b/codecheckers/plugin.py @@ -9,8 +9,14 @@ class PyCodeCheckItem(py.test.collect.It self._ep = ep def runtest(self): + c = py.io.StdCapture() mod = self._ep.load() - mod.check_file(self.fspath) + found_errors, out, err = c.call(mod.check_file, self.fspath) + self.out, self.err = out, err + assert not found_errors + + def repr_failure(self, exc_info): + return self.out def reportinfo(self): return (self.fspath, -1, "codecheck") @@ -21,6 +27,7 @@ class PyCheckerCollector(py.test.collect def __init__(self, path, parent): super(PyCheckerCollector, self).__init__(path, parent) self.name += '[code-check]' + def collect(self): entrypoints = pkg_resources.iter_entry_points('codechecker') return [PyCodeCheckItem(ep, self) for ep in entrypoints] --- a/codecheckers/flakes.py +++ b/codecheckers/flakes.py @@ -10,5 +10,5 @@ def assignment_monkeypatched_init(self, Assignment.__init__ = assignment_monkeypatched_init def check_file(path): - error_count = pyflakes_check(path.read(), str(path)) - assert not error_count + return pyflakes_check(path.read(), str(path)) + --- a/codecheckers/pep.py +++ b/codecheckers/pep.py @@ -18,4 +18,4 @@ def check_file(path): checker = PyTestChecker(str(path)) error_count = checker.check_all() ignored = checker.ignored_errors - assert error_count <= ignored + return max(error_count - ignored, 0) --- a/tests/test_pyflakes.py +++ b/tests/test_pyflakes.py @@ -6,8 +6,9 @@ def test_pyflakes_finds_name_error(testd abc ''') f.write(f.read() + '\n') #XXX: bad hack cause i fail to disable the pep8 checker - out = testdir.runpytest('--tb=short', '-k', 'flakes') + out = testdir.runpytest('--tb=short', '-k', 'flakes', '-v') out.stdout.fnmatch_lines([ + '*abc*', '*1 failed*', ]) @@ -19,5 +20,5 @@ def test_reportinfo_verbose(testdir): f.write(f.read() + '\n') out = testdir.runpytest('-v') out.stdout.fnmatch_lines([ - '*test_reportinfo_verbose.py: codecheck', + '*test_reportinfo_verbose.py: codecheck PASS', ]) From commits-noreply at bitbucket.org Sat Feb 13 12:38:15 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 11:38:15 +0000 (UTC) Subject: [py-svn] pytest-pycheckers commit 6409b2b16009: add codechecker name to the reportinfo test name Message-ID: <20100213113815.E4BA87EE74@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-pycheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-pycheckers/overview/ # User Ronny Pfannschmidt # Date 1266060937 -3600 # Node ID 6409b2b16009ea594da1006c3ca7ae80974103c1 # Parent 5bef9172457dd0d5cda10ff109b7ec7c83e43bff add codechecker name to the reportinfo test name --- a/codecheckers/plugin.py +++ b/codecheckers/plugin.py @@ -19,7 +19,7 @@ class PyCodeCheckItem(py.test.collect.It return self.out def reportinfo(self): - return (self.fspath, -1, "codecheck") + return (self.fspath, -1, "codecheck %s" % self._ep.name) --- a/tests/test_pyflakes.py +++ b/tests/test_pyflakes.py @@ -20,5 +20,5 @@ def test_reportinfo_verbose(testdir): f.write(f.read() + '\n') out = testdir.runpytest('-v') out.stdout.fnmatch_lines([ - '*test_reportinfo_verbose.py: codecheck PASS', + '*test_reportinfo_verbose.py: codecheck pyflakes PASS', ]) From commits-noreply at bitbucket.org Sat Feb 13 13:33:59 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 12:33:59 +0000 (UTC) Subject: [py-svn] pytest-pycheckers commit e5011b8b69d0: add build/dist to .hgignore Message-ID: <20100213123359.B1B467EF12@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-pycheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-pycheckers/overview/ # User Ronny Pfannschmidt # Date 1266064281 -3600 # Node ID e5011b8b69d0db3ef350af46f12659d4e0ff2b17 # Parent 6409b2b16009ea594da1006c3ca7ae80974103c1 add build/dist to .hgignore --- a/.hgignore +++ b/.hgignore @@ -1,1 +1,3 @@ .*\.egg-info +build +dist From commits-noreply at bitbucket.org Sat Feb 13 13:46:56 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 12:46:56 +0000 (UTC) Subject: [py-svn] pytest-pycheckers commit 267da01f799f: version bump Message-ID: <20100213124656.7D72D7EF12@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-pycheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-pycheckers/overview/ # User Ronny Pfannschmidt # Date 1266065049 -3600 # Node ID 267da01f799fafad6703f9dafad76d38c987d696 # Parent e5011b8b69d0db3ef350af46f12659d4e0ff2b17 version bump --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup setup( name='pytest-codecheckers', description='pytest addon to add code-checking as source for testcases', - version='0.0', + version='0.1', author='Ronny Pfannschmidt', author_email='Ronny.Pfannschmidt at gmx.de', packages=[ From commits-noreply at bitbucket.org Sat Feb 13 13:46:58 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 12:46:58 +0000 (UTC) Subject: [py-svn] pytest-pycheckers commit 4f8cb3a4a8cb: Added tag 0.1 for changeset 267da01f799f Message-ID: <20100213124658.3EE997EF12@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-pycheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-pycheckers/overview/ # User Ronny Pfannschmidt # Date 1266065055 -3600 # Node ID 4f8cb3a4a8cb6844595c8e2ec982ab4e55b4b22a # Parent 267da01f799fafad6703f9dafad76d38c987d696 Added tag 0.1 for changeset 267da01f799f --- /dev/null +++ b/.hgtags @@ -0,0 +1,1 @@ +267da01f799fafad6703f9dafad76d38c987d696 0.1 From commits-noreply at bitbucket.org Sat Feb 13 14:55:27 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 13:55:27 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit ca8b4307740f: add url to setup.py Message-ID: <20100213135527.943067EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User Ronny Pfannschmidt # Date 1266065233 -3600 # Node ID ca8b4307740fa69e8a89e88c21658fa556c7ab30 # Parent 4f8cb3a4a8cb6844595c8e2ec982ab4e55b4b22a add url to setup.py --- a/setup.py +++ b/setup.py @@ -3,6 +3,7 @@ from setuptools import setup setup( name='pytest-codecheckers', description='pytest addon to add code-checking as source for testcases', + url='http://bitbucket.org/RonnyPfannschmidt/pytest-pycheckers/', version='0.1', author='Ronny Pfannschmidt', author_email='Ronny.Pfannschmidt at gmx.de', From commits-noreply at bitbucket.org Sat Feb 13 14:55:29 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 13:55:29 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit c550e0cb2394: depend on py>=1.2.0 Message-ID: <20100213135529.4388B7EF3F@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User Ronny Pfannschmidt # Date 1266069167 -3600 # Node ID c550e0cb239426f187108eef8b2d3338d1e47dbc # Parent ca8b4307740fa69e8a89e88c21658fa556c7ab30 depend on py>=1.2.0 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ setup( ], }, install_requires=[ + 'py>=1.2.0', 'pyflakes>=0.4', 'pep8', ], From commits-noreply at bitbucket.org Sat Feb 13 15:01:47 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 14:01:47 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit a05bf0e0ffa8: adding a longer description, the py>=1.2.0 dependency and bumping Message-ID: <20100213140147.A6E177EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User holger krekel # Date 1266069524 -3600 # Node ID a05bf0e0ffa81af4114aa857ec949c5fd6995969 # Parent 4f8cb3a4a8cb6844595c8e2ec982ab4e55b4b22a adding a longer description, the py>=1.2.0 dependency and bumping the version number, hope that's fine with ronny. --- a/setup.py +++ b/setup.py @@ -1,9 +1,25 @@ +""" +py.test plugin for checking PEP8 source code compliance using pyflakes. + +Usage +--------- + +after installation (e.g. via ``pip install pytest-codecheckers``) you can type:: + + py.test [path/to/mypkg] + +which will automatically perform source code sanity checks. If you have +further questions please send them to the `pytest-dev`_ mailing list. + +.. _`pytest-dev`: http://codespeak.net/mailman/listinfo/py-dev +""" from setuptools import setup setup( name='pytest-codecheckers', - description='pytest addon to add code-checking as source for testcases', - version='0.1', + description='pytest plugin to add source code sanity checks (pep8 and friends)', + long_description=__doc__, + version='0.2', author='Ronny Pfannschmidt', author_email='Ronny.Pfannschmidt at gmx.de', packages=[ @@ -21,5 +37,6 @@ setup( install_requires=[ 'pyflakes>=0.4', 'pep8', + 'py>=1.2.0', ], ) From commits-noreply at bitbucket.org Sat Feb 13 15:01:49 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 14:01:49 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit 7dfa0cd9715d: merge - added long description, bumping version number Message-ID: <20100213140149.610547EF38@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User holger krekel # Date 1266069688 -3600 # Node ID 7dfa0cd9715dfd9ba4b5018ac86a91926b270bc9 # Parent c550e0cb239426f187108eef8b2d3338d1e47dbc # Parent a05bf0e0ffa81af4114aa857ec949c5fd6995969 merge - added long description, bumping version number --- a/setup.py +++ b/setup.py @@ -1,10 +1,25 @@ +""" +py.test plugin for checking PEP8 source code compliance using pyflakes. + +Usage +--------- + +after installation (e.g. via ``pip install pytest-codecheckers``) you can type:: + + py.test [path/to/mypkg] + +which will automatically perform source code sanity checks. If you have +further questions please send them to the `pytest-dev`_ mailing list. + +.. _`pytest-dev`: http://codespeak.net/mailman/listinfo/py-dev +""" from setuptools import setup setup( name='pytest-codecheckers', - description='pytest addon to add code-checking as source for testcases', - url='http://bitbucket.org/RonnyPfannschmidt/pytest-pycheckers/', - version='0.1', + description='pytest plugin to add source code sanity checks (pep8 and friends)', + long_description=__doc__, + version='0.2', author='Ronny Pfannschmidt', author_email='Ronny.Pfannschmidt at gmx.de', packages=[ From commits-noreply at bitbucket.org Sat Feb 13 15:02:59 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 14:02:59 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit ff6e3c34321f: Added tag 0.2 for changeset 7dfa0cd9715d Message-ID: <20100213140259.577507EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User Ronny Pfannschmidt # Date 1266069607 -3600 # Node ID ff6e3c34321fc1d329f85b96aa5b390e044349a6 # Parent 7dfa0cd9715dfd9ba4b5018ac86a91926b270bc9 Added tag 0.2 for changeset 7dfa0cd9715d --- a/.hgtags +++ b/.hgtags @@ -1,1 +1,2 @@ 267da01f799fafad6703f9dafad76d38c987d696 0.1 +7dfa0cd9715dfd9ba4b5018ac86a91926b270bc9 0.2 From commits-noreply at bitbucket.org Sat Feb 13 15:14:26 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 14:14:26 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit a23bb4ace996: ignore pyc files Message-ID: <20100213141426.6265F7EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User holger krekel # Date 1266070457 -3600 # Node ID a23bb4ace996d5e71fa8a6ffcd3879cf0eb8c3ec # Parent ff6e3c34321fc1d329f85b96aa5b390e044349a6 ignore pyc files --- a/.hgignore +++ b/.hgignore @@ -1,3 +1,4 @@ .*\.egg-info build dist +.*\.pyc From commits-noreply at bitbucket.org Sat Feb 13 20:55:40 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 13 Feb 2010 19:55:40 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit 8abd5975f32d: re-add url to setup.py Message-ID: <20100213195540.BACA47EF44@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User Ronny Pfannschmidt # Date 1266090564 -3600 # Node ID 8abd5975f32d54c99747cb55ad295b6572e61a25 # Parent a23bb4ace996d5e71fa8a6ffcd3879cf0eb8c3ec re-add url to setup.py --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ setup( version='0.2', author='Ronny Pfannschmidt', author_email='Ronny.Pfannschmidt at gmx.de', + url='http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/', packages=[ 'codecheckers', ], From commits-noreply at bitbucket.org Wed Feb 24 23:13:18 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Feb 2010 22:13:18 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit a29b2b076620: handle internal errors and fix pep8 test violations Message-ID: <20100224221318.A4EE67EEDE@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User Ronny Pfannschmidt # Date 1267049403 -3600 # Node ID a29b2b0766200fe782a6798d326b37df301d7fa6 # Parent 8abd5975f32d54c99747cb55ad295b6572e61a25 handle internal errors and fix pep8 test violations --- a/codecheckers/plugin.py +++ b/codecheckers/plugin.py @@ -11,18 +11,25 @@ class PyCodeCheckItem(py.test.collect.It def runtest(self): c = py.io.StdCapture() mod = self._ep.load() - found_errors, out, err = c.call(mod.check_file, self.fspath) - self.out, self.err = out, err + try: + found_errors, out, err = c.call(mod.check_file, self.fspath) + self.out, self.err = out, err + except: + found_errors = True + self.info = py.code.ExceptionInfo() assert not found_errors def repr_failure(self, exc_info): - return self.out + try: + return self.out + except AttributeError: + #XXX: internal error ?! + return super(PyCodeCheckItem, self).repr_failure(self.info) def reportinfo(self): return (self.fspath, -1, "codecheck %s" % self._ep.name) - class PyCheckerCollector(py.test.collect.File): def __init__(self, path, parent): super(PyCheckerCollector, self).__init__(path, parent) --- a/codecheckers/pep.py +++ b/codecheckers/pep.py @@ -3,7 +3,8 @@ import pep8 class PyTestChecker(pep8.Checker): ignored_errors = 0 def report_error(self, line_number, offset, text, check): - if pep8.ignore_code(text[:4]): #XXX: pep8 is a retarded module! + #XXX: pep8 is a retarded module! + if pep8.ignore_code(text[:4]): self.ignored_errors += 1 pep8.Checker.report_error(self, line_number, offset, text, check) @@ -16,6 +17,7 @@ def check_file(path): 'dummy file', ]) checker = PyTestChecker(str(path)) + #XXX: bails out on death error_count = checker.check_all() ignored = checker.ignored_errors return max(error_count - ignored, 0) --- a/tests/test_pyflakes.py +++ b/tests/test_pyflakes.py @@ -5,7 +5,8 @@ def test_pyflakes_finds_name_error(testd def b(): abc ''') - f.write(f.read() + '\n') #XXX: bad hack cause i fail to disable the pep8 checker + #XXX: bad hack cause i fail to disable the pep8 checker + f.write(f.read() + '\n') out = testdir.runpytest('--tb=short', '-k', 'flakes', '-v') out.stdout.fnmatch_lines([ '*abc*', From commits-noreply at bitbucket.org Thu Feb 25 15:24:54 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:24:54 +0000 (UTC) Subject: [py-svn] pytest-coverage commit ffd3f4e234bd: Added tag 0.2.1 for changeset 9faf4bae9b48 Message-ID: <20100225142454.C9DBA7EF01@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267106266 -36000 # Node ID ffd3f4e234bd1bb7b17d0a626874c0182d487cbe # Parent 9faf4bae9b48724bb80b6103ae2369cf4e37ad58 Added tag 0.2.1 for changeset 9faf4bae9b48 --- a/.hgtags +++ b/.hgtags @@ -1,2 +1,3 @@ 8e083df63e4386453cf880f0186766b6d20f2c49 1.0 b3978e930a7be474e4dfd67bab0afe2345d3f2da 0.2 +9faf4bae9b48724bb80b6103ae2369cf4e37ad58 0.2.1 From commits-noreply at bitbucket.org Thu Feb 25 15:24:54 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:24:54 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 9faf4bae9b48: Ignore dist dir Message-ID: <20100225142454.9BCAF7EEFC@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267106264 -36000 # Node ID 9faf4bae9b48724bb80b6103ae2369cf4e37ad58 # Parent 68ab9b202d7b795254f040542c6d0b6f3bb6adb6 Ignore dist dir --- a/.hgignore +++ b/.hgignore @@ -2,5 +2,6 @@ syntax: glob *.pyc *.patch +dist build pytest_coverage.egg-info From commits-noreply at bitbucket.org Thu Feb 25 15:24:57 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:24:57 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 96ecb90a1f36: Fixed tests by correcting options passed Message-ID: <20100225142457.4E6707EF08@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267107292 -36000 # Node ID 96ecb90a1f3646debe2d0b5e783618a29ced4a37 # Parent ffd3f4e234bd1bb7b17d0a626874c0182d487cbe Fixed tests by correcting options passed --- a/test_pytest_coverage.py +++ b/test_pytest_coverage.py @@ -12,8 +12,12 @@ def test_functional(testdir): def test_whatever(): pass """) - result = testdir.runpytest('--cover-action=report') + result = testdir.runpytest('--cover=test_functional --cover-report=report') assert result.ret == 0 + print + print type(result.stdout) + print repr(result.stdout) + print assert result.stdout.fnmatch_lines([ '*Processing Coverage*', 'test_functional*4*3*75%*', @@ -30,7 +34,6 @@ def test_coverage_is_not_imported(testdi assert result.stdout.fnmatch_lines([ '*1 passed*', ]) - #print result.stdout.str() def test_cover_package(testdir): testdir.makepyfile(""" @@ -39,8 +42,8 @@ def test_cover_package(testdir): def test_whatever(): pass """) - result = testdir.runpytest('--cover-package=test_cover_package', - '--cover-action=report') + result = testdir.runpytest('--cover=test_cover_package', + '--cover-report=report') assert result.ret == 0 assert result.stdout.fnmatch_lines([ '*Processing Coverage*', From commits-noreply at bitbucket.org Thu Feb 25 15:25:11 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:11 +0000 (UTC) Subject: [py-svn] pytest-coverage commit b7d4ac6dbbef: Added Makefile and tools/mkpkgs helpers Message-ID: <20100225142511.A34BD7EF21@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267105140 -36000 # Node ID b7d4ac6dbbefa9d2163805f15902817d50a1df7e # Parent df4eeb6a1087a7c59a880adf6f25df4f9ab78b35 Added Makefile and tools/mkpkgs helpers --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +.PHONY: help clean tests packages + +help: + @echo "Please use \`make ' where is one of" + @echo " clean to cleanup build and temporary files" + @echo " tests to run the test suite" + @echo " packages to build python source and egg packages" + +clean: + @rm -rf build dist *.egg-info + @rm -rf .coverage coverage + @find . -name '*.pyc' -delete + @find . -name '*.pyo' -delete + @find . -name '*~' -delete + +packages: + @tools/mkpkgs -p python2.5 + @tools/mkpkgs -p python2.6 + +tests: + @py.test -x --ignore=tmp \ + --pastebin=all \ + --report=skipped \ + --cover=pytest_coverage \ + --cover-report=html \ + --cover-directory=coverage \ + --cover-show-missing --- /dev/null +++ b/tools/mkpkgs @@ -0,0 +1,105 @@ +#!/bin/bash +# +# mkpkgs +# +# Copyright (C) 2010 James Mills +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. +# + +VERSION="0.1" + +test_application () { + application=${1} + $application --version &> /dev/null + if [[ $? != 0 ]]; then + echo "Cannot find or execute ${application}!" + exit 1 + fi +} + +get_latest_tag() { + echo "$(hg tags | awk '{if (NR == 2) print $1}')" +} + +make_packages() { + cwd=$(pwd) + hg=$(which hg) + python=$(which ${1}) + + test_application "$hg" + test_application "$python" + + status=$(hg status -0 -m) + if [[ $status ]]; then + echo "Working directory not in a clean state! Aborting..." + exit 2 + fi + + echo "Building packages for $python ..." + + tag=$(get_latest_tag) + + $hg update -C ${tag} &> /dev/null + + $python setup.py clean &> /dev/null + $python setup.py build &> /dev/null + $python setup.py bdist_egg &> /dev/null + $python setup.py sdist --formats=bztar,gztar,zip &> /dev/null + + $hg update -C &> /dev/null +} + +print_help() { + echo "usage: $COMMAND [options] machines" + echo "options:" + echo " -p=PYTHON specify python binary to use" + echo " -v print version and exit" + echo " -h print help and exit" +} + +parse_options() { + PYTHON="python2.6" + + while getopts "p:vh-" OPT ; do + case $OPT in + p) + PYTHON="$OPTARG" ;; + v) + echo "$COMMAND $VERSION" + exit 0 ;; + h) + print_help + exit 0 ;; + esac + done + + shift $(($OPTIND - 1)) +} + +main() { + parse_options "$@" + + make_packages "$PYTHON" +} + +### Main + +COMMAND=$(basename $0) + +main "$@" + +#n End of File From commits-noreply at bitbucket.org Thu Feb 25 15:25:11 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:11 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 4085d81f3d90: Fixed action for --cover-show-missing option Message-ID: <20100225142511.E0A9E7EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267105185 -36000 # Node ID 4085d81f3d90c0dec3b26c3a577b2176e9dd43af # Parent b7d4ac6dbbefa9d2163805f15902817d50a1df7e Fixed action for --cover-show-missing option --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -23,7 +23,7 @@ def pytest_addoption(parser): group.addoption('--cover-directory', action='store', default=None, dest='directory', help='Directory for the reports (html / annotate results) defaults to ./coverage') - group.addoption('--cover-show-missing', action='store', default=None, + group.addoption('--cover-show-missing', action='store_true', default=False, dest='show_missing', help='Show missing files') group.addoption('--cover-ignore-errors', action='store', default=None, From commits-noreply at bitbucket.org Thu Feb 25 15:25:14 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:14 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 68ab9b202d7b: Fixed example usage in pypi description Message-ID: <20100225142514.89EB27EF29@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267106256 -36000 # Node ID 68ab9b202d7b795254f040542c6d0b6f3bb6adb6 # Parent f2559946de082c2d7a588068927f4cbeebfdd524 Fixed example usage in pypi description --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ Usage after installation (e.g. via ``pip install pytest-coverage``) you can type:: - py.test --cover-action=report + py.test --cover-report=report to enable coverage. Use ``py.test --help`` to display other options. """ @@ -17,7 +17,7 @@ from setuptools import setup setup( name="pytest-coverage", - version="0.2", + version="0.2.1", description='py.test coverage plugin', long_description=__doc__, license='MIT', From commits-noreply at bitbucket.org Thu Feb 25 15:25:12 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:12 +0000 (UTC) Subject: [py-svn] pytest-coverage commit b3978e930a7b: Bump version -> 0.2 Message-ID: <20100225142512.1F6E97EF28@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267105440 -36000 # Node ID b3978e930a7be474e4dfd67bab0afe2345d3f2da # Parent 4085d81f3d90c0dec3b26c3a577b2176e9dd43af Bump version -> 0.2 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import setup setup( name="pytest-coverage", - version="0.1", + version="0.2", description='py.test coverage plugin', long_description=__doc__, license='MIT', From commits-noreply at bitbucket.org Thu Feb 25 15:25:14 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:14 +0000 (UTC) Subject: [py-svn] pytest-coverage commit f2559946de08: Added tag 0.2 for changeset b3978e930a7b Message-ID: <20100225142514.205D87EF1D@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267105442 -36000 # Node ID f2559946de082c2d7a588068927f4cbeebfdd524 # Parent b3978e930a7be474e4dfd67bab0afe2345d3f2da Added tag 0.2 for changeset b3978e930a7b --- a/.hgtags +++ b/.hgtags @@ -1,1 +1,2 @@ 8e083df63e4386453cf880f0186766b6d20f2c49 1.0 +b3978e930a7be474e4dfd67bab0afe2345d3f2da 0.2 From commits-noreply at bitbucket.org Thu Feb 25 15:25:01 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:01 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 1f836abc3a4f: Added tag 0.2.2 for changeset 96ecb90a1f36 Message-ID: <20100225142501.3302A7EF0A@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267107303 -36000 # Node ID 1f836abc3a4f7387ef828ba14da79e6e9c1f558c # Parent 96ecb90a1f3646debe2d0b5e783618a29ced4a37 Added tag 0.2.2 for changeset 96ecb90a1f36 --- a/.hgtags +++ b/.hgtags @@ -1,3 +1,4 @@ 8e083df63e4386453cf880f0186766b6d20f2c49 1.0 b3978e930a7be474e4dfd67bab0afe2345d3f2da 0.2 9faf4bae9b48724bb80b6103ae2369cf4e37ad58 0.2.1 +96ecb90a1f3646debe2d0b5e783618a29ced4a37 0.2.2 From commits-noreply at bitbucket.org Thu Feb 25 15:25:03 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:03 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 4a076679b0cb: Bump version -> 0.2.2 Message-ID: <20100225142503.9664B7EF0C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267107394 -36000 # Node ID 4a076679b0cbb7e0d1aae66a328f6a175c2b3768 # Parent 1f836abc3a4f7387ef828ba14da79e6e9c1f558c Bump version -> 0.2.2 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import setup setup( name="pytest-coverage", - version="0.2.1", + version="0.2.2", description='py.test coverage plugin', long_description=__doc__, license='MIT', From commits-noreply at bitbucket.org Thu Feb 25 15:25:08 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:08 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 2d667c923279: Added tag 0.2.2 for changeset 4a076679b0cb Message-ID: <20100225142508.2EE4F7EF12@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267107404 -36000 # Node ID 2d667c92327901babf3ecfcdd78394876ae4e414 # Parent 4a076679b0cbb7e0d1aae66a328f6a175c2b3768 Added tag 0.2.2 for changeset 4a076679b0cb --- a/.hgtags +++ b/.hgtags @@ -2,3 +2,5 @@ 8e083df63e4386453cf880f0186766b6d20f2c49 b3978e930a7be474e4dfd67bab0afe2345d3f2da 0.2 9faf4bae9b48724bb80b6103ae2369cf4e37ad58 0.2.1 96ecb90a1f3646debe2d0b5e783618a29ced4a37 0.2.2 +96ecb90a1f3646debe2d0b5e783618a29ced4a37 0.2.2 +4a076679b0cbb7e0d1aae66a328f6a175c2b3768 0.2.2 From commits-noreply at bitbucket.org Thu Feb 25 15:25:11 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:11 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 93959d2603d5: Added tag 0.2.2 for changeset 111ba18695c4 Message-ID: <20100225142511.3BDDE7EF1C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267107857 -36000 # Node ID 93959d2603d5a3cf5919e8d5f07275295d170ab8 # Parent 111ba18695c42603c387db824ff301b0e7d4a6ed Added tag 0.2.2 for changeset 111ba18695c4 --- a/.hgtags +++ b/.hgtags @@ -4,3 +4,5 @@ 9faf4bae9b48724bb80b6103ae2369cf4e37ad58 96ecb90a1f3646debe2d0b5e783618a29ced4a37 0.2.2 96ecb90a1f3646debe2d0b5e783618a29ced4a37 0.2.2 4a076679b0cbb7e0d1aae66a328f6a175c2b3768 0.2.2 +4a076679b0cbb7e0d1aae66a328f6a175c2b3768 0.2.2 +111ba18695c42603c387db824ff301b0e7d4a6ed 0.2.2 From commits-noreply at bitbucket.org Thu Feb 25 15:25:10 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:10 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 111ba18695c4: Makefile: output coverage report to terminal Message-ID: <20100225142510.A5B2C7EF18@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267107850 -36000 # Node ID 111ba18695c42603c387db824ff301b0e7d4a6ed # Parent 45329429a664576b29f70da7b329a98b1f7d7b54 Makefile: output coverage report to terminal --- a/Makefile +++ b/Makefile @@ -22,6 +22,5 @@ tests: --pastebin=all \ --report=skipped \ --cover=pytest_coverage \ - --cover-report=html \ - --cover-directory=coverage \ + --cover-report=report \ --cover-show-missing From commits-noreply at bitbucket.org Thu Feb 25 15:25:09 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 14:25:09 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 45329429a664: Merged with 96f47169f745 Message-ID: <20100225142509.9FB6F7EF14@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267107771 -36000 # Node ID 45329429a664576b29f70da7b329a98b1f7d7b54 # Parent 96f47169f7458a1d29dc3a6c8a89c382df53e7c6 # Parent 2d667c92327901babf3ecfcdd78394876ae4e414 Merged with 96f47169f745 --- a/test_pytest_coverage.py +++ b/test_pytest_coverage.py @@ -12,8 +12,12 @@ def test_functional(testdir): def test_whatever(): pass """) - result = testdir.runpytest('--cover-report=report') + result = testdir.runpytest('--cover=test_functional --cover-report=report') assert result.ret == 0 + print + print type(result.stdout) + print repr(result.stdout) + print assert result.stdout.fnmatch_lines([ '*Processing Coverage*', 'test_functional*4*3*75%*', @@ -30,7 +34,6 @@ def test_coverage_is_not_imported(testdi assert result.stdout.fnmatch_lines([ '*1 passed*', ]) - #print result.stdout.str() def test_cover_package(testdir): testdir.makepyfile(""" @@ -39,7 +42,8 @@ def test_cover_package(testdir): def test_whatever(): pass """) - result = testdir.runpytest('--cover=test_cover_package',) + result = testdir.runpytest('--cover=test_cover_package', + '--cover-report=report') assert result.ret == 0 assert result.stdout.fnmatch_lines([ '*Processing Coverage*', --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -23,7 +23,7 @@ def pytest_addoption(parser): group.addoption('--cover-directory', action='store', default=None, dest='directory', help='Directory for the reports (html / annotate results) defaults to ./coverage') - group.addoption('--cover-show-missing', action='store', default=None, + group.addoption('--cover-show-missing', action='store_true', default=False, dest='show_missing', help='Show missing files') group.addoption('--cover-ignore-errors', action='store', default=None, From commits-noreply at bitbucket.org Thu Feb 25 20:34:53 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 19:34:53 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 7df573848ebe: Trying to move child process coverage functionality into a py.test helper function to be called by python scripts being tested that are run externally Message-ID: <20100225193453.6EB477EE85@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267126481 -36000 # Node ID 7df573848ebeee6d52400e97c8c74e136f34585d # Parent 93959d2603d5a3cf5919e8d5f07275295d170ab8 Trying to move child process coverage functionality into a py.test helper function to be called by python scripts being tested that are run externally --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -5,7 +5,21 @@ Original code by Ross Lawley. Requires Ned Batchelder's excellent coverage: http://nedbatchelder.com/code/coverage/ """ -import sys, py +import sys +import atexit + +def pytest_namespace(): + return {"cover_child": cover_child} + +def cover_cleanup(cover): + cover.stop() + cover.save() + +def cover_child(): + from coverage import coverage + cover = coverage() + atexit.register(cover_cleanup, cover) + cover.start() def pytest_addoption(parser): group = parser.getgroup('Coverage options') From commits-noreply at bitbucket.org Thu Feb 25 21:19:06 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 20:19:06 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 2faf4a275eb9: Backed out changeset 7df573848ebe Message-ID: <20100225201906.05E7F7EF0C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267129131 -36000 # Node ID 2faf4a275eb9071b2a1936cf19d19531235739ea # Parent 7df573848ebeee6d52400e97c8c74e136f34585d Backed out changeset 7df573848ebe * No clear path to adding generic features to enable coverage of externally executed (via subprocess or similar) scripts. --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -5,21 +5,7 @@ Original code by Ross Lawley. Requires Ned Batchelder's excellent coverage: http://nedbatchelder.com/code/coverage/ """ -import sys -import atexit - -def pytest_namespace(): - return {"cover_child": cover_child} - -def cover_cleanup(cover): - cover.stop() - cover.save() - -def cover_child(): - from coverage import coverage - cover = coverage() - atexit.register(cover_cleanup, cover) - cover.start() +import sys, py def pytest_addoption(parser): group = parser.getgroup('Coverage options') From commits-noreply at bitbucket.org Thu Feb 25 22:01:54 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 21:01:54 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 951db18315b4: I like imports on single lines :) Message-ID: <20100225210154.9DD8D7EE70@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267131667 -36000 # Node ID 951db18315b48dd8c5bf545f09bd1d0aa9cfda6d # Parent 2faf4a275eb9071b2a1936cf19d19531235739ea I like imports on single lines :) --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -5,7 +5,10 @@ Original code by Ross Lawley. Requires Ned Batchelder's excellent coverage: http://nedbatchelder.com/code/coverage/ """ -import sys, py + +import sys + +from coverage import coverage def pytest_addoption(parser): group = parser.getgroup('Coverage options') From commits-noreply at bitbucket.org Thu Feb 25 22:01:56 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Feb 2010 21:01:56 +0000 (UTC) Subject: [py-svn] pytest-coverage commit 55a0426c3999: Added 'coverage' funcarg to our plugin object DoCoverage. Message-ID: <20100225210156.DA8D47EF01@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-coverage # URL http://bitbucket.org/prologic/pytest-coverage/overview/ # User prologic # Date 1267131698 -36000 # Node ID 55a0426c39999fb4f88470e4cd1c3593e2e9c16d # Parent 951db18315b48dd8c5bf545f09bd1d0aa9cfda6d Added 'coverage' funcarg to our plugin object DoCoverage. --- a/pytest_coverage.py +++ b/pytest_coverage.py @@ -41,20 +41,25 @@ def pytest_configure(config): config.pluginmanager.register(DoCoverage(config), "coverage") class DoCoverage: + def __init__(self, config): self.config = config - import coverage - self.cov = coverage.coverage() - self.cov.use_cache(0) # Do not cache any of the coverage.py stuff - self.cov.start() + + self._coverage = coverage() + self._coverage.use_cache(False) + self._coverage.start() + + def pytest_funcarg__coverage(self, request): + return self._coverage def pytest_terminal_summary(self, terminalreporter): + self._coverage.stop() + self._coverage.save() + config = terminalreporter.config tw = terminalreporter._tw tw.sep('-', 'coverage') tw.line('Processing Coverage...') - self.cov.stop() - self.cov.save() # Get the configurations config = terminalreporter.config @@ -87,8 +92,9 @@ class DoCoverage: # report_args['omit_prefixes'] = omit_prefixes if report_type == 'report': - self.cov.report(show_missing=show_missing, file=tw, **report_args) + self._coverage.report(show_missing=show_missing, file=tw, + **report_args) elif report_type == 'annotate': - self.cov.annotate(directory=directory, **report_type) + self._coverage.annotate(directory=directory, **report_type) elif report_type == 'html': - self.cov.html_report(directory=directory, **report_args) + self._coverage.html_report(directory=directory, **report_args) From commits-noreply at bitbucket.org Sun Feb 28 20:38:03 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 28 Feb 2010 19:38:03 +0000 (UTC) Subject: [py-svn] pytest-codecheckers commit 6309ddd6bf42: make pep8 show all errors Message-ID: <20100228193803.E2F2C7EEF8@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project pytest-codecheckers # URL http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/overview/ # User Ronny Pfannschmidt # Date 1267385688 -3600 # Node ID 6309ddd6bf429cc2eb685a777fd8242c34825ed1 # Parent a29b2b0766200fe782a6798d326b37df301d7fa6 make pep8 show all errors --- a/codecheckers/pep.py +++ b/codecheckers/pep.py @@ -11,9 +11,10 @@ class PyTestChecker(pep8.Checker): def check_file(path): pep8.process_options(['pep8', - #taken from moin + # ignore list taken from moin '--ignore=E202,E221,E222,E241,E301,E302,E401,E501,E701,W391,W601,W602', '--show-source', + '--repeat', 'dummy file', ]) checker = PyTestChecker(str(path))