Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrating Behave or Lettuce with Python unittest

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:

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

From the Behave tutorial:

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

Compare this to Python unittest:

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?

like image 764
Frank Kusters Avatar asked Sep 25 '22 10:09

Frank Kusters


1 Answers

nose includes a package that takes all the class-based asserts that unittest provides and turns them into plain functions, the module's documentation states:

The nose.tools module provides [...] all of the same assertX methods found in unittest.TestCase (only spelled in PEP 8#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.

like image 200
Louis Avatar answered Oct 03 '22 07:10

Louis