Skip to content
Snippets Groups Projects
Commit a23e5a71 authored by Bienchen's avatar Bienchen
Browse files

Documentation for action tests

parent 3d21d364
No related branches found
No related tags found
No related merge requests found
:mod:`test_actions.ActionTestCase` - Testing Actions
================================================================================
.. module:: test_actions
.. currentmodule:: test_actions
This module is **not** part of the |project| binary distribution. That is the
productive bit running to produce models. It is only part of the source
distribution intended to help developing |project|. Basically it supports you
......
......@@ -268,7 +268,8 @@ extlinks = {'py_docs' : ('@PYTHON_DOC_URL@/%s',
'OpenStructure 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.
# the Python url prefix, we define sth here. Same holds for _mainattr. But this
# time instead of printing '__name__' we want to see '__main__'.
rst_epilog = """
.. |project| replace:: %s
.. |cmake| replace:: CMake
......@@ -284,6 +285,7 @@ rst_epilog = """
.. |C++| replace:: C++
.. _ost_s: http://www.OpenStructure.org
.. _nameattr: @PYTHON_DOC_URL@/library/__main__.html
.. _mainattr: @PYTHON_DOC_URL@/library/__main__.html
.. |pep8| replace:: PEP 8
.. _pep8: https://www.python.org/dev/peps/pep-0008/
""" % project
......
......@@ -270,6 +270,8 @@ http://sphinx-doc.org/markup/inline.html
If you write new functionality for |project|, or fix bugs, feel free to extend
the Changelog. It will be automatically pulled into the documentation.
.. _how-to-start-your-own-module:
--------------------------------------------------------------------------------
How To Start Your Own Module
--------------------------------------------------------------------------------
......@@ -640,6 +642,142 @@ you.
Now tests should be available by ``make check``, ``make codetest`` and
``make test_something.py_run``.
--------------------------------------------------------------------------------
How To Start Your Own Action
--------------------------------------------------------------------------------
In |project| we call scripts/ programs 'actions'. They are started by a
launcher found in your staging directory at :file:`stage/bin/pm`. This little
guy helps keeping the shell environment in the right mood to carry out your
job. So usually you will start an action by
.. code-block:: console
$ stage/bin/pm help
To start your own action, follow :ref:`how-to-start-your-own-module` until
creating a directory structure for a new module. Also **do** go for a dedicated
branch for action-development. There you can produce intermediate commits while
other branches stay clean in case you have to do some work there which needs to
get public.
After preparing your repository its time to create a file for the action. That
is a bit different than for modules. Assuming we are sitting in the
repository's root:
.. code-block:: console
$ touch action/pm-awesome-action
$ chmod +x action/pm-awesome-action
Two things are important here: actions are prefixed with :file:`pm-`, so they
are recognised by the :file:`pm` launcher. Secondly, action files need to be
executable, which does not propagate if you do it **after** the first call to
``make``.
To get the new action recognised by ``make`` to be placed in
:file:`stage/libexec/promod3`, it has to be registered with |cmake| in
:file:`actions/CMakeLists.txt`:
.. code-block:: cmake
:linenos:
add_custom_target(actions ALL)
add_subdirectory(tests)
pm_action_init()
pm_action(pm-build-rawmodel actions)
pm_action(pm-help actions)
pm_action(pm-awesome-action actions)
Just add your action with its full filename with a call to
:cmake:command:`pm_action` at the end of the file.
Before coding your action, lets set up unit tests for it. Usually when adding
features, you will immediately try them, check that everything works as
intended, etc.. |project| helps you automatising those tests so its rather easy
to check later, if code changes break anything. Start with a file
:file:`actions/tests/test_action_awesome.py`:
.. testcode:: contribute_action
:hide:
import sys
sys.dont_write_bytecode = True
import test_actions
import unittest
class DoAwesomeActionTests(test_actions.ActionTestCase):
def __init__(self, *args, **kwargs):
test_actions.ActionTestCase.__init__(self, *args, **kwargs)
self.pm_bin = os.path.join(os.getcwd(), os.pardir, 'stage', 'bin',
'pm')
self.pm_action = 'help'
def testExit0(self):
self.RunExitStatusTest(0, list())
if __name__ == "__builtin__":
import os
suite = unittest.TestLoader().loadTestsFromTestCase(DoAwesomeActionTests)
unittest.TextTestRunner().run(suite)
.. code-block:: python
:linenos:
import sys
# this is needed so there will be no test_actions.pyc created in the source
# directory
sys.dont_write_bytecode = True
import test_actions
class AwesomeActionTests(test_actions.ActionTestCase):
def __init__(self, *args, **kwargs):
test_actions.ActionTestCase.__init__(self, *args, **kwargs)
self.pm_action = 'awesome'
def testExit0(self):
self.RunExitStatusTest(0, list())
if __name__ == "__main__":
from ost import testutils
testutils.RunTests()
Please note that for actions we are using
:class:`test_actions.ActionTestCase <test_actions>` instead of
:class:`unittest.TestCase`. Since testing has a lot in common for different
actions, we decided to put up a little wrapper around this subject. See the
documentation of :class:`ActionTestCase <test_actions>` for more information.
Now its time to fill your action with code. Instead of reading a lot more of
explanations, it should be easy to go by examples from the :file:`actions`
directory. There are only two really important points:
* No shebang line (``#! /usr/bin/python``) in your action! Also no
``#! /usr/bin/env python`` or anything like this. This may lead to funny side
effects, like calling a |python| interpreter from outside a virtual
environment or a different version |ost_s|. Basically it may mess up the
environment your action is running in. Actions are called by :file:`pm`,
that's enough to get everything just right.
* The action of your action happens in the |mainattr|_ branch of the script.
Your action will have own function definitions, variables and all the bells
and whistles. Hiding behind |mainattr|_ keeps everything separated and makes
things easier when it gets to debugging. So just after
.. code-block:: python
import alot
def functions_specific_to_your_action(...):
if __name__ == "__main__":
<put together what your action should do here>
start putting your action together.
--------------------------------------------------------------------------------
Third Party Contributions (License Issues)
--------------------------------------------------------------------------------
......@@ -674,6 +812,7 @@ contributions to web pages using |project|.
.. |fedora| replace:: Fedora
.. |nameattr| replace:: :attr:`__name__`
.. |mainattr| replace:: :attr:`__main__`
.. |pylint| replace:: Pylint
.. _pylint: http://www.pylint.org
.. LocalWords: cmake hotfix doctest linkcheck rebase BRANCHNAME rebasing py
......@@ -684,6 +823,8 @@ contributions to web pages using |project|.
.. LocalWords: changelog Optimized DOPTIMIZE gitignore cd conf subtree attr
.. LocalWords: unittest TestCase nameattr testcode staticmethod builtin cp
.. LocalWords: SomethingTests testFileExistsFalse testutils RunTests DQMEAN
.. LocalWords: pre API inline CMake hh ProMod Bienchen OST OPENSTRUCTURE
.. LocalWords: pre API inline CMake hh ProMod Bienchen OST OPENSTRUCTURE os
.. LocalWords: mol alg conop QMEAN KIC eigen eigenvectors Lapack rawmodel
.. LocalWords: OpenStructure ost pylint
.. LocalWords: OpenStructure ost pylint chmod sys pyc dont bytecode args
.. LocalWords: AwesomeActionTests ActionTestCase kwargs testExit getcwd
.. LocalWords: RunExitStatusTest DoAwesomeActionTests pardir mainattr alot
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment