holger krekel avatar holger krekel committed ecd4bc8

update

Comments (0)

Files changed (14)

6/test/conftest.py

         help="run tests that require network access",
         action="store_true", default=False)
 
+def pytest_report_header(config):
+    import myscan
+    return "myscan imported from: %s" % myscan.__file__
+
 class MySetup:
     def __init__(self, request):
         self.tmpdir = request.getfuncargvalue("tmpdir")

7/test/conftest.py

         help="run tests that require network access",
         action="store_true", default=False)
 
+def pytest_report_header(config):
+    import myscan
+    return "myscan imported from: %s" % myscan.__file__
+
+
 class MySetup:
     def __init__(self, request):
         self.tmpdir = request.getfuncargvalue("tmpdir")
 
 [testenv]
 commands=
-  py.test -rfsxX []
+  py.test --checkremote -rfsxX []
+import subprocess
+import py
+
+tdir = py.path.local("/tmp/pytest-ep2010")
+
+if tdir.check():
+    tdir.remove()
+
+base = py.path.local()
+out = py.process.cmdexec("hg manifest")
+for line in out.split("\n"):
+    p = py.path.local(line)
+    assert p.check(), p
+    target = tdir.join(p.relto(base))
+    target.dirpath().ensure(dir=1)
+    if p != base:
+        print "copying", p, "to", target
+        p.copy(target)
+
+print "created", tdir
+zipname = py.path.local("%s.zip" % tdir.basename)
+if zipname.check():
+    zipname.remove()
+tdir.dirpath().chdir()
+py.process.cmdexec("zip -r %s %s" % (zipname, tdir.basename))
+print "created", zipname

old3/myscan/__init__.py

-#

old3/myscan/config.py

-from ConfigParser import ConfigParser
-
-class Config:
-    def __init__(self, path):
-        path = str(path)
-        f = open(path)
-        parser = ConfigParser()
-        parser.readfp(f)
-        f.close()
-        parser.read(path)
-        self.parser = parser
-        self.extensions = self._getopt("extensions", ".txt").split()
-        self.urlprefixes = []
-        for prefix in self._getopt("urlprefixes", "http https").split():
-            if not prefix.endswith("://"):
-                prefix += "://"
-            self.urlprefixes.append(prefix)
-   
-    def _getopt(self, name, default):
-        if self.parser.has_option("myscan", name):
-            return self.parser.get("myscan", name)
-        return default

old3/myscan/scanner.py

-import urllib
-
-class Scanner:
-    def __init__(self, config):
-        self.config = config
-
-    def extract_urls(self, path):
-        urls = []
-        for line in path.readlines():
-            line = line.strip()
-            for urlprefix in self.config.urlprefixes:
-                if line.startswith(urlprefix):
-                    urls.append(line)
-        return urls
-
-    def checkremote(self, path):
-        checked = []
-        for url in self.extract_urls(path):
-            print ("checking: %s" %(url))
-            f = urllib.urlopen(url)
-            f.close()
-            checked.append(url)
-        return checked 
-            
-            

old3/test/__init__.py

-#

old3/test/conftest.py

-from myscan.config import Config
-
-class MySetup:
-    def __init__(self, request):
-        # internally call the ``tmpdir`` funcarg factory
-        self.tmpdir = request.getfuncargvalue("tmpdir")
-
-    def makeconfig(self, **kwargs):
-        p = self.tmpdir.join("test.ini")
-        lines = ["[myscan]"]
-        for key, value in kwargs.items():
-            lines.append("%s = %s" % (key, value))
-        p.write("\n".join(lines))
-        return Config(str(p))
-
-def pytest_funcarg__mysetup(request):
-    return MySetup(request)
-

old3/test/test_myscan.py

-import py
-from myscan.scanner import Scanner
-from myscan.config import Config
-
-def test_config_fails_on_non_existing():
-    py.test.raises(IOError, 'Config("not-existing")')
-
-def test_config_defaults(tmpdir):
-    path = tmpdir.join("test.ini")
-    path.write("[myscan]")
-    config = Config(path)
-    assert config.extensions == ['.txt', ]
-    assert config.urlprefixes == ['http://', 'https://']
-
-def test_config_extensions(tmpdir):
-    path = tmpdir.join("test.ini")
-    path.write("[myscan]\nextensions = .txt .rst")
-    config = Config(path)
-    assert config.extensions == ['.txt', '.rst']
-
-def test_config_prefix(tmpdir):
-    path = tmpdir.join("test.ini")
-    path.write("[myscan]\nurlprefixes = http https custom")
-    config = Config(path)
-    assert config.urlprefixes == ['http://', 'https://', 'custom://']
-
-def test_extract_http(tmpdir):
-    path = tmpdir.join("test.ini")
-    path.write("[myscan]\nextensions = .txt")
-    config = Config(path)
-    scanner = Scanner(config)
-    p = tmpdir.join("example.txt")
-    p.write("xyz\n  http://codespeak.net")
-    l = scanner.extract_urls(p)
-    assert len(l) == 1
-    assert l == ['http://codespeak.net']
-
-def test_extract_custom_prefix(tmpdir):
-    path = tmpdir.join("test.ini")
-    path.write("[myscan]\nextensions = .rst\nurlprefixes = custom")
-    config = Config(path)
-    scanner = Scanner(config)
-    p = tmpdir.join("example.rst")
-    p.write("xyz\n  custom://codespeak.net")
-    l = scanner.extract_urls(p)
-    assert len(l) == 1
-    assert l == ['custom://codespeak.net']

Binary file modified.

pytest-advanced.txt

 
 slides and examples::
     
-    http://pytest.org/tutorial/pytest-II-ep2010.zip
+    http://pytest.org/tutorial/pytest-ep2010.zip
 
 me 
 ==
 
 slides and examples::
 
-    http://pytest.org/tutorial/pytest-II-ep2010.zip
+    http://pytest.org/tutorial/pytest-ep2010.zip
 
 Failure / Traceback Demo [0]
 ==============================
 
-exercise: go to directory ``pytest-basic/0`` and play with::
+exercise: go to directory ``0`` and play with::
 
     py.test test_failures.py 
 
 
     def pytest_generate_tests(metafunc) 
 
-hook is consulted.  It can generate multiple invocations
-for the same test functions, using different parameter
-sets. 
+hook is consulted.  It is a **metaprogramming** hook in that it operates
+on test functions and allows to generate multiple invocations using
+different parameter sets. 
 
 
 Example: re-running with multiple argument values
 Exercise: add some parametrization to myscan 
 ====================================================
 
-base files are in ``5/*`` directory. exercise::
+base files are in ``5/*`` directory. exercise is to:
 
 - add the above "multi" parametrizer to ``5/test/conftest.py``
 
-- add ``urlprefix`` parametrization to 
-  ``5/test/test_myscan.py::test_checkremote`` 
+- add an ``urlprefix`` parameter to 
+  ``5/test/test_myscan.py::test_checkremote``
+
+- add a "multi" marker aka 
+  ``@py.test.mark.multi(urlprefix=['http', 'https'])`` 
+  to the same test function and modify the test code 
+  to use the ``urlprefix`` parameter. 
 
 - run ``py.test --checkremote --collectonly`` 
 
 - run ``py.test --checkremote`` 
 
-bonus: add ``id=str(val)`` to the ``metafunc.addcall(...)`` 
-parameters. 
+
+py.test hooks and plugins 
+===================================================
+
+- pytest delegates its work to "hook functions"
+- hooks can be defined in plugins 
+- ``conftest.py`` files are considered as "local plugins" 
+- global plugins integrate via a setuptools-entry point
+- ``pytest_addoption(parser)`` is one such extension hook 
+
+local plugins: conftest.py 
+===============================
+
+- project specific test config and fixtures
+- auto-discovered in test directory or higher up 
+- can contain hook implementations 
+- can add command line options
+- can specify required plugins
+- best put into ``test/conftest.py`` 
+
+a simple config: ignoring directories
+==========================================
+
+:: 
+
+    # conftest.py
+    collect_ignore = ['data', 'test_myfile.py']
+
+this will prevent py.test from trying to collect
+the ``test_myfile.py`` test module or in the ``data`` 
+directory.  Paths are specified relative to 
+the directory which contains conftest.py 
+
+a simple default option: verbose 
+==========================================
+
+::
+
+    # conftest.py
+    pytest_option_verbose = True   # always run in verbose mode
+    pytest_option_exitfirst = True # always exit on first fail
+
+notes: 
+
+- use "py.test --help-config" to see other option names
+- limitation: not all options can be set like this
+
+a simple project specific hook
+==========================================
+
+if you want to customize the reporting header
+you can write the following function into your
+project-specific ``test/conftest.py`` file::
+
+    def pytest_report_header(config):
+        import myscan
+        return "myscan imported from: %s" % myscan.__file__
+
+**Exercise**: add it to ``5/test/conftest.py`` and run::
+
+    py.test 
+
+and look at the output. Also add option defaults 
+to the ``conftest.py`` as you like (see 
+``py.test --help-config`` for names you can use).
+
+break 
+===================================================
+
+.. image:: img/end_of_a_age_by_marikaz.jpg
+   :scale: 100
+   :align: left
+
+http://marikaz.deviantart.com/  CC 3.0 AN-ND
 
 Installing "global" plugins
 ===============================
 note: installed plugins are integrated automatically 
 through the setuptools' entrypoint mechanism.
 
-**do the above install now, please ...** 
+**Exercise: do the install and type:**::
+
+    py.test -h
 
 The distributed testing plugin 
 =========================================
 
-``pytest-xdist`` enables you to::
+The ``pytest-xdist`` plugin enables you to:
 
 - distribute tests to multiple local processes 
+- loop on failing test set until they pass 
 - distribute tests to multiple hosts
-- loop on failing tests 
 
 exercise: multi-CPU and looponfailing 
 ===================================================
 
-run the ``myscan`` tests in multiple subprocesses::
+run the ``myscan`` tests in directory ``6``::
 
     py.test -n3   
     py.test --checkremote -n3   
+    py.test -v --checkremote -n3  # look at output!
 
-run the ``myscan`` tests in looponfailing mode
+run the ``myscan`` tests in looponfailing mode::
 
     py.test --checkremote -f 
 
 and (in another window) edit the source code
 and artifically make a typo.  Look at what the
-"looponfailing" window does.  Then fix again. 
+"looponfailing" window does.  Then fix the typo
+and look again what happens in the windows.
 
 sending tests to multipe hosts 
 ===================================================
 - we would like to rather work in virtualenvs
 
 
-break 
-===================================================
-
-.. image:: img/end_of_a_age_by_marikaz.jpg
-   :scale: 100
-   :align: left
-
-http://marikaz.deviantart.com/  CC 3.0 AN-ND
 
 tox, the virtualenv test automation tool
 ============================================
 - ``tox`` is driven from a simple ``tox.ini`` file
 - allows to test against multiple interpreters at once
 
-**It is easy to integrate ``tox`` and py.test**
+**Tox makes it easy to integrate py.test**
 
 tox examples 
 ============================================
 
-let's visit the ``tox`` webpage and do some interactive
-examples:
+let's visit the ``tox`` webpage and walk through 
+some interactive examples::
 
     http://codespeak.net/tox
 
 ============================================
 
 let's look at a ``tox.ini`` configuration for our 
-``myscan`` project. 
+``myscan`` project in directory ``7``. 
 
-See also directory ``7``. 
+**Exercise**: 
+
+* install tox via ``pip install tox`` 
+* go to directory ``7`` and type ``tox`` 
+* edit and play with ``tox.ini`` and ``tox`` 
 
 scenarios, questions and solutions
 ======================================
 
 For what kind of scenarios do you want to write tests? 
 
-Let's do it together ... 
+Let's do it together ... (interactive session) 
 
 Summary 
 ===================================================

Binary file modified.

 
 slides and examples::
     
-    http://pytest.org/tutorial/pytest-I-ep2010.zip
+    http://pytest.org/tutorial/pytest-ep2010.zip
 
 me 
 ==
 
 slides and examples::
 
-    http://pytest.org/tutorial/pytest-I-ep2010.zip
+    http://pytest.org/tutorial/pytest-ep2010.zip
 
 Failure / Traceback Demo [0]
 ==============================
 
 questions, remarks? 
 
-py.test hooks and plugins 
-===================================================
-
-- pytest delegates its work to "hook functions"
-- hooks can be defined in plugins 
-- ``conftest.py`` files are considered as "local plugins" 
-- global plugins integrate via a setuptools-entry point
-- ``pytest_addoption(parser)`` is one such extension hook 
-
 Installing "global" plugins
 ===============================
 
 - inspect "html" directory created by figleaf
 - add an untested method to the app code and re-run
 
-local plugins: conftest.py 
-===============================
-
-- project specific test config and fixtures
-- auto-discovered in test directory or higher up 
-- can contain hook implementations 
-- can add command line options
-- can specify required plugins
-- best put into ``test/conftest.py`` 
-
-a simple config: ignoring directories
-==========================================
-
-:: 
-
-    # conftest.py
-    collect_ignore = ['data', 'test_myfile.py']
-
-this will prevent py.test from trying to collect
-the ``test_myfile.py`` test module or in the ``data`` 
-directory.  Paths are specified relative to 
-the directory which contains conftest.py 
-
-a simple default option: verbose 
-==========================================
-
-::
-
-    # conftest.py
-    pytest_option_verbose = True   # always run in verbose mode
-    pytest_option_exitfirst = True # always exit on first fail
-
-notes: 
-
-- use "py.test --help-config" to see other option names
-- limitation: not all options can be set like this
-
 quick discussion of advanced usages 
 ===================================================
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.