nose introduction

This post has several examples, and covers fixtures, test discovery, asserts, running options, and running unittests and doctests.

Nose’s tagline is “nose extends unittest to make testing easier”.
It’s is a fairly well known python unit test framework, and can run doctests, unittests, and “no boilerplate” tests.

It is a good candidate for a go-to test framework.

I think a smart developer should get familiar doctest, unittest, pytest, and nose. Then decide if one of those makes the most sense for them, or if they want to keep looking for features only found in other frameworks.
That’s of course the reason why I’m writing this series. So I guess that last bit goes without saying.

Contents

No boilerplate, some api

A basic test file for nose is pretty simple, without any boilerplate code, without required classes to drive from, without unnecessary imports, and without any extra api.

This is identical to the simple test shown in my pytest intro.
There are differences between how you have to write your tests for the two frameworks once you get into extra features of the frameworks, like fixtures, plugins, assert mechanisms, etc.
I’m going to leave a full comparison of pytest and nose to a future post.

Why do I say ‘some api’? Well, when you get into fixtures (like setup/teardown, etc), there is some nose api that is needed in the tests. I’ll get into that in the fixture section.

Nose example

For completeness in following the styles of previous framework introductions, here is the full basic test.
This only differs from above that I’ve added another test function.

Running nose

To run nose, use the nosetests command that comes with nose.

And with verbose:

Here’s an example run both with and without verbose:

Nose fixtures

Nose extends the unittest fixture model of setup/teardown.

We can add specific code to run:

  • at the beginning and end of a module of test code (setup_module/teardown_module)
    To get this to work, you just have to use the right naming rules.

  • at the beginning and end of a class of test methods (setup_class/teardown_class)
    To get this to work, you have to use the right naming rules, and include the ‘@classmethod’ decorator.

  • before and after a test function call (setup_function/teardown_function)
    You can use any name. You have to apply them with the ‘@with_setup’ decorator imported from nose.
    You can also use direct assignment, which I’ll show in the example.

  • before and after a test method call (setup/teardown)
    To get this to work, you have to use the right name.

The easiest fixtures to add are:

  • setup_module() function: runs before anything else in the file
  • teardown_module() function: runs after everything else in the file

And if you use a class to define some tests:

  • setup() method: runs before every test method
  • teardown() method: runs after every test method

You can also set non-class based test functions to have setup/teardown
functions, but you have to import the ‘with_setup’ decorator from nose, like so:

from nose import with_setup # optional

If you don’t like to use decorators, you can also assign the setup and teardown attributes like this:

However, I think that’s a bit awkward.

With classes, you can set a setup/teardown for the class, but you do it differently.
You need to make sure the methods are class methods using the ‘classmethod’ decorator, and name them correctly, like so:

It works, it’s just that you have to keep the syntax straight for all the different rules for different fixtures.

Here they are all together.

To see it in action, I’ll use the -s option, which turns off output capture.
This will show the order of the different fixture calls.

Testing markdown.py

This is also identical to code that can be run from py.test.
It’s similar to unittest code, but without boilerplate, and with simple assert calls instead of assertEquals.
Again, I’m using the API adapter to cleanly call markdown functionality.

Here’s the code to use nose to test markdown.py:

And here’s the output:

All of the tests are failing.
Although the line numbers of the failures, along with the test function names, are printed, it’s not real obvious from the report what’s wrong.

Nose assert_equals

If we are using lots of assert something == somethingElse type tests, and we are committed to using nose for testing, we can use nose tools to make the report a bit obvious about what the failure is.

I’m going to rewrite the tests from above using nose.tools.assert_equals:

Nose’s assert_equals works a lot like unittest’s assertEquals.

Now lets look at the output:

Now the output makes it more obvious what’s wrong.

Test discovery

I use the same naming conventions for nose as I do for py.test.

  • Name my test modules/files starting with ‘test_’.
  • Name my test functions starting with ‘test_’.
  • Name my test classes starting with ‘Test’.
  • Name my test methods starting with ‘test_’.
  • Make sure all packages with test code have an ‘init.py’ file.

These rules work just fine for me.

This isn’t the complete list of rules. If you want to do something different, look at the nose documentation for finding tests

Running unittests from nose

Nose finds and runs unittests with no problem, and with no extra steps.
Here I’ll run the tests from the unittest intro:

Running doctests from nose

Nose can run doctests, supposedly.
However, I couldn’t get it to work on doctests in a separate file method, using test_unnecessary_math.txt.

I tried several of the options, with no luck.
If you know what I’m doing wrong, please let me know.

More nose info (links)

  • nose.readthedocs – nose official documentation (I think)
  • pypi – download links and multiple versions
  • nose-dev – google group on nose

Examples on github

All of the examples here are available in the markdown.py project on github.

Comments

  1. says

    Looking forward to the full review of nose vs. pytest. So far, doing my own comparison, nose appears faster but pytest (as you pointed out) has much better error reporting.

  2. Mathias says

    I am able to run doctests with nosetests with nosetests -w docs/ –doctest-extension=txt

    But ended up using doctest directly as nosetests doesn’t support 1 testfixture for multiple doctests files.

  3. Eric says

    It’s a great introduction of nose!
    By the way, is it possible to add ‘with_setup’ inside a class method?

  4. Dhana says

    Simple and superb. Glad if you can bring in some tutorials on using Mock and @patch usages. In case you already did that please paste the links in your reply.

  5. cuocdoi says

    Hi,

    I confuse whether we need to add fixture “setup/teardown” on Class or for functions ? If I remove them, I can run “nosetests” without any errors ?

    Thanks

Leave a Reply