diff --git a/doc/conf.py.in b/doc/conf.py.in index 71ff3e3700542181c8e1666e9fb01328bd9623ea..79fcf5ce42cb4264bda10c693fa8ddb46bbb7859 100644 --- a/doc/conf.py.in +++ b/doc/conf.py.in @@ -253,6 +253,9 @@ intersphinx_mapping = {'python': ('@PYTHON_DOC_URL@', None), # -- ProMod3 specific configuration -------------------------------------------- extlinks = {'py_docs' : ('@PYTHON_DOC_URL@/%s', 'Python documentation')} +# The _nameattr is a bit ugly: we want to have __name__ formatted as Python +# attribute but Sphinx does not go with calling :attr: inside extlinks. To keep +# the Python url prefix, we define sth here. rst_epilog = """ .. |project| replace:: %s .. |cmake| replace:: CMake @@ -267,6 +270,7 @@ rst_epilog = """ .. |git| replace:: Git .. |C++| replace:: C++ .. _ost_s: http://www.OpenStructure.org +.. _nameattr: @PYTHON_DOC_URL@/library/__main__.html """ % project # in some versions of sphinx, doctest invokes doctest_path AFTER executing code doctest_global_setup = """ diff --git a/doc/contributing.rst b/doc/contributing.rst index 869300d8702b2334086fa46095eebe7cfa8eac00..e83104db1a5c72517b334c929b4f8bcde1623fce 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -269,7 +269,6 @@ version control, create a couple of files which are always needed. .. code-block:: console $ touch sidechains/pymod/__init__.py - $ echo "FOO" >> sidechains/doc/index.rst $ echo ":mod:\`~promod3.sidechains\` - ProMod3 side chain optimiser" >> sidechains/doc/index.rst $ echo "================================================================================" >> sidechains/doc/index.rst $ @@ -330,7 +329,7 @@ a couple of examples around in this repository. Here is the most basic :file:`CMakeLists.txt`: .. code-block:: cmake - :linenos: + :linenos: set(SIDECHAINS_PYMOD __init__.py @@ -348,8 +347,8 @@ The final step towards |cmake| is to register your module's directory in the top level :file:`CMakeLists.txt`: .. code-block:: cmake - :linenos: - :emphasize-lines: 80 + :linenos: + :emphasize-lines: 80 #------------------------------------------------------------------------------- # Author: Bienchen @@ -481,14 +480,90 @@ a new configuration script. The following example assumes |fedora| 19. From this point, :command:`make` should work and you could start adding your files to the repository using ``git add``. +Up to now, we did not cover the :file:`tests` branch of a new module. But its +good practice to develop new functionality along tests and that right from the +beginning. At some point, new code needs testing anyway to see if it does what +it should, so just do this by writing unit tests. Test sources are stored in +files with a prefix :file:`test_` and usually come per submodule instead of +sporting a single monolithic :file:`test_sidechains.py`. + +|python| code is evaluated using its own +:py_docs:`unit testing framework <library/unittest.html>` with a little help +from |ost_s|_. The basic scheme is to import your module, subclass +:class:`unittest.TestCase` and make the whole file runnable as script using the +most common |nameattr|_ attribute. A file :file:`tests/test_something.py` could +look like this, carrying a single test case: + +.. testcode:: promod3unittest + :hide: + + import unittest + + class something(): + @staticmethod + def Else(): + return 1 + + class SomethingTests(unittest.TestCase): + def testFileExistsFalse(self): + self.assertEquals(something.Else(), 1) + + if __name__ == "__builtin__": + suite = unittest.TestLoader().loadTestsFromTestCase(SomethingTests) + unittest.TextTestRunner().run(suite) + +.. code-block:: python + :linenos: + + import unittest + from promod3.sidechains import something + + class SomethingTests(unittest.TestCase): + def testFileExistsFalse(self): + self.assertEquals(something.Else(), 1) + + if __name__ == "__main__": + from ost import testutils + testutils.RunTests() + +To hook up your tests with ``make codetest`` (and to create a +``test_something.py_run`` target), everything has to be introduced to |cmake|. +First, tell |cmake| to search :file:`tests` for a :file:`CMakeLists.txt` file +by extending the list of sub-directories in :file:`sidechains/CMakeLists.txt`: + +.. code-block:: cmake + :linenos: + + add_subdirectory(pymod) + add_subdirectory(doc) + add_subdirectory(tests) + +Then fill :file:`sidechains/tests/CMakeLists.txt` with your new test script and +``make`` will recognise the changes next time it is run and fix the rest for +you. + +.. code-block:: cmake + :linenos: + + set(SIDECHAINS_UNIT_TESTS + test_something.py + ) + + promod3_unittest(MODULE sidechains SOURCES "${SIDECHAINS_UNIT_TESTS}") + +Now tests should be available by ``make check``, ``make codetest`` and +``make test_something.py_run``. + .. _restructuredtext: http://docutils.sourceforge.net/rst.html .. |fedora| replace:: Fedora - +.. |nameattr| replace:: :attr:`__name__` .. LocalWords: cmake hotfix doctest linkcheck rebase BRANCHNAME rebasing py .. LocalWords: CMakeLists txt rst pymod init submodule src restructuredtext .. LocalWords: makefiles formatters Changelog codetest promod sidechains io .. LocalWords: mkdir linenos subdirectory abrv emphasize CXX GNUCXX gcc fno .. LocalWords: ARGS endif OPTIMIZE LIBEXEC Wno DIRS dirs subdirs config dbg -.. LocalWords: changelog Optimized DOPTIMIZE gitignore cd conf +.. LocalWords: changelog Optimized DOPTIMIZE gitignore cd conf subtree attr +.. LocalWords: unittest TestCase nameattr testcode staticmethod builtin +.. LocalWords: SomethingTests testFileExistsFalse testutils RunTests