ruby
How to make the simplest unittests in Python
0Testing your code is nearly a requirement (even more so in Ruby). Unittests are now the most vital elements for evaluating the quality/viability of a project.
I was a little jealous of Ruby where you don’t have so much to write to implement unittests. Here is a simple example:
1 2 3 4 5 6 7 8 9 | require "mymodule" require "test/unit" class TestMyModule < Test::Unit::TestCase def test_simple assert_equal(1, 1 ) end end |
Now, using Nose, you can get even shorter code. If you do standard Python projects, you’ll use a setup.py file. To use nose, you do not even need to specify the path where to find the tests, just add two lines (tests_require and test_suite) to call nosetest:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | from setuptools import setup, find_packages import sys, os import mymodule version = mymodule.__version__ setup(name='myproject', version=version, description="Module to display blah blah blah.", long_description=""" """, classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers keywords='mymodule foobar', author='Luc Stepniewski', author_email='[email protected]', url='', license='GPL', packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), include_package_data=True, tests_require='nose', test_suite='nose.collector', zip_safe=False, install_requires=[ # -*- Extra requirements: -*- 'simplejson', ], entry_points=""" # -*- Entry points: -*- [console_scripts] mymodule = mymodule.mainmodule:main """, ) |
Now, to add tests, you just have to create a directory named tests (in the root of your project, where your setup.py resides, and then add a python file()s. No need to add a __init__.py to set the directory as a module. Now just add simple python files, like my-tests.py :
1 2 3 4 5 6 7 8 9 10 11 | import mymodule class TestAstInfoCli(object): def setup(self): pass def teardown(self): pass def test_annuaire_inverse(self): assert 1 == 1 |
As you can see, no need to import anything for doing unittests, not even the standard python unittest module! That’s better than ruby! The downside of this is that nose is an ‘external’ package, so you’ll have to install it first (or set it as a dependency in your setup.py file, as shown above).
If you don’t use a setup.py, you can call nose directly from the command line, with ‘nosetest’.
Now, let’s find an equivalent to the really cool rspec ruby module!
Puppet: Files found in modules without specifying ‘modules’ in file path will be deprecated in the next major release
0DEPRECATION NOTICE: Files found in modules without specifying ‘modules’ in file path will be deprecated in the next major release.
If you get this warning in your puppet logs, you should take action (only if you don’t have any Puppet agent with a version <= 0.24) and modify all you references to file resources.
For example, if you have a module named 'ssh', normally, up to puppet 0.25 you would reference a file to it as:
source => ["puppet:///ssh/authorized_keys",]
But now, you need to insert a ‘module’ identifier in between like this:
source => ["puppet:///modules/ssh/authorized_keys",]
Just a small note: It seems that the templates do not need any modification.
Synchronization methods of a file with Puppet
0Usually, to synchronize a file with remote hosts, using puppet, one would use the following pattern:
file { "/etc/init.d/pvfs2-server":
owner => root, group => root,
mode => 755,
source => "puppet:///files/pvfs2-server"
}
(using “source” to copy data as-is, and using “template(“filename”) to use a template structure as data).
Or, if one wishes to directly set the content of the target file:
file { "/etc/init.d/pvfs2-server":
owner => root, group => root,
mode => 755,
source => "puppet:///files/pvfs2-server"
}
Please note that on the first line, for example ‘file { “/etc/mpd.conf”:’), the “/etc/mpd.conf” is a merge of two functionalities/concepts: Usually, the syntax is clear and simple:
file { mon_fichier_mpd_conf:
path => "/etc/mpd.conf",
[...]
}
The first line is about the resource description. Its goal is to be able to reference to it a little later from another resources (Notify[], etc.). By putting directly the file path and name (I think it’s identified as a filename and not as a description because there are quotes, or maybe it’s because it begins with a slash?) you mege the “path” attribute with its description.
On the other end, we’ll not be able to reference to it later, if you need to.
You may also need to synchronize a file that is not present in the repository (puppet:///files/*). That usually happens, for example, when that file is regenerated by an external program or an external action (like /etc/passwd).
file {"/etc/passwd":
owner => root, group => root, mode => 644,
content => file("/etc/passwd")
}
Troll of the day: Why Ruby sucks and why Python rocks!
0I found a nicely written article about the problems with Ruby, written by a Ruby user, and why he found Python to be really good. There’s even a quote about Twisted!
And, there are a bunch of things available to a Python guy that Ruby just can’t compete with that are of particular interest to me. Two that come to mind immediately are Twisted and Stackless Python. The former was used by others at TurnTide for creating a really powerful SMTP testing tool and the latter was used by TurnTide’s competitor IronPort to build one of the industry’s best MTAs.
I didn’t knew that IronPort was done in Python, even in Stackless Python!









Recent Comments