Integrating Behave or Lettuce with Python unittest
Question: I'm looking at BDD with Python. Verification of results is a drag, because the
results being verified are not printed on failure.

Compare Behave output:

    
    
    AssertionError: 
      File "C:\Python27\lib\site-packages\behave\model.py", line 1456, in run
        match.run(runner.context)
      File "C:\Python27\lib\site-packages\behave\model.py", line 1903, in run
        self.func(context, *args, **kwargs)
      File "steps\EcuProperties.py", line 28, in step_impl
        assert vin == context.driver.find_element_by_xpath("//table[@id='infoTable']/tbody/tr[4]/td[2]").text
    

to SpecFlow+NUnit output:

    
    
    Scenario: Verify VIN in Retrieve ECU properties -> Failed on thread #0
        [ERROR]   String lengths are both 16. Strings differ at index 15.
      Expected: "ABCDEFGH12345679"
      But was:  "ABCDEFGH12345678"
      --------------------------^
    

Finding failure causes is way faster with the SpecFlow output. To get the
variable contents on error, they have to be put into a string manually.

From the [Lettuce tutorial](http://lettuce.it/tutorial/simple.html#lettuce-
id4):

    
    
    assert world.number == expected, \
        "Got %d" % world.number
    

From the [Behave tutorial](https://pythonhosted.org/behave/tutorial.html#step-
parameters):

    
    
    if text not in context.response:
        fail('%r not in %r' % (text, context.response))
    

Compare this to [Python
unittest](https://docs.python.org/3/library/unittest.html):

    
    
    self.assertEqual('foo2'.upper(), 'FOO')
    

resulting in:

    
    
    Failure
    Expected :'FOO2'
    Actual   :'FOO'
     <Click to see difference>
    
    Traceback (most recent call last):
      File "test.py", line 6, in test_upper
        self.assertEqual('foo2'.upper(), 'FOO')
    AssertionError: 'FOO2' != 'FOO'
    

However, the methods from Python unittest cannot be used outside a `TestCase`
instance.

Is there a good way of getting all the niceness of Python unittest integrated
into Behave or Lettuce?


Answer: [nose](https://nose.readthedocs.org/en/latest/) includes a package that takes
all the class-based asserts that `unittest` provides and turns them into plain
functions, the module's [documentation
states](https://nose.readthedocs.org/en/latest/testing_tools.html?highlight=nose.tools#module-
nose.tools):

> The nose.tools module provides [...] all of the same `assertX` methods found
> in `unittest.TestCase` (only spelled in [PEP 8#function-
> names](https://www.python.org/dev/peps/pep-0008#function-names) fashion, so
> `assert_equal` rather than `assertEqual`).

For instance:

    
    
    from nose.tools import assert_equal
    
    @given("foo is 'blah'")
    def step_impl(context):
        assert_equal(context.foo, "blah")
    

You can ad custom messages to assertions just like you would with the
`.assertX` methods of `unittest`.

That's what I use for the test suites that I run with Behave.

